1. Пакет CARET

models <- names(getModelInfo())
length(models)
## [1] 239
head(models, 20)
##  [1] "ada"         "AdaBag"      "AdaBoost.M1" "adaboost"    "amdai"      
##  [6] "ANFIS"       "avNNet"      "awnb"        "awtan"       "bag"        
## [11] "bagEarth"    "bagEarthGCV" "bagFDA"      "bagFDAGCV"   "bam"        
## [16] "bartMachine" "bayesglm"    "binda"       "blackboost"  "blasso"
set.seed(123)
x <- as.data.frame(matrix(rnorm(50 * 5), ncol = 5))
colnames(x) <- paste0("X", 1:5)
y <- factor(rep(c("A", "B"), 25))
print(featurePlot(x, y, plot = "box"))

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

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

print(featurePlot(x, y, plot = "ellipse"))

Вывод. Функция featurePlot() построила пять типов графиков (strip, box, density, pairs, ellipse). На сгенерированных данных x (5 независимых нормальных признаков) и метках y, чередующихся случайно, диаграммы размаха показали почти совпадающие медианы и квартили для классов A и B; кривые плотности практически накладываются друг на друга; на матрице рассеяния точки обоих классов перемешаны, а на графике с эллипсами эллипсы почти полностью перекрываются. Единственный наглядный вывод, который можно сделать — между признаками нет корреляции, а между классами и признаками нет зависимости. Это ожидаемый результат для случайных данных и хороший «нулевой пример»: он наглядно показывает, как выглядят данные без информативных признаков, и позволяет в дальнейшем сравнить их с реальным набором (например, iris), где графики сразу выявляют разделяющие признаки.

2. FSelector

library(FSelector)
data(iris)
w_ig  <- information.gain(Species ~ ., iris)
w_chi <- chi.squared(Species ~ ., iris)
w_rf  <- random.forest.importance(Species ~ ., iris)
w_ig; w_chi; w_rf
##              attr_importance
## Sepal.Length       0.4521286
## Sepal.Width        0.2672750
## Petal.Length       0.9402853
## Petal.Width        0.9554360
##              attr_importance
## Sepal.Length       0.6288067
## Sepal.Width        0.4922162
## Petal.Length       0.9346311
## Petal.Width        0.9432359
##              attr_importance
## Sepal.Length       15.215175
## Sepal.Width         4.983734
## Petal.Length       49.136910
## Petal.Width        47.063541
cutoff.k(w_ig, 2)
## [1] "Petal.Width"  "Petal.Length"
cfs(Species ~ ., iris)
## [1] "Petal.Length" "Petal.Width"

Вывод. Для набора iris важность признаков оценивалась тремя методами из пакета FSelector — information.gain (прирост информации), chi.squared (хи-квадрат) и random.forest.importance (по случайному лесу). Каждый метод использует собственную шкалу, поэтому абсолютные значения между ними несопоставимы напрямую: Petal.Width даёт 0.955 у information.gain, 0.943 у chi.squared и 47.06 у random.forest.importance, — корректно сравнивать методы только по порядку признаков. Этот порядок во всех трёх случаях одинаков: Petal.Width и Petal.Length делят первые два места с минимальным отрывом друг от друга, третьим идёт Sepal.Length, а последним — Sepal.Width с заметным отставанием. Автоматические процедуры отбора подтверждают ту же картину: cutoff.k(w_ig, 2) возвращает Petal.Width и Petal.Length, а метод CFS (cfs(Species ~ ., iris)) — ровно ту же пару. Следовательно, для классификации трёх видов ириса достаточно двух признаков лепестка, и размерность задачи можно сократить с четырёх до двух без потери информативности: признаки чашелистика либо слабо разделяют классы (Sepal.Length), либо почти не несут полезной информации (Sepal.Width).

3. Дискретизация arules

