В данной работе необходимо:
x <- matrix(rnorm(50*5),ncol=5)
y <- factor(rep(c(“A”, “B”), 25))
Сохранить полученные графики в *.jpg файлы. Сделать выводы.
С использование функций из пакета Fselector [2] определить важность признаков для решения задачи классификации. Использовать набор data(iris). Сделать выводы.
С использованием функции discretize() из пакета arules выполните преобразование непрерывной переменной в категориальную [3] различными методами: «interval» (равная ширина интервала), «frequency» (равная частота), «cluster» (кластеризация) и «fixed» (категории задают границы интервалов). Используйте набор данных iris. Сделайте выводы
Установите пакет Boruta и проведите выбор признаков для набора данных data(“Ozone”) [4, 5, 6]. Построить график boxplot, сделать выводы.
Всю представленную работу собрать в единый файл Rmarkdown. Опубликовать его на RPubs, в качестве отчета о лабораторной работе представить ссылку на полученный файл.
Задание 1. Установка пакета CARET и графический анализ (featurePlot)
Устанавливаем и подключаем пакет caret
install.packages("caret")
library(caret)
Смотрим список доступных моделей
model_list <- names(getModelInfo())
model_list
## [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"
Команда names(getModelInfo()) выдаст в консоль перечень моделей, доступных для обучения в пакете caret. Их список может включать десятки методов (например, “rf”, “lm”, “gbm”, “svmLinear” и т. д.).
Создаём выборку и строим графики
set.seed(123)
x <- matrix(rnorm(50*5), ncol=5)
y <- factor(rep(c("A", "B"), 25))
df <- as.data.frame(x)
colnames(df) <- paste0("Feature", 1:5)
Построение парных диаграмм рассеяния (plot=“pairs”)
jpeg("featurePlot_pairs.jpg")
featurePlot(x = df, y = y, plot = "pairs", auto.key = list(columns = 2))
dev.off()
Построение “штрип”-графиков (plot=“strip”)
jpeg("featurePlot_strip.jpg")
featurePlot(x = df, y = y, plot = "strip", auto.key = list(columns = 2))
dev.off()
Построение “бокс”-графиков (plot=“box”)
jpeg("featurePlot_box.jpg")
featurePlot(x=df[,1:5], y=df$y, plot="box")
dev.off()
Выводы
names(getModelInfo()) показывает большое количество моделей, доступных в пакете caret. Графические функции featurePlot() помогают быстро посмотреть на данные. На случайных данных чёткого разделения классов не видно.
Задание 2. Оценка важности признаков с помощью пакета FSelector (на наборе iris)
Установка и подключение пакета
install.packages("FSelector")
library(FSelector)
Работа с набором данных iris
data(iris)
head(iris)
Набор содержит 150 наблюдений и 5 столбцов: четыре числовых признака (Sepal.Length, Sepal.Width, Petal.Length, Petal.Width) и фактор Species (три класса: setosa, versicolor, virginica).
Определение важности признаков
В пакете FSelector есть несколько метрик для оценки важности признаков, например information.gain, gain.ratio, chi.squared.
Информационная выгода (Information Gain)
ig <- information.gain(Species ~ ., data = iris)
ig
Отношение прироста (Gain Ratio)
gr <- gain.ratio(Species ~ ., data = iris)
gr
Статистика хи-квадрат
chi <- chi.squared(Species ~ ., data = iris)
chi
Как правило, для iris наиболее важными признаками оказываются Petal.Length и Petal.Width (особенно хорошо отделяют класс setosa). Sepal.Length и Sepal.Width обычно имеют меньшую информативность, но всё равно могут вносить вклад в разделение видов. Методы Information Gain, Gain Ratio и Chi-squared могут незначительно отличаться в итоговой шкале, однако общая тенденция по ранжированию признаков совпадает.
Задание 3. Дискретизация непрерывных переменных с помощью arules::discretize()
Установка и подключение пакета
install.packages("arules")
library(arules)
data(iris)
Будем дискретизировать, к примеру, признак Sepal.Length. Преобразуем признак Sepal.Length, показываем разные методы
Метод “interval” (равные интервалы)
Разбивает диапазон значений на равные интервалы. Может быть неэффективен, если данные не равномерно распределены (в некоторых категориях может оказаться мало значений).
iris_discrete <- discretize(iris$Sepal.Length, method = "interval", categories = 3)
## Warning in discretize(iris$Sepal.Length, method = "fixed", categories = c(4.5,
## : Parameter categories is deprecated. Use breaks instead! Also, the default
## method is now frequency!
print(iris_discrete)
## [1] [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5)
## [8] [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5)
## [15] [5.5,6.7) [5.5,6.7) [4.3,5.5) [4.3,5.5) [5.5,6.7) [4.3,5.5) [4.3,5.5)
## [22] [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5)
## [29] [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5) [5.5,6.7) [4.3,5.5)
## [36] [4.3,5.5) [5.5,6.7) [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5)
## [43] [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5) [4.3,5.5)
## [50] [4.3,5.5) [6.7,7.9] [5.5,6.7) [6.7,7.9] [5.5,6.7) [5.5,6.7) [5.5,6.7)
## [57] [5.5,6.7) [4.3,5.5) [5.5,6.7) [4.3,5.5) [4.3,5.5) [5.5,6.7) [5.5,6.7)
## [64] [5.5,6.7) [5.5,6.7) [6.7,7.9] [5.5,6.7) [5.5,6.7) [5.5,6.7) [5.5,6.7)
## [71] [5.5,6.7) [5.5,6.7) [5.5,6.7) [5.5,6.7) [5.5,6.7) [5.5,6.7) [6.7,7.9]
## [78] [6.7,7.9] [5.5,6.7) [5.5,6.7) [5.5,6.7) [5.5,6.7) [5.5,6.7) [5.5,6.7)
## [85] [4.3,5.5) [5.5,6.7) [6.7,7.9] [5.5,6.7) [5.5,6.7) [5.5,6.7) [5.5,6.7)
## [92] [5.5,6.7) [5.5,6.7) [4.3,5.5) [5.5,6.7) [5.5,6.7) [5.5,6.7) [5.5,6.7)
## [99] [4.3,5.5) [5.5,6.7) [5.5,6.7) [5.5,6.7) [6.7,7.9] [5.5,6.7) [5.5,6.7)
## [106] [6.7,7.9] [4.3,5.5) [6.7,7.9] [6.7,7.9] [6.7,7.9] [5.5,6.7) [5.5,6.7)
## [113] [6.7,7.9] [5.5,6.7) [5.5,6.7) [5.5,6.7) [5.5,6.7) [6.7,7.9] [6.7,7.9]
## [120] [5.5,6.7) [6.7,7.9] [5.5,6.7) [6.7,7.9] [5.5,6.7) [6.7,7.9] [6.7,7.9]
## [127] [5.5,6.7) [5.5,6.7) [5.5,6.7) [6.7,7.9] [6.7,7.9] [6.7,7.9] [5.5,6.7)
## [134] [5.5,6.7) [5.5,6.7) [6.7,7.9] [5.5,6.7) [5.5,6.7) [5.5,6.7) [6.7,7.9]
## [141] [6.7,7.9] [6.7,7.9] [5.5,6.7) [6.7,7.9] [6.7,7.9] [6.7,7.9] [5.5,6.7)
## [148] [5.5,6.7) [5.5,6.7) [5.5,6.7)
## attr(,"discretized:breaks")
## [1] 4.3 5.5 6.7 7.9
## attr(,"discretized:method")
## [1] interval
## Levels: [4.3,5.5) [5.5,6.7) [6.7,7.9]
Метод “frequency” (равная частота)
iris_discrete <- discretize(iris$Sepal.Length, method = "fixed", categories = c(4.5, 5.5, 6.5)) print(iris_discrete)
## [1] [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4) [5.4,6.3) [4.3,5.4)
## [8] [4.3,5.4) [4.3,5.4) [4.3,5.4) [5.4,6.3) [4.3,5.4) [4.3,5.4) [4.3,5.4)
## [15] [5.4,6.3) [5.4,6.3) [5.4,6.3) [4.3,5.4) [5.4,6.3) [4.3,5.4) [5.4,6.3)
## [22] [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4)
## [29] [4.3,5.4) [4.3,5.4) [4.3,5.4) [5.4,6.3) [4.3,5.4) [5.4,6.3) [4.3,5.4)
## [36] [4.3,5.4) [5.4,6.3) [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4)
## [43] [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4)
## [50] [4.3,5.4) [6.3,7.9] [6.3,7.9] [6.3,7.9] [5.4,6.3) [6.3,7.9] [5.4,6.3)
## [57] [6.3,7.9] [4.3,5.4) [6.3,7.9] [4.3,5.4) [4.3,5.4) [5.4,6.3) [5.4,6.3)
## [64] [5.4,6.3) [5.4,6.3) [6.3,7.9] [5.4,6.3) [5.4,6.3) [5.4,6.3) [5.4,6.3)
## [71] [5.4,6.3) [5.4,6.3) [6.3,7.9] [5.4,6.3) [6.3,7.9] [6.3,7.9] [6.3,7.9]
## [78] [6.3,7.9] [5.4,6.3) [5.4,6.3) [5.4,6.3) [5.4,6.3) [5.4,6.3) [5.4,6.3)
## [85] [5.4,6.3) [5.4,6.3) [6.3,7.9] [6.3,7.9] [5.4,6.3) [5.4,6.3) [5.4,6.3)
## [92] [5.4,6.3) [5.4,6.3) [4.3,5.4) [5.4,6.3) [5.4,6.3) [5.4,6.3) [5.4,6.3)
## [99] [4.3,5.4) [5.4,6.3) [6.3,7.9] [5.4,6.3) [6.3,7.9] [6.3,7.9] [6.3,7.9]
## [106] [6.3,7.9] [4.3,5.4) [6.3,7.9] [6.3,7.9] [6.3,7.9] [6.3,7.9] [6.3,7.9]
## [113] [6.3,7.9] [5.4,6.3) [5.4,6.3) [6.3,7.9] [6.3,7.9] [6.3,7.9] [6.3,7.9]
## [120] [5.4,6.3) [6.3,7.9] [5.4,6.3) [6.3,7.9] [6.3,7.9] [6.3,7.9] [6.3,7.9]
## [127] [5.4,6.3) [5.4,6.3) [6.3,7.9] [6.3,7.9] [6.3,7.9] [6.3,7.9] [6.3,7.9]
## [134] [6.3,7.9] [5.4,6.3) [6.3,7.9] [6.3,7.9] [6.3,7.9] [5.4,6.3) [6.3,7.9]
## [141] [6.3,7.9] [6.3,7.9] [5.4,6.3) [6.3,7.9] [6.3,7.9] [6.3,7.9] [6.3,7.9]
## [148] [6.3,7.9] [5.4,6.3) [5.4,6.3)
## attr(,"discretized:breaks")
## [1] 4.3 5.4 6.3 7.9
## attr(,"discretized:method")
## [1] frequency
## Levels: [4.3,5.4) [5.4,6.3) [6.3,7.9]
Данные распределяются так, чтобы в каждой категории было примерно одинаковое количество значений. Может быть полезен, если данные имеют неравномерное распределение.
Метод “cluster” (кластеризация, по умолчанию k-means) Использует алгоритмы кластеризации для разделения данных. Может адаптироваться к форме данных, но зависит от выбора количества кластеров.
iris_discrete <- discretize(iris$Sepal.Length, method = "cluster", categories = 3)
print(iris_discrete)
## [1] [4.3,5.45) [4.3,5.45) [4.3,5.45) [4.3,5.45) [4.3,5.45) [4.3,5.45)
## [7] [4.3,5.45) [4.3,5.45) [4.3,5.45) [4.3,5.45) [4.3,5.45) [4.3,5.45)
## [13] [4.3,5.45) [4.3,5.45) [5.45,6.46) [5.45,6.46) [4.3,5.45) [4.3,5.45)
## [19] [5.45,6.46) [4.3,5.45) [4.3,5.45) [4.3,5.45) [4.3,5.45) [4.3,5.45)
## [25] [4.3,5.45) [4.3,5.45) [4.3,5.45) [4.3,5.45) [4.3,5.45) [4.3,5.45)
## [31] [4.3,5.45) [4.3,5.45) [4.3,5.45) [5.45,6.46) [4.3,5.45) [4.3,5.45)
## [37] [5.45,6.46) [4.3,5.45) [4.3,5.45) [4.3,5.45) [4.3,5.45) [4.3,5.45)
## [43] [4.3,5.45) [4.3,5.45) [4.3,5.45) [4.3,5.45) [4.3,5.45) [4.3,5.45)
## [49] [4.3,5.45) [4.3,5.45) [6.46,7.9] [5.45,6.46) [6.46,7.9] [5.45,6.46)
## [55] [6.46,7.9] [5.45,6.46) [5.45,6.46) [4.3,5.45) [6.46,7.9] [4.3,5.45)
## [61] [4.3,5.45) [5.45,6.46) [5.45,6.46) [5.45,6.46) [5.45,6.46) [6.46,7.9]
## [67] [5.45,6.46) [5.45,6.46) [5.45,6.46) [5.45,6.46) [5.45,6.46) [5.45,6.46)
## [73] [5.45,6.46) [5.45,6.46) [5.45,6.46) [6.46,7.9] [6.46,7.9] [6.46,7.9]
## [79] [5.45,6.46) [5.45,6.46) [5.45,6.46) [5.45,6.46) [5.45,6.46) [5.45,6.46)
## [85] [4.3,5.45) [5.45,6.46) [6.46,7.9] [5.45,6.46) [5.45,6.46) [5.45,6.46)
## [91] [5.45,6.46) [5.45,6.46) [5.45,6.46) [4.3,5.45) [5.45,6.46) [5.45,6.46)
## [97] [5.45,6.46) [5.45,6.46) [4.3,5.45) [5.45,6.46) [5.45,6.46) [5.45,6.46)
## [103] [6.46,7.9] [5.45,6.46) [6.46,7.9] [6.46,7.9] [4.3,5.45) [6.46,7.9]
## [109] [6.46,7.9] [6.46,7.9] [6.46,7.9] [5.45,6.46) [6.46,7.9] [5.45,6.46)
## [115] [5.45,6.46) [5.45,6.46) [6.46,7.9] [6.46,7.9] [6.46,7.9] [5.45,6.46)
## [121] [6.46,7.9] [5.45,6.46) [6.46,7.9] [5.45,6.46) [6.46,7.9] [6.46,7.9]
## [127] [5.45,6.46) [5.45,6.46) [5.45,6.46) [6.46,7.9] [6.46,7.9] [6.46,7.9]
## [133] [5.45,6.46) [5.45,6.46) [5.45,6.46) [6.46,7.9] [5.45,6.46) [5.45,6.46)
## [139] [5.45,6.46) [6.46,7.9] [6.46,7.9] [6.46,7.9] [5.45,6.46) [6.46,7.9]
## [145] [6.46,7.9] [6.46,7.9] [5.45,6.46) [6.46,7.9] [5.45,6.46) [5.45,6.46)
## attr(,"discretized:breaks")
## [1] 4.300000 5.452320 6.461111 7.900000
## attr(,"discretized:method")
## [1] cluster
## Levels: [4.3,5.45) [5.45,6.46) [6.46,7.9]
Метод “fixed” (заданные вручную границы) Категории задаются вручную. Хороший вариант, если известны важные границы разбиения.
iris_discrete <- discretize(iris$Sepal.Length, method = "frequency", categories = 3)
print(iris_discrete)
table(interval_cut) table(freq_cut) table(cluster_cut) table(fixed_cut)
## [1] [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4) [5.4,6.3) [4.3,5.4)
## [8] [4.3,5.4) [4.3,5.4) [4.3,5.4) [5.4,6.3) [4.3,5.4) [4.3,5.4) [4.3,5.4)
## [15] [5.4,6.3) [5.4,6.3) [5.4,6.3) [4.3,5.4) [5.4,6.3) [4.3,5.4) [5.4,6.3)
## [22] [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4)
## [29] [4.3,5.4) [4.3,5.4) [4.3,5.4) [5.4,6.3) [4.3,5.4) [5.4,6.3) [4.3,5.4)
## [36] [4.3,5.4) [5.4,6.3) [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4)
## [43] [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4) [4.3,5.4)
## [50] [4.3,5.4) [6.3,7.9] [6.3,7.9] [6.3,7.9] [5.4,6.3) [6.3,7.9] [5.4,6.3)
## [57] [6.3,7.9] [4.3,5.4) [6.3,7.9] [4.3,5.4) [4.3,5.4) [5.4,6.3) [5.4,6.3)
## [64] [5.4,6.3) [5.4,6.3) [6.3,7.9] [5.4,6.3) [5.4,6.3) [5.4,6.3) [5.4,6.3)
## [71] [5.4,6.3) [5.4,6.3) [6.3,7.9] [5.4,6.3) [6.3,7.9] [6.3,7.9] [6.3,7.9]
## [78] [6.3,7.9] [5.4,6.3) [5.4,6.3) [5.4,6.3) [5.4,6.3) [5.4,6.3) [5.4,6.3)
## [85] [5.4,6.3) [5.4,6.3) [6.3,7.9] [6.3,7.9] [5.4,6.3) [5.4,6.3) [5.4,6.3)
## [92] [5.4,6.3) [5.4,6.3) [4.3,5.4) [5.4,6.3) [5.4,6.3) [5.4,6.3) [5.4,6.3)
## [99] [4.3,5.4) [5.4,6.3) [6.3,7.9] [5.4,6.3) [6.3,7.9] [6.3,7.9] [6.3,7.9]
## [106] [6.3,7.9] [4.3,5.4) [6.3,7.9] [6.3,7.9] [6.3,7.9] [6.3,7.9] [6.3,7.9]
## [113] [6.3,7.9] [5.4,6.3) [5.4,6.3) [6.3,7.9] [6.3,7.9] [6.3,7.9] [6.3,7.9]
## [120] [5.4,6.3) [6.3,7.9] [5.4,6.3) [6.3,7.9] [6.3,7.9] [6.3,7.9] [6.3,7.9]
## [127] [5.4,6.3) [5.4,6.3) [6.3,7.9] [6.3,7.9] [6.3,7.9] [6.3,7.9] [6.3,7.9]
## [134] [6.3,7.9] [5.4,6.3) [6.3,7.9] [6.3,7.9] [6.3,7.9] [5.4,6.3) [6.3,7.9]
## [141] [6.3,7.9] [6.3,7.9] [5.4,6.3) [6.3,7.9] [6.3,7.9] [6.3,7.9] [6.3,7.9]
## [148] [6.3,7.9] [5.4,6.3) [5.4,6.3)
## attr(,"discretized:breaks")
## [1] 4.3 5.4 6.3 7.9
## attr(,"discretized:method")
## [1] frequency
## Levels: [4.3,5.4) [5.4,6.3) [6.3,7.9]
Выводы по заданию:
При выборе разных методов дискретизации распределение объектов по категориям будет отличаться.
Метод «равная ширина» (interval) равномерно разбивает ось признака, но может “потерять” детали, если данных много в узком диапазоне. Метод «равная частота» (frequency) стремится уравнять количество объектов в каждой категории.
Метод «cluster» старается группировать данные по естественным кластерам; это может лучше отражать структуру данных, но нужно осторожно подбирать число кластеров.
Метод «fixed» позволяет вручную задавать интересующие границы, но требует знаний об области значений.
Задание 4. Выбор признаков с помощью пакета Boruta (пример на наборе Ozone)
Установка и подключение
install.packages("Boruta")
nstall.packages("mlbench")
library(Boruta)
library(mlbench)
data("Ozone") # Подгружаем набор данных
str(Ozone)
Запуск алгоритма Boruta Предположим, что набор данных называется Ozone и у него есть столбец V4 (например, это значение озона, которое мы хотим предсказывать).
set.seed(123)
boruta_result <- Boruta(V4 ~ ., data = ozone_clean, doTrace = 2, maxRuns = 100)
boruta_result
График boxplot важности признаков
plot(boruta_result, xlab = "", xaxt = "n", main = "Boruta Feature Importance")
lz <- lapply(1:ncol(boruta_result$ImpHistory),
function(i) boruta_result$ImpHistory[is.finite(boruta_result$ImpHistory[, i]), i])
names(lz) <- colnames(boruta_result$ImpHistory)
axis(side = 1, las = 2, labels = names(lz),
at = 1:ncol(boruta_result$ImpHistory), cex.axis = 0.7)
Выводы по результатам Boruta
На основании boxplot и итогового решения можно определить, какие признаки вносят наибольший вклад в предсказание целевой переменной. Признаки со статусом Confirmed стоит оставить в модели, признаки с Rejected — можно исключить, а Tentative — проверить детальнее или изменить параметры алгоритма, чтобы принять окончательное решение.
Заключение
Итоговые выводы
Пакет caret предоставляет широкий выбор методов для обучения моделей (более 200). Функция featurePlot() позволяет выполнять быстрый разведочный анализ признаков, однако по случайно сгенерированным данным чёткого разделения между классами ожидать не приходится. Пакет FSelector показывает, что для классической задачи iris наибольшую важность обычно имеют признаки, связанные с лепестками (Petal.Length и Petal.Width). Ранжирование по различным метрикам может немного отличаться, но общее направление сохраняется. Функция discretize() из arules даёт гибкие средства дискретизации: равная ширина, равная частота, кластеризация и пользовательские границы. На практике выбор метода зависит от задачи и особенностей данных. Алгоритм Boruta помогает автоматически определять набор «подтверждённых» и «отклонённых» признаков для задач регрессии или классификации. Визуализация с помощью plot(boruta_result) даёт наглядное представление о важности каждого признака.