Установка и загрузка пакетов:

library(caret)
## Warning: пакет 'caret' был собран под R версии 4.4.3
## Загрузка требуемого пакета: ggplot2
## Загрузка требуемого пакета: lattice
library(FSelector)
## Warning: пакет 'FSelector' был собран под R версии 4.4.3
library(arules)
## Загрузка требуемого пакета: Matrix
## 
## Присоединяю пакет: 'arules'
## Следующие объекты скрыты от 'package:base':
## 
##     abbreviate, write
library(Boruta)
## Warning: пакет 'Boruta' был собран под R версии 4.4.3
library(mlbench)
## Warning: пакет 'mlbench' был собран под R версии 4.4.3

Задание 1: Пакет caret и графический анализ данных

Пакет caret предобработки данных, выбора признаков и построения моделей.

Доступные методы выбора признаков:

names(getModelInfo())
##   [1] "ada"                 "AdaBag"              "AdaBoost.M1"        
##   [4] "adaboost"            "amdai"               "ANFIS"              
##   [7] "avNNet"              "awnb"                "awtan"              
##  [10] "bag"                 "bagEarth"            "bagEarthGCV"        
##  [13] "bagFDA"              "bagFDAGCV"           "bam"                
##  [16] "bartMachine"         "bayesglm"            "binda"              
##  [19] "blackboost"          "blasso"              "blassoAveraged"     
##  [22] "bridge"              "brnn"                "BstLm"              
##  [25] "bstSm"               "bstTree"             "C5.0"               
##  [28] "C5.0Cost"            "C5.0Rules"           "C5.0Tree"           
##  [31] "cforest"             "chaid"               "CSimca"             
##  [34] "ctree"               "ctree2"              "cubist"             
##  [37] "dda"                 "deepboost"           "DENFIS"             
##  [40] "dnn"                 "dwdLinear"           "dwdPoly"            
##  [43] "dwdRadial"           "earth"               "elm"                
##  [46] "enet"                "evtree"              "extraTrees"         
##  [49] "fda"                 "FH.GBML"             "FIR.DM"             
##  [52] "foba"                "FRBCS.CHI"           "FRBCS.W"            
##  [55] "FS.HGD"              "gam"                 "gamboost"           
##  [58] "gamLoess"            "gamSpline"           "gaussprLinear"      
##  [61] "gaussprPoly"         "gaussprRadial"       "gbm_h2o"            
##  [64] "gbm"                 "gcvEarth"            "GFS.FR.MOGUL"       
##  [67] "GFS.LT.RS"           "GFS.THRIFT"          "glm.nb"             
##  [70] "glm"                 "glmboost"            "glmnet_h2o"         
##  [73] "glmnet"              "glmStepAIC"          "gpls"               
##  [76] "hda"                 "hdda"                "hdrda"              
##  [79] "HYFIS"               "icr"                 "J48"                
##  [82] "JRip"                "kernelpls"           "kknn"               
##  [85] "knn"                 "krlsPoly"            "krlsRadial"         
##  [88] "lars"                "lars2"               "lasso"              
##  [91] "lda"                 "lda2"                "leapBackward"       
##  [94] "leapForward"         "leapSeq"             "Linda"              
##  [97] "lm"                  "lmStepAIC"           "LMT"                
## [100] "loclda"              "logicBag"            "LogitBoost"         
## [103] "logreg"              "lssvmLinear"         "lssvmPoly"          
## [106] "lssvmRadial"         "lvq"                 "M5"                 
## [109] "M5Rules"             "manb"                "mda"                
## [112] "Mlda"                "mlp"                 "mlpKerasDecay"      
## [115] "mlpKerasDecayCost"   "mlpKerasDropout"     "mlpKerasDropoutCost"
## [118] "mlpML"               "mlpSGD"              "mlpWeightDecay"     
## [121] "mlpWeightDecayML"    "monmlp"              "msaenet"            
## [124] "multinom"            "mxnet"               "mxnetAdam"          
## [127] "naive_bayes"         "nb"                  "nbDiscrete"         
## [130] "nbSearch"            "neuralnet"           "nnet"               
## [133] "nnls"                "nodeHarvest"         "null"               
## [136] "OneR"                "ordinalNet"          "ordinalRF"          
## [139] "ORFlog"              "ORFpls"              "ORFridge"           
## [142] "ORFsvm"              "ownn"                "pam"                
## [145] "parRF"               "PART"                "partDSA"            
## [148] "pcaNNet"             "pcr"                 "pda"                
## [151] "pda2"                "penalized"           "PenalizedLDA"       
## [154] "plr"                 "pls"                 "plsRglm"            
## [157] "polr"                "ppr"                 "pre"                
## [160] "PRIM"                "protoclass"          "qda"                
## [163] "QdaCov"              "qrf"                 "qrnn"               
## [166] "randomGLM"           "ranger"              "rbf"                
## [169] "rbfDDA"              "Rborist"             "rda"                
## [172] "regLogistic"         "relaxo"              "rf"                 
## [175] "rFerns"              "RFlda"               "rfRules"            
## [178] "ridge"               "rlda"                "rlm"                
## [181] "rmda"                "rocc"                "rotationForest"     
## [184] "rotationForestCp"    "rpart"               "rpart1SE"           
## [187] "rpart2"              "rpartCost"           "rpartScore"         
## [190] "rqlasso"             "rqnc"                "RRF"                
## [193] "RRFglobal"           "rrlda"               "RSimca"             
## [196] "rvmLinear"           "rvmPoly"             "rvmRadial"          
## [199] "SBC"                 "sda"                 "sdwd"               
## [202] "simpls"              "SLAVE"               "slda"               
## [205] "smda"                "snn"                 "sparseLDA"          
## [208] "spikeslab"           "spls"                "stepLDA"            
## [211] "stepQDA"             "superpc"             "svmBoundrangeString"
## [214] "svmExpoString"       "svmLinear"           "svmLinear2"         
## [217] "svmLinear3"          "svmLinearWeights"    "svmLinearWeights2"  
## [220] "svmPoly"             "svmRadial"           "svmRadialCost"      
## [223] "svmRadialSigma"      "svmRadialWeights"    "svmSpectrumString"  
## [226] "tan"                 "tanSearch"           "treebag"            
## [229] "vbmpRadial"          "vglmAdjCat"          "vglmContRatio"      
## [232] "vglmCumulative"      "widekernelpls"       "WM"                 
## [235] "wsrf"                "xgbDART"             "xgbLinear"          
## [238] "xgbTree"             "xyf"

