Цель работы — изучить методы графического анализа данных, оценки важности признаков, дискретизации непрерывных переменных и отбора признаков в языке R.
library(caret)
models <- names(getModelInfo())
length(models)
## [1] 239
В результате было получено 239 доступных методов машинного обучения
из пакета caret.
set.seed(123)
x <- matrix(rnorm(50 * 5), ncol = 5)
y <- factor(rep(c("A", "B"), 25))
colnames(x) <- paste0("V", 1:5)
data_caret <- data.frame(x)
head(data_caret)
## V1 V2 V3 V4 V5
## 1 -0.56047565 0.25331851 -0.71040656 0.7877388 2.1988103
## 2 -0.23017749 -0.02854676 0.25688371 0.7690422 1.3124130
## 3 1.55870831 -0.04287046 -0.24669188 0.3322026 -0.2651451
## 4 0.07050839 1.36860228 -0.34754260 -1.0083766 0.5431941
## 5 0.12928774 -0.22577099 -0.95161857 -0.1194526 -0.4143399
## 6 1.71506499 1.51647060 -0.04502772 -0.2803953 -0.4762469
featurePlot(
x = data_caret,
y = y,
plot = "pairs",
auto.key = list(columns = 2)
)
На графике представлена матрица диаграмм рассеяния для признаков V1–V5. Объекты классов A и B обозначены разными цветами. Видно, что точки двух классов сильно перемешаны, выраженного разделения между ними не наблюдается.
featurePlot(
x = data_caret,
y = y,
plot = "density",
scales = list(
x = list(relation = "free"),
y = list(relation = "free")
),
auto.key = list(columns = 2)
)
Графики плотности показывают распределение каждого признака отдельно для классов A и B. Для всех признаков наблюдается значительное перекрытие распределений, поэтому признаки плохо разделяют классы.
featurePlot(
x = data_caret,
y = y,
plot = "box",
scales = list(
y = list(relation = "free"),
x = list(rot = 90)
),
auto.key = list(columns = 2)
)
Диаграммы размаха показывают, что значения признаков для классов A и B существенно пересекаются. Это подтверждает, что данные не содержат выраженных закономерностей для разделения классов.
Вывод:
Данные были сгенерированы случайным образом, поэтому классы A и B плохо
разделяются по признакам V1–V5.
library(FSelectorRcpp)
data(iris)
importance <- information_gain(
Species ~ .,
data = iris
)
importance_sorted <- importance[order(-importance$importance), ]
importance_sorted
## attributes importance
## 4 Petal.Width 0.9554360
## 3 Petal.Length 0.9402853
## 1 Sepal.Length 0.4521286
## 2 Sepal.Width 0.2672750
barplot(
importance_sorted$importance,
names.arg = importance_sorted$attributes,
las = 2,
main = "Важность признаков для классификации iris",
ylab = "Information Gain"
)
На графике представлена важность признаков набора данных
iris, полученная методом Information Gain.
Вывод:
Наиболее важными признаками для классификации видов ириса являются
Petal.Width и Petal.Length. Признаки
Sepal.Length и Sepal.Width имеют меньшую
информативность. Следовательно, для определения вида ириса наиболее
полезны характеристики лепестков.
library(arules)
data(iris)
x <- iris$Sepal.Length
disc_interval <- discretize(
x,
method = "interval",
categories = 3
)
disc_frequency <- discretize(
x,
method = "frequency",
categories = 3
)
disc_cluster <- discretize(
x,
method = "cluster",
categories = 3
)
disc_fixed <- discretize(
x,
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.42) [5.42,6.39) [6.39,7.9]
## 52 56 42
table(disc_fixed)
## disc_fixed
## [4,5.5) [5.5,6.5) [6.5,8]
## 52 63 35
result <- data.frame(
Original = x,
Interval = disc_interval,
Frequency = disc_frequency,
Cluster = disc_cluster,
Fixed = disc_fixed
)
head(result, 20)
## Original Interval Frequency Cluster Fixed
## 1 5.1 [4.3,5.5) [4.3,5.4) [4.3,5.42) [4,5.5)
## 2 4.9 [4.3,5.5) [4.3,5.4) [4.3,5.42) [4,5.5)
## 3 4.7 [4.3,5.5) [4.3,5.4) [4.3,5.42) [4,5.5)
## 4 4.6 [4.3,5.5) [4.3,5.4) [4.3,5.42) [4,5.5)
## 5 5.0 [4.3,5.5) [4.3,5.4) [4.3,5.42) [4,5.5)
## 6 5.4 [4.3,5.5) [5.4,6.3) [4.3,5.42) [4,5.5)
## 7 4.6 [4.3,5.5) [4.3,5.4) [4.3,5.42) [4,5.5)
## 8 5.0 [4.3,5.5) [4.3,5.4) [4.3,5.42) [4,5.5)
## 9 4.4 [4.3,5.5) [4.3,5.4) [4.3,5.42) [4,5.5)
## 10 4.9 [4.3,5.5) [4.3,5.4) [4.3,5.42) [4,5.5)
## 11 5.4 [4.3,5.5) [5.4,6.3) [4.3,5.42) [4,5.5)
## 12 4.8 [4.3,5.5) [4.3,5.4) [4.3,5.42) [4,5.5)
## 13 4.8 [4.3,5.5) [4.3,5.4) [4.3,5.42) [4,5.5)
## 14 4.3 [4.3,5.5) [4.3,5.4) [4.3,5.42) [4,5.5)
## 15 5.8 [5.5,6.7) [5.4,6.3) [5.42,6.39) [5.5,6.5)
## 16 5.7 [5.5,6.7) [5.4,6.3) [5.42,6.39) [5.5,6.5)
## 17 5.4 [4.3,5.5) [5.4,6.3) [4.3,5.42) [4,5.5)
## 18 5.1 [4.3,5.5) [4.3,5.4) [4.3,5.42) [4,5.5)
## 19 5.7 [5.5,6.7) [5.4,6.3) [5.42,6.39) [5.5,6.5)
## 20 5.1 [4.3,5.5) [4.3,5.4) [4.3,5.42) [4,5.5)
Для признака Sepal.Length была выполнена дискретизация
четырьмя методами: interval, frequency,
cluster и fixed.
Вывод:
Метод interval делит диапазон значений на интервалы
одинаковой ширины. Метод frequency формирует группы с
примерно одинаковым количеством наблюдений. Метод cluster
выделяет группы на основе кластеризации. Метод fixed
позволяет вручную задать границы интервалов. Результаты различаются, так
как методы используют разные принципы формирования категорий.
library(Boruta)
library(mlbench)
data(Ozone)
Ozone_clean <- na.omit(Ozone)
set.seed(123)
boruta_result <- Boruta(
V4 ~ .,
data = Ozone_clean,
doTrace = 0
)
boruta_result
## Boruta performed 18 iterations in 0.5454578 secs.
## 9 attributes confirmed important: V1, V10, V11, V12, V13 and 4 more;
## 3 attributes confirmed unimportant: V2, V3, V6;
attStats(boruta_result)
## 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
plot(
boruta_result,
las = 2,
cex.axis = 0.8,
main = "Boruta Feature Selection"
)
На графике представлен результат отбора признаков методом Boruta для
набора данных Ozone. Зеленым цветом отмечены значимые
признаки, красным — незначимые, синим — теневые признаки, используемые
для сравнения.
Вывод:
Метод Boruta показал, что наиболее важными признаками для
прогнозирования переменной V4 являются V9,
V8 и V12. Признаки V2,
V3 и V6 были признаны малоинформативными.
Алгоритм позволил выделить признаки, наиболее влияющие на качество
модели.
В ходе лабораторной работы были изучены методы анализа и отбора
признаков в языке R. Пакет caret был использован для
графического разведочного анализа данных. С помощью
FSelectorRcpp была определена важность признаков на наборе
iris. Пакет arules позволил выполнить
дискретизацию непрерывной переменной различными методами. Метод Boruta
был применен для автоматического отбора значимых признаков на наборе
данных Ozone.
Работа показала, что предварительный анализ, преобразование и отбор признаков являются важными этапами подготовки данных к построению моделей машинного обучения.