library(arules)
v <- iris$Sepal.Length
d_int  <- discretize(v, method = "interval",  breaks = 3)
d_freq <- discretize(v, method = "frequency", breaks = 3)
d_clu  <- discretize(v, method = "cluster",   breaks = 3)
d_fix  <- discretize(v, method = "fixed", breaks = c(-Inf, 5.5, 6.5, Inf))
table(d_int); table(d_freq); table(d_clu); table(d_fix)
## d_int
## [4.3,5.5) [5.5,6.7) [6.7,7.9] 
##        52        70        28
## d_freq
## [4.3,5.4) [5.4,6.3) [6.3,7.9] 
##        46        53        51
## d_clu
##  [4.3,5.33) [5.33,6.27)  [6.27,7.9] 
##          46          53          51
## d_fix
## [-Inf,5.5)  [5.5,6.5) [6.5, Inf] 
##         52         63         35

Вывод. interval даёт равную ширину интервалов, но неравные группы (52/70/28); frequency и cluster дают близкие по числу наблюдений группы (46/53/51), но разными путями — frequency по порядку, cluster по структуре данных; fixed полностью зависит от заданных порогов. Первый подходит для равномерного шага по шкале, второй и третий — для алгоритмов, чувствительных к дисбалансу, четвёртый — когда границы имеют содержательный смысл.

4. Boruta на Ozone

library(mlbench)
library(Boruta)
data("Ozone", package = "mlbench")
ozone <- na.omit(Ozone)
set.seed(123)
boruta_res <- Boruta(V4 ~ ., data = ozone, doTrace = 0)
print(boruta_res)
## Boruta performed 18 iterations in 0.314564 secs.
##  9 attributes confirmed important: V1, V10, V11, V12, V13 and 4 more;
##  3 attributes confirmed unimportant: V2, V3, V6;
plot(boruta_res, las = 2, cex.axis = 0.7)

attStats(boruta_res)
##         meanImp   medianImp      minImp     maxImp   normHits  decision
## V1   0.40660229  0.39874710  0.37208192 0.50361585 1.00000000 Confirmed
## V2   0.04391890  0.03169822 -0.02604472 0.13137821 0.11111111  Rejected
## V3  -0.03235907 -0.04528594 -0.08039941 0.03178173 0.00000000  Rejected
## V5   0.37961385  0.37663333  0.33809868 0.42147363 1.00000000 Confirmed
## V6   0.04740489  0.05979747 -0.01572443 0.12718160 0.05555556  Rejected
## V7   0.51883205  0.50588169  0.46725744 0.59114026 1.00000000 Confirmed
## V8   0.77086858  0.76889989  0.73251688 0.81327051 1.00000000 Confirmed
## V9   0.86915268  0.86432645  0.84273725 0.92413075 1.00000000 Confirmed
## V10  0.42389058  0.41739463  0.38164901 0.49245967 1.00000000 Confirmed
## V11  0.55143690  0.54721914  0.49482770 0.61161304 1.00000000 Confirmed
## V12  0.66051279  0.65832222  0.60234621 0.73958611 1.00000000 Confirmed
## V13  0.42761454  0.42057856  0.38618408 0.46920282 1.00000000 Confirmed

Вывод. Boruta за 18 итераций подтвердил 9 признаков (V1, V5, V7–V13) и отклонил 3 (V2, V3, V6), неопределённых нет. У подтверждённых normHits = 1.0, то есть важность стабильно выше теневых копий. Самые сильные — V9, V8 и V12 (температуры), что логично для озона. Отклонены V2 и V3 (календарные артефакты) и V6 — связи с концентрацией озона нет. Важность признаков устойчива от итерации к итерации

Общий вывод

В лабораторной работе освоены четыре инструмента отбора признаков и подготовки данных в R: caret (обзор моделей, featurePlot()), FSelector (фильтры, CFS, обёртки), arules (discretize()) и Boruta. На случайных данных featurePlot() наглядно показала отсутствие информативных признаков; на iris все методы FSelector согласованно выделили признаки лепестка (Petal.Width, Petal.Length), что позволяет сократить размерность с 4 до 2; дискретизация arules продемонстрировала четыре разных подхода к преобразованию непрерывной переменной, выбор между которыми зависит от задачи; Boruta на Ozone надёжно отделила значимые признаки (температуры и сезонность) от шума без ручного порога важности.