Задание 1. Пакет CARET и разведочный анализ featurePlot()

Загрузим пакет caret и ознакомимся со списком доступных моделей с помощью names(getModelInfo()):

library(caret)
models <- names(getModelInfo())
head(models, 30)
##  [1] "ada"            "AdaBag"         "AdaBoost.M1"    "adaboost"      
##  [5] "amdai"          "ANFIS"          "avNNet"         "awnb"          
##  [9] "awtan"          "bag"            "bagEarth"       "bagEarthGCV"   
## [13] "bagFDA"         "bagFDAGCV"      "bam"            "bartMachine"   
## [17] "bayesglm"       "binda"          "blackboost"     "blasso"        
## [21] "blassoAveraged" "bridge"         "brnn"           "BstLm"         
## [25] "bstSm"          "bstTree"        "C5.0"           "C5.0Cost"      
## [29] "C5.0Rules"      "C5.0Tree"
cat("Всего доступно моделей в CARET:", length(models), "\n")
## Всего доступно моделей в CARET: 239
set.seed(42)
x <- matrix(rnorm(50 * 5), ncol = 5)
y <- factor(rep(c("A", "B"), 25))

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

featurePlot(x = x, y = y, plot = "pairs", auto.key = list(columns = 2))

# Сохранение в файлы .jpg
jpeg("featurePlot_box.jpg", width = 800, height = 600)
print(featurePlot(x = x, y = y, plot = "box"))
dev.off()
## png 
##   2

Вывод: В пакете caret доступно более 230 моделей машинного обучения и отбора признаков. Поскольку матрица x сгенерирована из стандартного нормального распределения rnorm() независимо от фактора y, графики featurePlot демонстрируют отсутствие статистически значимых различий между классами A и B (медианы около 0, распределения перекрываются).


Задание 2. Определение важности признаков (FSelector / iris)

Определим информационную значимость признаков набора данных iris для классификации вида ириса (Species):

library(FSelectorRcpp)
data(iris)

weights_ig <- information_gain(Species ~ ., data = iris)
print(weights_ig)
##     attributes importance
## 1 Sepal.Length  0.4521286
## 2  Sepal.Width  0.2672750
## 3 Petal.Length  0.9402853
## 4  Petal.Width  0.9554360
weights_gr <- information_gain(Species ~ ., data = iris, type = "gainratio")
print(weights_gr)
##     attributes importance
## 1 Sepal.Length  0.4196464
## 2  Sepal.Width  0.2472972
## 3 Petal.Length  0.8584937
## 4  Petal.Width  0.8713692
best_features <- cut_attrs(weights_ig, k = 2)
cat("Два наиболее важных признака:", best_features, "\n")
## Два наиболее важных признака: Petal.Width Petal.Length

Вывод: Наибольшим информационным выигрышем (Information Gain) обладают признаки длины лепестка (Petal.Length \(\approx 0.94\)) и ширины лепестка (Petal.Width \(\approx 0.95\)). Признаки чашелистика (Sepal.Length и особенно Sepal.Width \(\approx 0.26\)) имеют значительно меньшую разделительную способность для классификации видов ириса.


Задание 3. Дискретизация непрерывной переменной (arules::discretize)

Выполним перевод непрерывной переменной Sepal.Length набора данных iris в категориальную четырьмя методами:

library(arules)
x_iris <- iris$Sepal.Length

d_interval <- discretize(x_iris, method = "interval", breaks = 3)
d_freq     <- discretize(x_iris, method = "frequency", breaks = 3)
set.seed(42)
d_cluster  <- discretize(x_iris, method = "cluster", breaks = 3)
d_fixed    <- discretize(x_iris, method = "fixed", breaks = c(-Inf, 5.5, 6.5, Inf),
                         labels = c("Малый", "Средний", "Большой"))

table(d_interval)
## d_interval
## [4.3,5.5) [5.5,6.7) [6.7,7.9] 
##        52        70        28
table(d_freq)
## d_freq
## [4.3,5.4) [5.4,6.3) [6.3,7.9] 
##        46        53        51
table(d_cluster)
## d_cluster
##  [4.3,5.33) [5.33,6.27)  [6.27,7.9] 
##          46          53          51
table(d_fixed)
## d_fixed
##   Малый Средний Большой 
##      52      63      35
par(mfrow = c(2, 2))
plot(d_interval, main = "interval (равная ширина)", col = "lightblue")
plot(d_freq, main = "frequency (равная частота)", col = "lightgreen")
plot(d_cluster, main = "cluster (кластеризация)", col = "lightcoral")
plot(d_fixed, main = "fixed (заданные границы)", col = "wheat")

par(mfrow = c(1, 1))

Вывод: Метод interval делит диапазон значений на равные отрезки, но создаёт несбалансированные по числу наблюдений группы. Метод frequency формирует практически равные по объёму категории (по ~50 объектов). Метод cluster опирается на естественные сгущения данных (k-means), а fixed позволяет задать экспертные пороги разбиения вручную.


Задание 4. Отбор признаков с помощью пакета Boruta (data("Ozone"))

Проведём отбор наиболее значимых метеорологических и временных признаков для прогнозирования уровня озона (V4):

library(Boruta)
library(mlbench)

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

set.seed(42)
boruta_ozone <- Boruta(V4 ~ ., data = ozone_clean, doTrace = 0)
print(boruta_ozone)
## Boruta performed 21 iterations in 0.168901 secs.
##  9 attributes confirmed important: V1, V10, V11, V12, V13 and 4 more;
##  3 attributes confirmed unimportant: V2, V3, V6;
plot(boruta_ozone, las = 2, cex.axis = 0.8, xlab = "", main = "Отбор признаков алгоритмом Boruta (Ozone)")

Вывод: Алгоритм Boruta (на базе Random Forest и теневых признаков shadowMin, shadowMean, shadowMax) признал важными (Confirmed, зелёный цвет на графике) 9 переменных (V1, V5, V7, V8, V9, V10, V11, V12, V13), среди которых наибольший вклад вносят температура (V8, V9) и геопотенциальная высота/инверсия (V5, V10, V12). Признаки дня недели (V3), числа месяца (V2) и скорости ветра (V6) признаны неинформативными (Rejected, красный цвет), так как их Z-score не превышает максимум случайных теневых признаков (shadowMax).