DATA 624: HOMEWORK 4

Author

Pascal Hermann Kouogang Tafo

Exercise 3.1

Let’s first load the library and open the data. I will install the mlbench package in my console so that the system won’t have to do it over every time that i run my entire file.

library(mlbench)
Warning: package 'mlbench' was built under R version 4.5.3
data(Glass)
str(Glass)
'data.frame':   214 obs. of  10 variables:
 $ RI  : num  1.52 1.52 1.52 1.52 1.52 ...
 $ Na  : num  13.6 13.9 13.5 13.2 13.3 ...
 $ Mg  : num  4.49 3.6 3.55 3.69 3.62 3.61 3.6 3.61 3.58 3.6 ...
 $ Al  : num  1.1 1.36 1.54 1.29 1.24 1.62 1.14 1.05 1.37 1.36 ...
 $ Si  : num  71.8 72.7 73 72.6 73.1 ...
 $ K   : num  0.06 0.48 0.39 0.57 0.55 0.64 0.58 0.57 0.56 0.57 ...
 $ Ca  : num  8.75 7.83 7.78 8.22 8.07 8.07 8.17 8.24 8.3 8.4 ...
 $ Ba  : num  0 0 0 0 0 0 0 0 0 0 ...
 $ Fe  : num  0 0 0 0 0 0.26 0 0 0 0.11 ...
 $ Type: Factor w/ 6 levels "1","2","3","5",..: 1 1 1 1 1 1 1 1 1 1 ...

Our Glass data have nine predictors including RI(refractive index), Na,Mg,Al,Si,K, CA, Ba and Fe.

  1. Using visualizations,let’s explore the predictor variables to understand their distributions as well as the relationship between predictors.

One of the best way to explore variables’ distributions is through an histogram. In order to create the histogram for our predictor, we will have to extract only the predictors from our Glass data meaning we should remove the variable “type” from the data.

# Let's create our dataset of interest

predictors <- Glass[, -10]   # drop Type
head(predictors)
       RI    Na   Mg   Al    Si    K   Ca Ba   Fe
1 1.52101 13.64 4.49 1.10 71.78 0.06 8.75  0 0.00
2 1.51761 13.89 3.60 1.36 72.73 0.48 7.83  0 0.00
3 1.51618 13.53 3.55 1.54 72.99 0.39 7.78  0 0.00
4 1.51766 13.21 3.69 1.29 72.61 0.57 8.22  0 0.00
5 1.51742 13.27 3.62 1.24 73.08 0.55 8.07  0 0.00
6 1.51596 12.79 3.61 1.62 72.97 0.64 8.07  0 0.26
# Let's create a histogram for each predictor

for (var in names(predictors)) 
  hist(predictors[[var]], main = var, xlab = "")

# Let's find relationships between predictors by looking at the correlation among predictors

library(corrplot) # Loading the coorplot library after installing it in my console
Warning: package 'corrplot' was built under R version 4.5.3
corrplot 0.95 loaded
# Let's create a correlation matrix and the plot associated

cor_matrix <- round(cor(predictors),3) # generating the correlation matrix at 3 decimals places
cor_matrix
       RI     Na     Mg     Al     Si      K     Ca     Ba     Fe
RI  1.000 -0.192 -0.122 -0.407 -0.542 -0.290  0.810  0.000  0.143
Na -0.192  1.000 -0.274  0.157 -0.070 -0.266 -0.275  0.327 -0.241
Mg -0.122 -0.274  1.000 -0.482 -0.166  0.005 -0.444 -0.492  0.083
Al -0.407  0.157 -0.482  1.000 -0.006  0.326 -0.260  0.479 -0.074
Si -0.542 -0.070 -0.166 -0.006  1.000 -0.193 -0.209 -0.102 -0.094
K  -0.290 -0.266  0.005  0.326 -0.193  1.000 -0.318 -0.043 -0.008
Ca  0.810 -0.275 -0.444 -0.260 -0.209 -0.318  1.000 -0.113  0.125
Ba  0.000  0.327 -0.492  0.479 -0.102 -0.043 -0.113  1.000 -0.059
Fe  0.143 -0.241  0.083 -0.074 -0.094 -0.008  0.125 -0.059  1.000
corrplot(cor_matrix, order = "hclust") # we are plotting the correlation using hierarchical clustering order.