Создадим матрицу случайных данных, затем проведем разведочный анализ с помощью featurePlot():

set.seed(123)
x <- matrix(rnorm(50 * 5), ncol = 5)
y <- factor(rep(c("A", "B"), 25))

featurePlot(x, y, plot = "pairs")

Сохраним графики в .jpg:

jpeg("1zad.jpeg")
featurePlot(x, y, plot = "pairs")
dev.off()
## png 
##   2

Вывод: Диаграмма рассеяния показывает, что объекты обоих классов распределены без явного порядка или структуры. Это связано со случайным характером сгенерированных признаков, из-за чего невозможно выделить чёткие различия между классами или выявить определённые зависимости.

Задание 2: Определение важности признаков с FSelector

Определим важность признаков для классификации в датасете iris с использованием метода information.gain, который вычисляет, насколько каждый признак уменьшает неопределённость при классификации.

data(iris)
str(iris)
## 'data.frame':    150 obs. of  5 variables:
##  $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
##  $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
##  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
##  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
##  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
importance <- information.gain(Species ~ ., iris)
print(importance)
##              attr_importance
## Sepal.Length       0.4521286
## Sepal.Width        0.2672750
## Petal.Length       0.9402853
## Petal.Width        0.9554360

Визуализируем важность признаков:

barplot(importance$attr_importance, 
        names.arg = rownames(importance),
        main = "Важность признаков",
        col = "red",
        ylab = "Information Gain")

Вывод: Анализ показал, что наибольший вклад в классификацию видов ирисов вносят признаки, связанные с размерами лепестков (Petal.Length и Petal.Width). Эти параметры содержат наибольшее количество информации для различения классов. В то же время характеристики чашелистиков (Sepal.Length и Sepal.Width) оказываются менее значимыми и при необходимости упрощения модели могут быть исключены без существенной потери качества.

Задание 3: Дискретизация данных с arules

Выполним дискретизацию переменной Sepal.Length в iris разными методами: «interval», «frequency», «cluster» и «fixed».

iris$Sepal.Length.interval <- discretize(iris$Sepal.Length, 
                                         method = "interval", breaks = 3)

iris$Sepal.Length.frequency <- discretize(iris$Sepal.Length, 
                                          method = "frequency", breaks = 3)

set.seed(42)
iris$Sepal.Length.cluster <- as.factor(kmeans(iris$Sepal.Length, centers = 3)$cluster)

