1. Графический анализ данных (caret)

Установить пакет CARET, выполнить команду names(getModelInfo()), ознакомиться со списком доступных методов выбора признаков. Выполните графический разведочный анализ данных с использование функции featurePlot() для набора данных из справочного файла пакета CARET:

library(caret)
## Загрузка требуемого пакета: ggplot2
## Загрузка требуемого пакета: lattice
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"
set.seed(123)

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

colnames(x) <- paste0("Var", 1:5)
featurePlot(x, y, plot="box")

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

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

Вывод

График pairs показывает попарные зависимости между признаками. График density отображает распределение значений признаков для каждого класса. График box позволяет визуализировать распределение данных по классам. Так как данные сгенерированы случайно, признаки не разделяют классы A и B. На графиках распределения совпадают, информативных признаков нет.

2. Оценка важности признаков (FSelector)

С использование функций из пакета Fselector [2] определить важность признаков для решения задачи классификации. Использовать набор data(iris). Сделать выводы.

library(FSelector)
data(iris)

weights <- information.gain(Species ~ ., iris)
weights[order(-weights$attr_importance), ]
## [1] 0.9554360 0.9402853 0.4521286 0.2672750

Вывод

Функция information.gain позволяет определить важность признаков для задачи классификации. Результаты показывают, какие признаки наиболее информативны для разделения классов.

Наиболее информативные признаки:

  • Petal.Length

  • Petal.Width

Наименее информативный:

  • Sepal.Width

Длина и ширина лепестка лучше всего различают виды ирисов.

3. Дискретизация признаков (arules)

С использованием функции discretize() из пакета arules выполните преобразование непрерывной переменной в категориальную [3] различными методами: «interval» (равная ширина интервала), «frequency» (равная частота), «cluster» (кластеризация) и «fixed» (категории задают границы интервалов). Используйте набор данных iris. Сделайте выводы

library(arules)
## Загрузка требуемого пакета: Matrix
## 
## Присоединяю пакет: 'arules'
## Следующие объекты скрыты от 'package:base':
## 
##     abbreviate, write
x <- iris$Sepal.Length

Метод interval

table(discretize(x, method="interval", breaks=3))
## 
## [4.3,5.5) [5.5,6.7) [6.7,7.9] 
##        52        70        28

Метод interval разделяет диапазон значений на интервалы равной ширины. При этом наблюдается неравномерное распределение объектов по категориям (52, 70 и 28 наблюдений), что связано с особенностями распределения исходных данных.

Метод frequency

table(discretize(x, method="frequency", breaks=3))
## 
## [4.3,5.4) [5.4,6.3) [6.3,7.9] 
##        46        53        51

Метод frequency формирует интервалы с приблизительно равным количеством наблюдений (46, 53 и 51 объект), что обеспечивает более сбалансированное распределение категорий.

Метод cluster

table(discretize(x, method="cluster", breaks=3))
## 
##  [4.3,5.42) [5.42,6.39)  [6.39,7.9] 
##          52          56          42

Метод cluster использует алгоритм k-means для выявления естественных групп в данных. Интервалы формируются с учетом структуры распределения признака (52, 56 и 42 наблюдения).

Метод fixed

table(discretize(x, method="fixed", breaks=c(4,5.5,6.5,8)))
## 
##   [4,5.5) [5.5,6.5)   [6.5,8] 
##        52        63        35

Метод fixed выполняет разбиение на основе заранее заданных границ интервалов. Такой подход удобен при наличии априорных знаний о значимых диапазонах значений.

Вывод

Таким образом, метод frequency обеспечивает наиболее равномерное распределение объектов, тогда как cluster учитывает внутреннюю структуру данных. Выбор метода зависит от цели анализа.

4. Выбор признаков методом Boruta

library(Boruta)
library(mlbench)

data(Ozone)
Ozone <- na.omit(Ozone)

set.seed(123)
boruta_model <- Boruta(V4 ~ ., data=Ozone, doTrace=0)
print(boruta_model)
## Boruta performed 24 iterations in 1.532608 secs.
##  9 attributes confirmed important: V1, V10, V11, V12, V13 and 4 more;
##  3 attributes confirmed unimportant: V2, V3, V6;
plot(boruta_model, las=2, cex.axis=0.7)

График boxplot показывает:

зелёные — важные признаки;

красные — неважные;

синие — тени (shadow features).

Вывод

В ходе работы был применён алгоритм Boruta для отбора значимых признаков при прогнозировании переменной V4 набора данных Ozone.

Алгоритм выполнил 24 итерации и определил 9 признаков как статистически значимые. Признаки V2, V3 и V6 были признаны неинформативными, так как их важность оказалась ниже важности случайно сгенерированных теневых признаков.

Метод Boruta основан на сравнении реальных признаков с искусственно созданными случайными переменными и позволяет надёжно выявлять действительно значимые факторы. В результате анализа были исключены признаки, не оказывающие существенного влияния на целевую переменную, что способствует улучшению качества последующего моделирования.