# Let's create a pairwise scatterplot matrix to see the relationship between predictors

pairs(predictors)

Interpretation

When we look at the correlation matrix, the correlation coefficient between RI and Ca is equal to 0.810 which means there is a strong positive relationship between these two predictors. We also observe some moderate relationship between all predictors with correlation coefficient between (+/-) 0.30 and 0.69 and finally we have some coefficients less than (+/-) 0.3 which shows some weak relationship between some predictors.

  1. Let’s find any possible outliers or skewness in predictors.

The box plot could easily help us figure out any outliers. In regard to the skewness in predictors,

# Boxplots flag outliers

for (var in names(predictors)) 
  boxplot(predictors[[var]], main = var)

Interpretation:

Following all the box plot, we observed outliers in predictors K, Ba, Fe, Ca and Al with some observed high values in the respective graph with some value that are single out and not directly related to the majority of the data.

When visualizing all the histograms form the question a), overall the Na and Al predictors histogram are roughly symmetrical and exhibit a sort of bell-shape form. As for the K, Ba, Ca, Fe, and Ri predictor exhibit a long tail to the right which mean they are right skewed. The Mg predictor shows what can be considered like 2 peaks which makes it a bimodal distribution. Lastly, the Si predictor is mainly symmetrical but also exhibit a long tail to the left.

  1. Are there any relevant transformations of one or more predictors that might improved the classification model?

Since we discover some skew distribution, some outliers and zeros in the predictors, therefore we believe some transformations can be done to improve the classification model. The necessary transformations are as followed:

  • We can use the Yeo-Johnson transformation handles zero and negative values and for the skewed predictors.

  • We can use the Spatial sign transformation to deal with outliers.

  • We can use the principal component analysis to deal with correlated predictors.

# We install and load the caret to deal with the pre-processing steps in R. I installed the package in my console to avoid for it to be installed anytime we run our command. 

library(caret)
Warning: package 'caret' was built under R version 4.5.3
Loading required package: ggplot2
Warning: package 'ggplot2' was built under R version 4.5.3
Loading required package: lattice
Warning: package 'lattice' was built under R version 4.5.2
# Box-Cox needs strictly positive values, so it works for RI, Na, Al, Si, Ca
# Yeo-Johnson transformation for (Mg, K, Ba, Fe ) that contain zeros

preProcess_Data <- preProcess(predictors, method = c("YeoJohnson", "center", "scale"))
YeoJohnson_trans <- predict(preProcess_Data, predictors)
 

# Spatial sign transformation to shrinks outliers

preProcess2_Data <- preProcess(predictors, method = c("center", "scale"))
ss_trans <- spatialSign(predict(preProcess2_Data, predictors))
head(ss_trans)
          RI          Na        Mg         Al          Si           K
1  0.3862138  0.12608198 0.5551342 -0.3063816 -0.49869486 -0.29720647
2 -0.1782866  0.42318047 0.4548937 -0.1218880  0.07316353 -0.01874385
3 -0.4739625  0.09851782 0.3951817  0.1254439  0.28831726 -0.10811108
4 -0.1932662 -0.20158533 0.5799799 -0.2581474 -0.04397201  0.09305653
5 -0.2268925 -0.12303180 0.4726731 -0.2991170  0.40373539  0.05916450
6 -0.3036441 -0.29004891 0.2459643  0.1344417  0.15791804  0.08402131
           Ca         Ba         Fe
1 -0.06449657 -0.1561358 -0.2594843
2 -0.56756147 -0.2523255 -0.4193433
3 -0.54468469 -0.2318677 -0.3853442
4 -0.43085072 -0.2929133 -0.4867968
5 -0.45422808 -0.2565822 -0.4264175
6 -0.23892010 -0.1349600  0.7986264
# Principal Component Analysis to handle correlated predictors such as RI and Ca

