Введение

Цель работы: изучить методы визуального анализа, оценки важности, дискретизации и отбора признаков в среде R с использованием пакетов caret, FSelectorRcpp, arules и Boruta.

1. Анализ данных с использованием caret

library(caret)

names(getModelInfo())[1: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 <- matrix(rnorm(50 * 5), ncol = 5)
y <- factor(rep(c("A", "B"), 25))

colnames(x) <- paste0("V", 1:5)

featurePlot(x, y)

jpeg("featurePlot.jpg", width = 1200, height = 800)
featurePlot(x, y)
dev.off()
## png 
##   2

Вывод

С помощью функции featurePlot() был выполнен графический разведочный анализ признаков. Поскольку данные были сгенерированы случайным образом, чёткого разделения классов A и B не наблюдается. Это означает, что случайно созданные признаки не являются информативными для уверенной классификации объектов.

2. Оценка важности признаков с использованием FSelectorRcpp

library(FSelectorRcpp)

data(iris)

ig <- information_gain(Species ~ ., iris)
ig
##     attributes importance
## 1 Sepal.Length  0.4521286
## 2  Sepal.Width  0.2672750
## 3 Petal.Length  0.9402853
## 4  Petal.Width  0.9554360

Вывод

По результатам оценки важности признаков наиболее значимыми оказались Petal.Width и Petal.Length, так как они имеют наибольшие значения information gain. Следовательно, именно эти признаки в наибольшей степени влияют на качество классификации видов ирисов.

3. Дискретизация непрерывной переменной с использованием arules

library(arules)

data(iris)

disc_interval  <- discretize(iris$Sepal.Length, method = "interval",  categories = 3)
disc_frequency <- discretize(iris$Sepal.Length, method = "frequency", categories = 3)
disc_cluster   <- discretize(iris$Sepal.Length, method = "cluster",   categories = 3)
disc_fixed     <- discretize(iris$Sepal.Length, method = "fixed", breaks = c(4, 5.5, 6.5, 8))

table(disc_interval)
## disc_interval
## [4.3,5.5) [5.5,6.7) [6.7,7.9] 
##        52        70        28
table(disc_frequency)
## disc_frequency
## [4.3,5.4) [5.4,6.3) [6.3,7.9] 
##        46        53        51
table(disc_cluster)
## disc_cluster
##  [4.3,5.45) [5.45,6.46)  [6.46,7.9] 
##          52          63          35
table(disc_fixed)
## disc_fixed
##   [4,5.5) [5.5,6.5)   [6.5,8] 
##        52        63        35

Вывод

Функция discretize() позволяет преобразовать непрерывный признак в категориальный различными способами. Метод interval делит значения на интервалы равной ширины, метод frequency формирует группы с примерно одинаковым числом наблюдений, метод cluster учитывает внутреннюю структуру данных, а метод fixed использует заранее заданные границы интервалов. Разные методы дают различное распределение объектов по категориям.

4. Отбор признаков с использованием Boruta

library(Boruta)
library(mlbench)

data("Ozone")

oz <- as.data.frame(na.omit(Ozone))
names(oz)
##  [1] "V1"  "V2"  "V3"  "V4"  "V5"  "V6"  "V7"  "V8"  "V9"  "V10" "V11" "V12"
## [13] "V13"
# Берём целевую переменную как первый столбец набора данных.
# Это убирает ошибку, из-за которой Boruta падал при записи Ozone ~ .
target_name <- names(oz)[1]

boruta_formula <- as.formula(paste(target_name, "~ ."))

set.seed(123)

boruta_model <- Boruta(boruta_formula, data = oz, doTrace = 0, maxRuns = 100)
boruta_fixed <- TentativeRoughFix(boruta_model)

print(boruta_fixed)
## Boruta performed 99 iterations in 7.667946 secs.
## Tentatives roughfixed over the last 99 iterations.
##  11 attributes confirmed important: V10, V11, V12, V13, V2 and 6 more;
##  1 attributes confirmed unimportant: V3;
attStats(boruta_fixed)
##       meanImp medianImp     minImp     maxImp  normHits  decision
## V2   5.821010  5.760510  2.4218605  8.2687433 0.9797980 Confirmed
## V3  -2.007861 -1.906401 -3.7488538 -0.5040296 0.0000000  Rejected
## V4  13.527867 13.617397 10.6093334 16.1777653 1.0000000 Confirmed
## V5  12.638131 12.588665  9.5659164 15.4017924 1.0000000 Confirmed
## V6   8.907734  8.750138  7.0835291 11.8084425 1.0000000 Confirmed
## V7  13.768534 13.850814 11.6675590 16.4435466 1.0000000 Confirmed
## V8  18.372047 18.389383 14.9959683 20.5675910 1.0000000 Confirmed
## V9  15.467346 15.519464 13.7786194 17.3987793 1.0000000 Confirmed
## V10  2.938999  2.958775  0.4460529  6.1341493 0.4848485 Confirmed
## V11 20.195125 20.147894 17.9234128 22.7248519 1.0000000 Confirmed
## V12  7.925655  7.848049  4.7943829 10.5359125 1.0000000 Confirmed
## V13  5.462715  5.387792  3.3746432  8.0815512 0.9797980 Confirmed
plot(boruta_fixed, las = 2, cex.axis = 0.8, main = "Boruta feature selection for Ozone")

jpeg("boruta_boxplot.jpg", width = 1200, height = 800)
plot(boruta_fixed, las = 2, cex.axis = 0.8, main = "Boruta feature selection for Ozone")
dev.off()
## png 
##   2

Вывод

Для набора данных Ozone был выполнен отбор признаков методом Boruta. Алгоритм сравнивает важность реальных признаков с их случайными копиями и на этой основе выделяет значимые, сомнительные и незначимые признаки. Полученный boxplot позволяет визуально оценить вклад каждого признака в предсказание целевой переменной.

Общий вывод

В ходе лабораторной работы были изучены основные методы анализа и отбора признаков в R. С помощью пакета caret был выполнен графический разведочный анализ данных. При использовании FSelectorRcpp была определена важность признаков для задачи классификации на наборе iris. С помощью функции discretize() из пакета arules было выполнено преобразование непрерывного признака в категориальный различными методами. С использованием алгоритма Boruta был проведён отбор признаков для набора данных Ozone. Полученные результаты показывают, что анализ, преобразование и выбор признаков являются важной частью подготовки данных для построения моделей машинного обучения.