Устанавливаем пакет CARET, выводим список доступных моделей и методов выбора признаков.
library(caret)
mi <- getModelInfo()
length(mi)
## [1] 239
Примеры моделей, поддерживающих отбор признаков:
names(mi)[sapply(mi, function(m) "Recursive Feature Elimination" %in% m$tags)]
## character(0)
Основные функции отбора признаков в caret: rfe()
(Recursive Feature Elimination), sbf() (Selection By
Filter), filterVarImp() и featurePlot().
Создаём набор данных из задания и выполняем графический разведочный анализ.
x <- matrix(rnorm(50*5), ncol = 5)
y <- factor(rep(c("A", "B"), 25))
colnames(x) <- paste0("V", 1:5)
featurePlot(x, y, plot = "box", main = "box")
featurePlot(x, y, plot = "strip", main = "strip")
featurePlot(x, y, plot = "density", main = "density")
featurePlot(x, y, plot = "ellipse", main = "ellipse")
featurePlot(x, y, plot = "pairs", main = "pairs")
Вывод. Данные сгенерированы случайно
(rnorm), поэтому распределения классов A и B по всем
признакам перекрываются — признаки не разделяют классы.
library(FSelector)
data(iris)
information.gain(Species ~ ., iris)
## attr_importance
## Sepal.Length 0.4521286
## Sepal.Width 0.2672750
## Petal.Length 0.9402853
## Petal.Width 0.9554360
gain.ratio(Species ~ ., iris)
## attr_importance
## Sepal.Length 0.4196464
## Sepal.Width 0.2472972
## Petal.Length 0.8584937
## Petal.Width 0.8713692
symmetrical.uncertainty(Species ~ ., iris)
## attr_importance
## Sepal.Length 0.4155563
## Sepal.Width 0.2452743
## Petal.Length 0.8571872
## Petal.Width 0.8705214
chi.squared(Species ~ ., iris)
## attr_importance
## Sepal.Length 0.6288067
## Sepal.Width 0.4922162
## Petal.Length 0.9346311
## Petal.Width 0.9432359
Вывод. По всем метрикам наиболее важны Petal.Width и Petal.Length, наименее — Sepal.Width.
library(arules)
v <- iris$Sepal.Length
discretize(v, method = "interval", breaks = 4)
## [1] [4.3,5.2) [4.3,5.2) [4.3,5.2) [4.3,5.2) [4.3,5.2) [5.2,6.1) [4.3,5.2)
## [8] [4.3,5.2) [4.3,5.2) [4.3,5.2) [5.2,6.1) [4.3,5.2) [4.3,5.2) [4.3,5.2)
## [15] [5.2,6.1) [5.2,6.1) [5.2,6.1) [4.3,5.2) [5.2,6.1) [4.3,5.2) [5.2,6.1)
## [22] [4.3,5.2) [4.3,5.2) [4.3,5.2) [4.3,5.2) [4.3,5.2) [4.3,5.2) [5.2,6.1)
## [29] [5.2,6.1) [4.3,5.2) [4.3,5.2) [5.2,6.1) [5.2,6.1) [5.2,6.1) [4.3,5.2)
## [36] [4.3,5.2) [5.2,6.1) [4.3,5.2) [4.3,5.2) [4.3,5.2) [4.3,5.2) [4.3,5.2)
## [43] [4.3,5.2) [4.3,5.2) [4.3,5.2) [4.3,5.2) [4.3,5.2) [4.3,5.2) [5.2,6.1)
## [50] [4.3,5.2) [7,7.9] [6.1,7) [6.1,7) [5.2,6.1) [6.1,7) [5.2,6.1)
## [57] [6.1,7) [4.3,5.2) [6.1,7) [5.2,6.1) [4.3,5.2) [5.2,6.1) [5.2,6.1)
## [64] [6.1,7) [5.2,6.1) [6.1,7) [5.2,6.1) [5.2,6.1) [6.1,7) [5.2,6.1)
## [71] [5.2,6.1) [6.1,7) [6.1,7) [6.1,7) [6.1,7) [6.1,7) [6.1,7)
## [78] [6.1,7) [5.2,6.1) [5.2,6.1) [5.2,6.1) [5.2,6.1) [5.2,6.1) [5.2,6.1)
## [85] [5.2,6.1) [5.2,6.1) [6.1,7) [6.1,7) [5.2,6.1) [5.2,6.1) [5.2,6.1)
## [92] [6.1,7) [5.2,6.1) [4.3,5.2) [5.2,6.1) [5.2,6.1) [5.2,6.1) [6.1,7)
## [99] [4.3,5.2) [5.2,6.1) [6.1,7) [5.2,6.1) [7,7.9] [6.1,7) [6.1,7)
## [106] [7,7.9] [4.3,5.2) [7,7.9] [6.1,7) [7,7.9] [6.1,7) [6.1,7)
## [113] [6.1,7) [5.2,6.1) [5.2,6.1) [6.1,7) [6.1,7) [7,7.9] [7,7.9]
## [120] [5.2,6.1) [6.1,7) [5.2,6.1) [7,7.9] [6.1,7) [6.1,7) [7,7.9]
## [127] [6.1,7) [6.1,7) [6.1,7) [7,7.9] [7,7.9] [7,7.9] [6.1,7)
## [134] [6.1,7) [6.1,7) [7,7.9] [6.1,7) [6.1,7) [5.2,6.1) [6.1,7)
## [141] [6.1,7) [6.1,7) [5.2,6.1) [6.1,7) [6.1,7) [6.1,7) [6.1,7)
## [148] [6.1,7) [6.1,7) [5.2,6.1)
## attr(,"discretized:breaks")
## [1] 4.3 5.2 6.1 7.0 7.9
## attr(,"discretized:method")
## [1] interval
## Levels: [4.3,5.2) [5.2,6.1) [6.1,7) [7,7.9]
discretize(v, method = "frequency", breaks = 4)
## [1] [5.1,5.8) [4.3,5.1) [4.3,5.1) [4.3,5.1) [4.3,5.1) [5.1,5.8) [4.3,5.1)
## [8] [4.3,5.1) [4.3,5.1) [4.3,5.1) [5.1,5.8) [4.3,5.1) [4.3,5.1) [4.3,5.1)
## [15] [5.8,6.4) [5.1,5.8) [5.1,5.8) [5.1,5.8) [5.1,5.8) [5.1,5.8) [5.1,5.8)
## [22] [5.1,5.8) [4.3,5.1) [5.1,5.8) [4.3,5.1) [4.3,5.1) [4.3,5.1) [5.1,5.8)
## [29] [5.1,5.8) [4.3,5.1) [4.3,5.1) [5.1,5.8) [5.1,5.8) [5.1,5.8) [4.3,5.1)
## [36] [4.3,5.1) [5.1,5.8) [4.3,5.1) [4.3,5.1) [5.1,5.8) [4.3,5.1) [4.3,5.1)
## [43] [4.3,5.1) [4.3,5.1) [5.1,5.8) [4.3,5.1) [5.1,5.8) [4.3,5.1) [5.1,5.8)
## [50] [4.3,5.1) [6.4,7.9] [6.4,7.9] [6.4,7.9] [5.1,5.8) [6.4,7.9] [5.1,5.8)
## [57] [5.8,6.4) [4.3,5.1) [6.4,7.9] [5.1,5.8) [4.3,5.1) [5.8,6.4) [5.8,6.4)
## [64] [5.8,6.4) [5.1,5.8) [6.4,7.9] [5.1,5.8) [5.8,6.4) [5.8,6.4) [5.1,5.8)
## [71] [5.8,6.4) [5.8,6.4) [5.8,6.4) [5.8,6.4) [6.4,7.9] [6.4,7.9] [6.4,7.9]
## [78] [6.4,7.9] [5.8,6.4) [5.1,5.8) [5.1,5.8) [5.1,5.8) [5.8,6.4) [5.8,6.4)
## [85] [5.1,5.8) [5.8,6.4) [6.4,7.9] [5.8,6.4) [5.1,5.8) [5.1,5.8) [5.1,5.8)
## [92] [5.8,6.4) [5.8,6.4) [4.3,5.1) [5.1,5.8) [5.1,5.8) [5.1,5.8) [5.8,6.4)
## [99] [5.1,5.8) [5.1,5.8) [5.8,6.4) [5.8,6.4) [6.4,7.9] [5.8,6.4) [6.4,7.9]
## [106] [6.4,7.9] [4.3,5.1) [6.4,7.9] [6.4,7.9] [6.4,7.9] [6.4,7.9] [6.4,7.9]
## [113] [6.4,7.9] [5.1,5.8) [5.8,6.4) [6.4,7.9] [6.4,7.9] [6.4,7.9] [6.4,7.9]
## [120] [5.8,6.4) [6.4,7.9] [5.1,5.8) [6.4,7.9] [5.8,6.4) [6.4,7.9] [6.4,7.9]
## [127] [5.8,6.4) [5.8,6.4) [6.4,7.9] [6.4,7.9] [6.4,7.9] [6.4,7.9] [6.4,7.9]
## [134] [5.8,6.4) [5.8,6.4) [6.4,7.9] [5.8,6.4) [6.4,7.9] [5.8,6.4) [6.4,7.9]
## [141] [6.4,7.9] [6.4,7.9] [5.8,6.4) [6.4,7.9] [6.4,7.9] [6.4,7.9] [5.8,6.4)
## [148] [6.4,7.9] [5.8,6.4) [5.8,6.4)
## attr(,"discretized:breaks")
## [1] 4.3 5.1 5.8 6.4 7.9
## attr(,"discretized:method")
## [1] frequency
## Levels: [4.3,5.1) [5.1,5.8) [5.8,6.4) [6.4,7.9]
discretize(v, method = "cluster", breaks = 4)
## [1] [4.3,5.28) [4.3,5.28) [4.3,5.28) [4.3,5.28) [4.3,5.28) [5.28,6.05)
## [7] [4.3,5.28) [4.3,5.28) [4.3,5.28) [4.3,5.28) [5.28,6.05) [4.3,5.28)
## [13] [4.3,5.28) [4.3,5.28) [5.28,6.05) [5.28,6.05) [5.28,6.05) [4.3,5.28)
## [19] [5.28,6.05) [4.3,5.28) [5.28,6.05) [4.3,5.28) [4.3,5.28) [4.3,5.28)
## [25] [4.3,5.28) [4.3,5.28) [4.3,5.28) [4.3,5.28) [4.3,5.28) [4.3,5.28)
## [31] [4.3,5.28) [5.28,6.05) [4.3,5.28) [5.28,6.05) [4.3,5.28) [4.3,5.28)
## [37] [5.28,6.05) [4.3,5.28) [4.3,5.28) [4.3,5.28) [4.3,5.28) [4.3,5.28)
## [43] [4.3,5.28) [4.3,5.28) [4.3,5.28) [4.3,5.28) [4.3,5.28) [4.3,5.28)
## [49] [5.28,6.05) [4.3,5.28) [6.87,7.9] [6.05,6.87) [6.87,7.9] [5.28,6.05)
## [55] [6.05,6.87) [5.28,6.05) [6.05,6.87) [4.3,5.28) [6.05,6.87) [4.3,5.28)
## [61] [4.3,5.28) [5.28,6.05) [5.28,6.05) [6.05,6.87) [5.28,6.05) [6.05,6.87)
## [67] [5.28,6.05) [5.28,6.05) [6.05,6.87) [5.28,6.05) [5.28,6.05) [6.05,6.87)
## [73] [6.05,6.87) [6.05,6.87) [6.05,6.87) [6.05,6.87) [6.05,6.87) [6.05,6.87)
## [79] [5.28,6.05) [5.28,6.05) [5.28,6.05) [5.28,6.05) [5.28,6.05) [5.28,6.05)
## [85] [5.28,6.05) [5.28,6.05) [6.05,6.87) [6.05,6.87) [5.28,6.05) [5.28,6.05)
## [91] [5.28,6.05) [6.05,6.87) [5.28,6.05) [4.3,5.28) [5.28,6.05) [5.28,6.05)
## [97] [5.28,6.05) [6.05,6.87) [4.3,5.28) [5.28,6.05) [6.05,6.87) [5.28,6.05)
## [103] [6.87,7.9] [6.05,6.87) [6.05,6.87) [6.87,7.9] [4.3,5.28) [6.87,7.9]
## [109] [6.05,6.87) [6.87,7.9] [6.05,6.87) [6.05,6.87) [6.05,6.87) [5.28,6.05)
## [115] [5.28,6.05) [6.05,6.87) [6.05,6.87) [6.87,7.9] [6.87,7.9] [5.28,6.05)
## [121] [6.87,7.9] [5.28,6.05) [6.87,7.9] [6.05,6.87) [6.05,6.87) [6.87,7.9]
## [127] [6.05,6.87) [6.05,6.87) [6.05,6.87) [6.87,7.9] [6.87,7.9] [6.87,7.9]
## [133] [6.05,6.87) [6.05,6.87) [6.05,6.87) [6.87,7.9] [6.05,6.87) [6.05,6.87)
## [139] [5.28,6.05) [6.87,7.9] [6.05,6.87) [6.87,7.9] [5.28,6.05) [6.05,6.87)
## [145] [6.05,6.87) [6.05,6.87) [6.05,6.87) [6.05,6.87) [6.05,6.87) [5.28,6.05)
## attr(,"discretized:breaks")
## [1] 4.300000 5.280833 6.048864 6.867246 7.900000
## attr(,"discretized:method")
## [1] cluster
## Levels: [4.3,5.28) [5.28,6.05) [6.05,6.87) [6.87,7.9]
discretize(v, method = "fixed", breaks = c(4, 5, 6, 7, 8))
## [1] [5,6) [4,5) [4,5) [4,5) [5,6) [5,6) [4,5) [5,6) [4,5) [4,5) [5,6) [4,5)
## [13] [4,5) [4,5) [5,6) [5,6) [5,6) [5,6) [5,6) [5,6) [5,6) [5,6) [4,5) [5,6)
## [25] [4,5) [5,6) [5,6) [5,6) [5,6) [4,5) [4,5) [5,6) [5,6) [5,6) [4,5) [5,6)
## [37] [5,6) [4,5) [4,5) [5,6) [5,6) [4,5) [4,5) [5,6) [5,6) [4,5) [5,6) [4,5)
## [49] [5,6) [5,6) [7,8] [6,7) [6,7) [5,6) [6,7) [5,6) [6,7) [4,5) [6,7) [5,6)
## [61] [5,6) [5,6) [6,7) [6,7) [5,6) [6,7) [5,6) [5,6) [6,7) [5,6) [5,6) [6,7)
## [73] [6,7) [6,7) [6,7) [6,7) [6,7) [6,7) [6,7) [5,6) [5,6) [5,6) [5,6) [6,7)
## [85] [5,6) [6,7) [6,7) [6,7) [5,6) [5,6) [5,6) [6,7) [5,6) [5,6) [5,6) [5,6)
## [97] [5,6) [6,7) [5,6) [5,6) [6,7) [5,6) [7,8] [6,7) [6,7) [7,8] [4,5) [7,8]
## [109] [6,7) [7,8] [6,7) [6,7) [6,7) [5,6) [5,6) [6,7) [6,7) [7,8] [7,8] [6,7)
## [121] [6,7) [5,6) [7,8] [6,7) [6,7) [7,8] [6,7) [6,7) [6,7) [7,8] [7,8] [7,8]
## [133] [6,7) [6,7) [6,7) [7,8] [6,7) [6,7) [6,7) [6,7) [6,7) [6,7) [5,6) [6,7)
## [145] [6,7) [6,7) [6,7) [6,7) [6,7) [5,6)
## attr(,"discretized:breaks")
## [1] 4 5 6 7 8
## attr(,"discretized:method")
## [1] fixed
## Levels: [4,5) [5,6) [6,7) [7,8]
Вывод. interval — равная ширина,
frequency — равная частота, cluster — границы
по k-means, fixed — заданные пользователем границы.
library(Boruta)
library(mlbench)
data(Ozone)
oz <- na.omit(Ozone)
set.seed(123)
bor <- Boruta(V4 ~ ., data = oz)
print(bor)
## Boruta performed 18 iterations in 0.427768 secs.
## 9 attributes confirmed important: V1, V10, V11, V12, V13 and 4 more;
## 3 attributes confirmed unimportant: V2, V3, V6;
attStats(bor)
## 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(bor, las = 2, cex.axis = 0.7, main = "Boruta: важность признаков (Ozone)")
plotImpHistory(bor, main = "История важности признаков")
Вывод. Boruta подтвердил значимость 9 признаков и отклонил 3 (V2, V3, V6). Наибольшая важность — у признака V9.
В работе изучены пакеты caret и Boruta: графический разведочный
анализ (featurePlot), отбор признаков методами FSelector,
дискретизация непрерывных переменных (arules::discretize) и
«обёрточный» отбор признаков Boruta.