preProcess3_Data <- preProcess(predictors, method = c("YeoJohnson", "center", "scale", "pca"))
preProcess3_Data
Created from 214 samples and 9 variables

Pre-processing:
  - centered (9)
  - ignored (0)
  - principal component signal extraction (9)
  - scaled (9)
  - Yeo-Johnson transformation (5)

Lambda estimates for Yeo-Johnson transformation:
-0.19, 2.24, 0, -0.98, -1.36
PCA needed 6 components to capture 95 percent of the variance

Exercise 3.2

Let’s load the soybean data before our analysis.

data(Soybean)
str(Soybean)
'data.frame':   683 obs. of  36 variables:
 $ Class          : Factor w/ 19 levels "2-4-d-injury",..: 11 11 11 11 11 11 11 11 11 11 ...
 $ date           : Factor w/ 7 levels "0","1","2","3",..: 7 5 4 4 7 6 6 5 7 5 ...
 $ plant.stand    : Ord.factor w/ 2 levels "0"<"1": 1 1 1 1 1 1 1 1 1 1 ...
 $ precip         : Ord.factor w/ 3 levels "0"<"1"<"2": 3 3 3 3 3 3 3 3 3 3 ...
 $ temp           : Ord.factor w/ 3 levels "0"<"1"<"2": 2 2 2 2 2 2 2 2 2 2 ...
 $ hail           : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 2 1 1 ...
 $ crop.hist      : Factor w/ 4 levels "0","1","2","3": 2 3 2 2 3 4 3 2 4 3 ...
 $ area.dam       : Factor w/ 4 levels "0","1","2","3": 2 1 1 1 1 1 1 1 1 1 ...
 $ sever          : Factor w/ 3 levels "0","1","2": 2 3 3 3 2 2 2 2 2 3 ...
 $ seed.tmt       : Factor w/ 3 levels "0","1","2": 1 2 2 1 1 1 2 1 2 1 ...
 $ germ           : Ord.factor w/ 3 levels "0"<"1"<"2": 1 2 3 2 3 2 1 3 2 3 ...
 $ plant.growth   : Factor w/ 2 levels "0","1": 2 2 2 2 2 2 2 2 2 2 ...
 $ leaves         : Factor w/ 2 levels "0","1": 2 2 2 2 2 2 2 2 2 2 ...
 $ leaf.halo      : Factor w/ 3 levels "0","1","2": 1 1 1 1 1 1 1 1 1 1 ...
 $ leaf.marg      : Factor w/ 3 levels "0","1","2": 3 3 3 3 3 3 3 3 3 3 ...
 $ leaf.size      : Ord.factor w/ 3 levels "0"<"1"<"2": 3 3 3 3 3 3 3 3 3 3 ...
 $ leaf.shread    : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
 $ leaf.malf      : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
 $ leaf.mild      : Factor w/ 3 levels "0","1","2": 1 1 1 1 1 1 1 1 1 1 ...
 $ stem           : Factor w/ 2 levels "0","1": 2 2 2 2 2 2 2 2 2 2 ...
 $ lodging        : Factor w/ 2 levels "0","1": 2 1 1 1 1 1 2 1 1 1 ...
 $ stem.cankers   : Factor w/ 4 levels "0","1","2","3": 4 4 4 4 4 4 4 4 4 4 ...
 $ canker.lesion  : Factor w/ 4 levels "0","1","2","3": 2 2 1 1 2 1 2 2 2 2 ...
 $ fruiting.bodies: Factor w/ 2 levels "0","1": 2 2 2 2 2 2 2 2 2 2 ...
 $ ext.decay      : Factor w/ 3 levels "0","1","2": 2 2 2 2 2 2 2 2 2 2 ...
 $ mycelium       : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
 $ int.discolor   : Factor w/ 3 levels "0","1","2": 1 1 1 1 1 1 1 1 1 1 ...
 $ sclerotia      : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
 $ fruit.pods     : Factor w/ 4 levels "0","1","2","3": 1 1 1 1 1 1 1 1 1 1 ...
 $ fruit.spots    : Factor w/ 4 levels "0","1","2","4": 4 4 4 4 4 4 4 4 4 4 ...
 $ seed           : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
 $ mold.growth    : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
 $ seed.discolor  : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
 $ seed.size      : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
 $ shriveling     : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
 $ roots          : Factor w/ 3 levels "0","1","2": 1 1 1 1 1 1 1 1 1 1 ...
  1. Let’s investigate the frequency distribution for the categorical predictors. Are any of the distribution degenerate in the way discussed earlier in this chapter?

