Задание 1

library(caret)
## Загрузка требуемого пакета: ggplot2
## Загрузка требуемого пакета: lattice
models <- names(getModelInfo())
length(models)
## [1] 239
head(models)
## [1] "ada"         "AdaBag"      "AdaBoost.M1" "adaboost"    "amdai"      
## [6] "ANFIS"
set.seed(1)
x <- matrix(rnorm(50*5), ncol = 5)
colnames(x) <- paste0("X", 1:5)
y <- factor(rep(c("A", "B"), 25))
jpeg("pairs.jpg", width = 800, height = 800)
featurePlot(x = x, y = y, plot = "pairs")
dev.off()
## png 
##   2
jpeg("ellipse.jpg", width = 800, height = 600)
featurePlot(x = x, y = y, plot = "ellipse")
dev.off()
## png 
##   2
jpeg("strip.jpg", width = 800, height = 600)
featurePlot(x = x, y = y, plot = "strip", jitter = TRUE)
dev.off()
## png 
##   2
jpeg("box.jpg", width = 800, height = 600)
featurePlot(x = x, y = y, plot = "box")
dev.off()
## png 
##   2

Графики

Вывод по заданию 1

Данные x сгенерированы случайно (rnorm), поэтому классы A и B не имеют реальной структуры. На всех графиках видно сильное перекрытие классов: точки классов A и B перемешаны, ящики с усами сильно пересекаются, эллипсы почти полностью накладываются. Это ожидаемый результат — он подтверждает, что данные не разделимы, и никакой метод классификации не покажет хорошего качества на таких данных. Графики pairs и ellipse наиболее наглядны для визуальной оценки перекрытия. Четыре графика сохранены в файлы pairs.jpg, ellipse.jpg, strip.jpg, box.jpg.

Задание 2

library(FSelector)

data(iris)

weights <- information.gain(Species ~ ., iris)
print(weights)
##              attr_importance
## Sepal.Length       0.4521286
## Sepal.Width        0.2672750
## Petal.Length       0.9402853
## Petal.Width        0.9554360
weights[order(-weights$attr_importance), , drop = FALSE]
##              attr_importance
## Petal.Width        0.9554360
## Petal.Length       0.9402853
## Sepal.Length       0.4521286
## Sepal.Width        0.2672750

Вывод по заданию 2

Наибольший информационный выигрыш дают признаки Petal.Width (~0.94) и Petal.Length (~0.94), наименьший — Sepal.Width (~0.15). Для классификации ирисов признаки лепестка гораздо информативнее признаков чашелистика. Результат согласуется с биологией: виды ирисов хорошо различаются именно по размеру лепестков. Метод information.gain оценивает, насколько сильно каждый признак снижает неопределённость (энтропию) относительно целевой переменной Species.

Задание 3

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

# 1
disc_interval <- discretize(x_pl, method = "interval", breaks = 3)
cat("--- interval ---\n"); table(disc_interval)
## --- interval ---
## disc_interval
##    [1,2.97) [2.97,4.93)  [4.93,6.9] 
##          50          54          46
# 2
disc_frequency <- discretize(x_pl, method = "frequency", breaks = 3)
cat("--- frequency ---\n"); table(disc_frequency)
## --- frequency ---
## disc_frequency
##   [1,2.63) [2.63,4.9)  [4.9,6.9] 
##         50         49         51
# 3
disc_cluster <- discretize(x_pl, method = "cluster", breaks = 3)
cat("--- cluster ---\n"); table(disc_cluster)
## --- cluster ---
## disc_cluster
##    [1,2.95) [2.95,5.13)  [5.13,6.9] 
##          50          66          34
# 4
disc_fixed <- discretize(x_pl, method = "fixed",
                         breaks = c(-Inf, 2.5, 5, Inf),
                         labels = c("small", "medium", "large"))
cat("--- fixed ---\n"); table(disc_fixed)
## --- fixed ---
## disc_fixed
##  small medium  large 
##     50     54     46

Вывод по заданию 3

  • interval — интервалы одинаковой ширины, но наблюдения распределены по группам неравномерно.
  • frequency — в каждой группе примерно равное число наблюдений (около 50), что удобно для моделей, чувствительных к дисбалансу.
  • cluster (k-means) — границы находятся по естественным сгущениям данных, поэтому группы получаются «осмысленными» с точки зрения распределения.
  • fixed — границы задаёт сам исследователь (-Inf, 2.5, 5, Inf); результат полностью зависит от выбранных порогов.

Выбор метода зависит от задачи: frequency — для равномерной нагрузки; cluster — для поиска естественных групп; fixed — когда есть экспертные пороги; interval — самый простой, но может дать дисбаланс.

Задание 4

library(Boruta)
library(mlbench)

data(Ozone)

ozone_clean <- na.omit(Ozone)

set.seed(123)
boruta_output <- Boruta(V4 ~ ., data = ozone_clean, doTrace = 0)
print(boruta_output)
## Boruta performed 18 iterations in 0.3925741 secs.
##  9 attributes confirmed important: V1, V10, V11, V12, V13 and 4 more;
##  3 attributes confirmed unimportant: V2, V3, V6;
jpeg("boruta_boxplot.jpg", width = 1000, height = 700)
plot(boruta_output, cex.axis = 0.7, las = 2, xlab = "", main = "Важность признаков (Boruta)")
dev.off()
## png 
##   2

График Boruta

Вывод по заданию 4

Алгоритм Boruta создаёт «теневые» копии признаков (синие ящики на графике) и сравнивает с ними важность настоящих признаков. - Зелёные ящики — признаки, значимо важнее теневых, то есть подтверждённые как важные. - Красные — отвергнутые (важность не выше случайной). - Жёлтые — спорные (Tentative).

По результатам видно, что большинство метеорологических признаков в Ozone оказались важными для предсказания уровня озона: концентрация озона зависит от температуры, давления, скорости ветра и других факторов. Boruta надёжнее обычной оценки важности случайного леса, так как учитывает вариабельность и отсекает случайные признаки через сравнение с «теневыми».