featurePlot()library(caret)
## Загрузка требуемого пакета: ggplot2
## Загрузка требуемого пакета: lattice
length(names(getModelInfo()))
## [1] 239
head(names(getModelInfo()), 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"
Пакет caret содержит более 200 моделей машинного
обучения. Полный список можно получить командой
names(getModelInfo()).
Создадим случайные данные: 50 наблюдений, 5 признаков, две группы A и B.
set.seed(123)
x <- matrix(rnorm(50*5), ncol=5)
y <- factor(rep(c("A", "B"), 25))
head(x)
## [,1] [,2] [,3] [,4] [,5]
## [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
table(y)
## y
## A B
## 25 25
Построим четыре типа графиков с помощью
featurePlot().
featurePlot(x = x, y = y, plot = "pairs", main = "Pairs")
featurePlot(x = x, y = y, plot = "box")
featurePlot(x = x, y = y, plot = "density")
featurePlot(x = x, y = y, plot = "ellipse")
Данные сгенерированы случайно, метки класса y не связаны
с признаками x, поэтому на графиках не наблюдается
закономерного разделения классов: облака точек A и B полностью
перекрываются, распределения по всем 5 признакам практически идентичны,
эллипсы рассеяния сильно пересекаются.
Функция featurePlot() удобна для быстрой визуальной
оценки разделимости классов по признакам, однако в данном случае
признаки неинформативны.
FSelector
(iris)library(FSelector)
data(iris)
head(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
ig <- information.gain(Species ~ ., data = iris)
gr <- gain.ratio(Species ~ ., data = iris)
su <- symmetrical.uncertainty(Species ~ ., data = iris)
chi <- chi.squared(Species ~ ., data = iris)
rf <- random.forest.importance(Species ~ ., data = iris)
cbind(ig, gr, su, chi, rf)
## attr_importance attr_importance attr_importance attr_importance
## Sepal.Length 0.4521286 0.4196464 0.4155563 0.6288067
## Sepal.Width 0.2672750 0.2472972 0.2452743 0.4922162
## Petal.Length 0.9402853 0.8584937 0.8571872 0.9346311
## Petal.Width 0.9554360 0.8713692 0.8705214 0.9432359
## attr_importance
## Sepal.Length 15.215175
## Sepal.Width 4.983734
## Petal.Length 49.136910
## Petal.Width 47.063541
Все пять методов дали согласованный результат:
| Признак | Info Gain | Gain Ratio | Symm. Uncert. | Chi2 | Rand. Forest |
|---|---|---|---|---|---|
| Sepal.Length | 0.452 | 0.420 | 0.416 | 0.629 | 15.84 |
| Sepal.Width | 0.267 | 0.247 | 0.245 | 0.492 | 6.39 |
| Petal.Length | 0.940 | 0.858 | 0.857 | 0.935 | 45.36 |
| Petal.Width | 0.955 | 0.871 | 0.871 | 0.943 | 48.14 |
Порядок важности: Petal.Width > Petal.Length >> Sepal.Length > Sepal.Width
Признаки лепестка примерно в 2–7 раз информативнее признаков
чашелистика. Для классификации видов ириса достаточно двух признаков —
Petal.Width и Petal.Length.
discretize()
(arules)library(arules)
## Загрузка требуемого пакета: Matrix
##
## Присоединяю пакет: 'arules'
## Следующие объекты скрыты от 'package:base':
##
## abbreviate, write
data(iris)
d_interval <- discretize(iris$Sepal.Length, method = "interval", breaks = 3)
d_frequency <- discretize(iris$Sepal.Length, method = "frequency", breaks = 3)
d_cluster <- discretize(iris$Sepal.Length, method = "cluster", breaks = 3)
d_fixed <- discretize(iris$Sepal.Length, method = "fixed",
breaks = c(4, 5.5, 6.5, 8))
table(d_interval)
## d_interval
## [4.3,5.5) [5.5,6.7) [6.7,7.9]
## 52 70 28
table(d_frequency)
## d_frequency
## [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
## [4,5.5) [5.5,6.5) [6.5,8]
## 52 63 35
attr(d_interval, "discretized:breaks")
## [1] 4.3 5.5 6.7 7.9
attr(d_frequency, "discretized:breaks")
## [1] 4.3 5.4 6.3 7.9
attr(d_cluster, "discretized:breaks")
## [1] 4.300000 5.332732 6.272161 7.900000
| Метод | Границы | Кол-во в интервалах |
|---|---|---|
| interval | 4.3 - 5.5 - 6.7 - 7.9 | 52 / 70 / 28 |
| frequency | 4.3 - 5.4 - 6.3 - 7.9 | 46 / 53 / 51 |
| cluster | 4.30 - 5.33 - 6.27 - 7.90 | 46 / 53 / 51 |
| fixed | 4 - 5.5 - 6.5 - 8 | 52 / 63 / 35 |
Выбор метода зависит от задачи: для балансировки категорий лучше
frequency/cluster, для прикладных порогов —
fixed.
Boruta (Ozone)library(mlbench)
library(Boruta)
data(Ozone)
dim(Ozone)
## [1] 366 13
ozone_clean <- na.omit(Ozone)
ozone_clean <- ozone_clean[, sapply(ozone_clean, is.numeric)]
dim(ozone_clean)
## [1] 203 10
set.seed(123)
boruta_result <- Boruta(V4 ~ ., data = ozone_clean, doTrace = 0)
print(boruta_result)
## Boruta performed 27 iterations in 0.3265772 secs.
## 8 attributes confirmed important: V10, V11, V12, V13, V5 and 3 more;
## 1 attributes confirmed unimportant: V6;
table(boruta_result$finalDecision)
##
## Tentative Confirmed Rejected
## 0 8 1
plot(boruta_result, las = 2, cex.axis = 0.7,
main = "Boruta: важность признаков (Ozone)")
confirmed <- getSelectedAttributes(boruta_result, withTentative = FALSE)
print(confirmed)
## [1] "V5" "V7" "V8" "V9" "V10" "V11" "V12" "V13"
Алгоритм Boruta уверенно отобрал 8 из 9 признаков:
Признак V6 (температура поверхности) отвергнут — вероятно, дублирует информацию из других переменных. Для модели прогнозирования озона достаточно 8 подтверждённых признаков.