Based on our chapter 3, degenerate distributions refer to predictors that have zero or near-zero variance(NZV). In order to check that we can use the caret package.

library(caret)

# Frequency tables for every predictor

lapply(Soybean[, -1], table, useNA = "ifany")
$date

   0    1    2    3    4    5    6 <NA> 
  26   75   93  118  131  149   90    1 

$plant.stand

   0    1 <NA> 
 354  293   36 

$precip

   0    1    2 <NA> 
  74  112  459   38 

$temp

   0    1    2 <NA> 
  80  374  199   30 

$hail

   0    1 <NA> 
 435  127  121 

$crop.hist

   0    1    2    3 <NA> 
  65  165  219  218   16 

$area.dam

   0    1    2    3 <NA> 
 123  227  145  187    1 

$sever

   0    1    2 <NA> 
 195  322   45  121 

$seed.tmt

   0    1    2 <NA> 
 305  222   35  121 

$germ

   0    1    2 <NA> 
 165  213  193  112 

$plant.growth

   0    1 <NA> 
 441  226   16 

$leaves

  0   1 
 77 606 

$leaf.halo

   0    1    2 <NA> 
 221   36  342   84 

$leaf.marg

   0    1    2 <NA> 
 357   21  221   84 

$leaf.size

   0    1    2 <NA> 
  51  327  221   84 

$leaf.shread

   0    1 <NA> 
 487   96  100 

$leaf.malf

   0    1 <NA> 
 554   45   84 

$leaf.mild

   0    1    2 <NA> 
 535   20   20  108 

$stem

   0    1 <NA> 
 296  371   16 

$lodging

   0    1 <NA> 
 520   42  121 

$stem.cankers

   0    1    2    3 <NA> 
 379   39   36  191   38 

$canker.lesion

   0    1    2    3 <NA> 
 320   83  177   65   38 

$fruiting.bodies

   0    1 <NA> 
 473  104  106 

$ext.decay

   0    1    2 <NA> 
 497  135   13   38 

$mycelium

   0    1 <NA> 
 639    6   38 

$int.discolor

   0    1    2 <NA> 
 581   44   20   38 

$sclerotia

   0    1 <NA> 
 625   20   38 

$fruit.pods

   0    1    2    3 <NA> 
 407  130   14   48   84 

$fruit.spots

   0    1    2    4 <NA> 
 345   75   57  100  106 

$seed

   0    1 <NA> 
 476  115   92 

$mold.growth

   0    1 <NA> 
 524   67   92 

$seed.discolor

   0    1 <NA> 
 513   64  106 

$seed.size

   0    1 <NA> 
 532   59   92 

$shriveling

   0    1 <NA> 
 539   38  106 

$roots

   0    1    2 <NA> 
 551   86   15   31 
# Let's check for zero and near-zero-variance predictors

nearzerovar_info <- nearZeroVar(predictors, saveMetrics = TRUE)
nearzerovar_info[nearzerovar_info$nearzerov == TRUE, ]
[1] freqRatio     percentUnique zeroVar       nzv          
<0 rows> (or 0-length row.names)
# Visualize or tabulate one of the degenerate variables (e.g., leaf.malf, mycelium)

table(predictors$leaf.malf, useNA = "always")

<NA> 
   0 
table(predictors$mycelium, useNA = "always")

<NA> 
   0 
  1. roughly 18% of the data are missing. Are there particular predictors that are more likely to be missing? Is the pattern of missing data related to the classes?