iris$Sepal.Length.fixed <- discretize(iris$Sepal.Length, 
                                      method = "fixed", breaks = c(4, 5.5, 6.5, 8))


par(mfrow = c(2, 2))
barplot(table(iris$Sepal.Length.interval), main = "Interval", col = "lightgreen")
barplot(table(iris$Sepal.Length.frequency), main = "Frequency", col = "lightyellow")
barplot(table(iris$Sepal.Length.cluster), main = "Cluster", col = "lightblue")
barplot(table(iris$Sepal.Length.fixed), main = "Fixed", col = "lightcoral")

par(mfrow = c(1, 1))

Вывод: Метод interval удобен для равномерного деления данных на интервалы по шкале значений. Frequency применяется, когда важно, чтобы в каждой группе было примерно одинаковое количество наблюдений. Метод cluster помогает выявить естественные кластеры в данных, а fixed используется в случаях, когда границы категорий заранее известны и заданы вручную.

Задание 4: Выбор признаков с Boruta

Алгоритм Boruta позволяет отобрать наиболее значимые признаки на основе метода случайных лесов (Random Forest).

Проведем выбор наиболее значимых признаков на наборе данных Ozone. Целевой переменной (target) будет уровень загрязнения озоном (V4), а остальные переменные будут рассматриваться как потенциальные факторы, влияющие на него:

data("Ozone")
 
Ozone <- na.omit(Ozone)
str(Ozone)
## 'data.frame':    203 obs. of  13 variables:
##  $ V1 : Factor w/ 12 levels "1","2","3","4",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ V2 : Factor w/ 31 levels "1","2","3","4",..: 5 6 7 8 9 12 13 14 15 16 ...
##  $ V3 : Factor w/ 7 levels "1","2","3","4",..: 1 2 3 4 5 1 2 3 4 5 ...
##  $ V4 : num  5 6 4 4 6 6 5 4 4 7 ...
##  $ V5 : num  5760 5720 5790 5790 5700 5720 5760 5780 5830 5870 ...
##  $ V6 : num  3 4 6 3 3 3 6 6 3 2 ...
##  $ V7 : num  51 69 19 25 73 44 33 19 19 19 ...
##  $ V8 : num  54 35 45 55 41 51 51 54 58 61 ...
##  $ V9 : num  45.3 49.6 46.4 52.7 48 ...
##  $ V10: num  1450 1568 2631 554 2083 ...
##  $ V11: num  25 15 -33 -28 23 9 -44 -44 -53 -67 ...
##  $ V12: num  57 53.8 54.1 64.8 52.5 ...
##  $ V13: num  60 60 100 250 120 150 40 200 250 200 ...
##  - attr(*, "na.action")= 'omit' Named int [1:163] 1 2 3 4 10 11 17 18 20 24 ...
##   ..- attr(*, "names")= chr [1:163] "1" "2" "3" "4" ...
set.seed(42)
boruta_result <- Boruta(V4 ~ ., data = Ozone, doTrace = 2)
##  1. run of importance source...
##  2. run of importance source...
##  3. run of importance source...
##  4. run of importance source...
##  5. run of importance source...
##  6. run of importance source...
##  7. run of importance source...
##  8. run of importance source...
##  9. run of importance source...
##  10. run of importance source...
##  11. run of importance source...
## After 11 iterations, +0.6 secs:
##  confirmed 9 attributes: V1, V10, V11, V12, V13 and 4 more;
##  rejected 1 attribute: V3;
##  still have 2 attributes left.
##  12. run of importance source...
##  13. run of importance source...
##  14. run of importance source...
##  15. run of importance source...
##  16. run of importance source...
##  17. run of importance source...
##  18. run of importance source...
## After 18 iterations, +0.98 secs:
##  rejected 1 attribute: V2;
##  still have 1 attribute left.
##  19. run of importance source...
##  20. run of importance source...
##  21. run of importance source...
## After 21 iterations, +1.1 secs:
##  rejected 1 attribute: V6;
##  no more attributes left.
print(boruta_result)
## Boruta performed 21 iterations in 1.142784 secs.
##  9 attributes confirmed important: V1, V10, V11, V12, V13 and 4 more;
##  3 attributes confirmed unimportant: V2, V3, V6;
plot(boruta_result, las = 2, cex.axis = 0.7, 
     main = "Feature Importance by Boruta")

Вывод: График продемонстрировал, что ряд переменных обладает статистической значимостью для прогнозирования уровня озона, тогда как другие оказывают несущественное влияние и могут быть исключены из модели. Это способствует не только улучшению точности

..