First, we will check the percent missing by predictor.

colMeans(is.na(Soybean[, -1])) * 100
           date     plant.stand          precip            temp            hail 
      0.1464129       5.2708638       5.5636896       4.3923865      17.7159590 
      crop.hist        area.dam           sever        seed.tmt            germ 
      2.3426061       0.1464129      17.7159590      17.7159590      16.3982430 
   plant.growth          leaves       leaf.halo       leaf.marg       leaf.size 
      2.3426061       0.0000000      12.2986823      12.2986823      12.2986823 
    leaf.shread       leaf.malf       leaf.mild            stem         lodging 
     14.6412884      12.2986823      15.8125915       2.3426061      17.7159590 
   stem.cankers   canker.lesion fruiting.bodies       ext.decay        mycelium 
      5.5636896       5.5636896      15.5197657       5.5636896       5.5636896 
   int.discolor       sclerotia      fruit.pods     fruit.spots            seed 
      5.5636896       5.5636896      12.2986823      15.5197657      13.4699854 
    mold.growth   seed.discolor       seed.size      shriveling           roots 
     13.4699854      15.5197657      13.4699854      15.5197657       4.5387994 
sort(colMeans(is.na(Soybean[, -1])), decreasing = TRUE)[1:10]
           hail           sever        seed.tmt         lodging            germ 
      0.1771596       0.1771596       0.1771596       0.1771596       0.1639824 
      leaf.mild fruiting.bodies     fruit.spots   seed.discolor      shriveling 
      0.1581259       0.1551977       0.1551977       0.1551977       0.1551977 

Secondly, let’s check the missing data by class.

# Let's generate the missing data by class table

missingdata_by_class <- aggregate(
  . ~ Class,
  data = cbind(Class = Soybean$Class, as.data.frame(is.na(Soybean[, -1]))),
  FUN = mean
)

head(missingdata_by_class,10)
                         Class   date plant.stand precip temp hail crop.hist
1                 2-4-d-injury 0.0625         1.0      1    1    1         1
2          alternarialeaf-spot 0.0000         0.0      0    0    0         0
3                  anthracnose 0.0000         0.0      0    0    0         0
4             bacterial-blight 0.0000         0.0      0    0    0         0
5            bacterial-pustule 0.0000         0.0      0    0    0         0
6                   brown-spot 0.0000         0.0      0    0    0         0
7               brown-stem-rot 0.0000         0.0      0    0    0         0
8                 charcoal-rot 0.0000         0.0      0    0    0         0
9                cyst-nematode 0.0000         1.0      1    1    1         0
10 diaporthe-pod-&-stem-blight 0.0000         0.4      0    0    1         0
   area.dam sever seed.tmt germ plant.growth leaves leaf.halo leaf.marg
1    0.0625     1        1  1.0            1      0         0         0
2    0.0000     0        0  0.0            0      0         0         0
3    0.0000     0        0  0.0            0      0         0         0
4    0.0000     0        0  0.0            0      0         0         0
5    0.0000     0        0  0.0            0      0         0         0
6    0.0000     0        0  0.0            0      0         0         0
7    0.0000     0        0  0.0            0      0         0         0
8    0.0000     0        0  0.0            0      0         0         0
9    0.0000     1        1  1.0            0      0         1         1
10   0.0000     1        1  0.4            0      0         1         1
   leaf.size leaf.shread leaf.malf leaf.mild stem lodging stem.cankers
1          0           1         0         1    1       1            1
2          0           0         0         0    0       0            0
3          0           0         0         0    0       0            0
4          0           0         0         0    0       0            0
5          0           0         0         0    0       0            0
6          0           0         0         0    0       0            0
7          0           0         0         0    0       0            0
8          0           0         0         0    0       0            0
9          1           1         1         1    0       1            1
10         1           1         1         1    0       1            0
   canker.lesion fruiting.bodies ext.decay mycelium int.discolor sclerotia
1              1               1         1        1            1         1
2              0               0         0        0            0         0
3              0               0         0        0            0         0
4              0               0         0        0            0         0
5              0               0         0        0            0         0
6              0               0         0        0            0         0
7              0               0         0        0            0         0
8              0               0         0        0            0         0
9              1               1         1        1            1         1
10             0               0         0        0            0         0
   fruit.pods fruit.spots seed mold.growth seed.discolor seed.size shriveling
1           1           1    1           1             1         1          1
2           0           0    0           0             0         0          0
3           0           0    0           0             0         0          0
4           0           0    0           0             0         0          0
5           0           0    0           0             0         0          0
6           0           0    0           0             0         0          0
7           0           0    0           0             0         0          0
8           0           0    0           0             0         0          0
9           0           1    0           0             1         0          1
10          0           0    0           0             0         0          0
   roots
1      1
2      0
3      0
4      0
5      0
6      0
7      0
8      0
9      0
10     1
  1. Let’s find a strategy to handle missing data
Soybean_New <- Soybean
Soybean_New$any_na <- NULL
for (v in names(Soybean_New)[-1]) {
  Soybean_New[[v]] <- addNA(Soybean_New[[v]])
  levels(Soybean_New[[v]])[is.na(levels(Soybean_New[[v]]))] <- "missing"
}

head(Soybean_New,10)
                   Class date plant.stand precip temp hail crop.hist area.dam
1  diaporthe-stem-canker    6           0      2    1    0         1        1
2  diaporthe-stem-canker    4           0      2    1    0         2        0
3  diaporthe-stem-canker    3           0      2    1    0         1        0
4  diaporthe-stem-canker    3           0      2    1    0         1        0
5  diaporthe-stem-canker    6           0      2    1    0         2        0
6  diaporthe-stem-canker    5           0      2    1    0         3        0
7  diaporthe-stem-canker    5           0      2    1    0         2        0
8  diaporthe-stem-canker    4           0      2    1    1         1        0
9  diaporthe-stem-canker    6           0      2    1    0         3        0
10 diaporthe-stem-canker    4           0      2    1    0         2        0
   sever seed.tmt germ plant.growth leaves leaf.halo leaf.marg leaf.size
1      1        0    0            1      1         0         2         2
2      2        1    1            1      1         0         2         2
3      2        1    2            1      1         0         2         2
4      2        0    1            1      1         0         2         2
5      1        0    2            1      1         0         2         2
6      1        0    1            1      1         0         2         2
7      1        1    0            1      1         0         2         2
8      1        0    2            1      1         0         2         2
9      1        1    1            1      1         0         2         2
10     2        0    2            1      1         0         2         2
   leaf.shread leaf.malf leaf.mild stem lodging stem.cankers canker.lesion
1            0         0         0    1       1            3             1
2            0         0         0    1       0            3             1
3            0         0         0    1       0            3             0
4            0         0         0    1       0            3             0
5            0         0         0    1       0            3             1
6            0         0         0    1       0            3             0
7            0         0         0    1       1            3             1
8            0         0         0    1       0            3             1
9            0         0         0    1       0            3             1
10           0         0         0    1       0            3             1
   fruiting.bodies ext.decay mycelium int.discolor sclerotia fruit.pods
1                1         1        0            0         0          0
2                1         1        0            0         0          0
3                1         1        0            0         0          0
4                1         1        0            0         0          0
5                1         1        0            0         0          0
6                1         1        0            0         0          0
7                1         1        0            0         0          0
8                1         1        0            0         0          0
9                1         1        0            0         0          0
10               1         1        0            0         0          0
   fruit.spots seed mold.growth seed.discolor seed.size shriveling roots
1            4    0           0             0         0          0     0
2            4    0           0             0         0          0     0
3            4    0           0             0         0          0     0
4            4    0           0             0         0          0     0
5            4    0           0             0         0          0     0
6            4    0           0             0         0          0     0
7            4    0           0             0         0          0     0
8            4    0           0             0         0          0     0
9            4    0           0             0         0          0     0
10           4    0           0             0         0          0     0