Освоить пакеты CARET, FSelector, arules и Boruta для первичного анализа данных, оценки важности признаков, дискретизации и отбора предикторов в языке R.
По условию сформирована матрица из 50 объектов и 5 признаков; метки классов A и B чередуются.
library(caret)
x <- matrix(rnorm(50 * 5), ncol = 5)
colnames(x) <- paste0("X", 1:5)
y <- factor(rep(c("A", "B"), 25))
methods <- names(getModelInfo())
length(methods)## [1] 239
## [1] "ada" "AdaBag" "AdaBoost.M1" "adaboost"
## [5] "amdai" "ANFIS" "avNNet" "awnb"
## [9] "awtan" "bag" "bagEarth" "bagEarthGCV"
## [13] "bagFDA" "bagFDAGCV" "bam" "bartMachine"
## [17] "bayesglm" "binda" "blackboost" "blasso"
## [21] "blassoAveraged" "bridge" "brnn" "BstLm"
## [25] "bstSm"
В установленной версии CARET доступно 239 методов. Ниже приведены матрица парных диаграмм и плотности распределений для всех пяти признаков.
CARET: <U+043C><U+0430><U+0442><U+0440><U+0438><U+0446><U+0430> <U+043F><U+0430><U+0440><U+043D><U+044B><U+0445> <U+0434><U+0438><U+0430><U+0433><U+0440><U+0430><U+043C><U+043C> <U+0434><U+043B><U+044F> <U+0443><U+0447><U+0435><U+0431><U+043D><U+043E><U+0439> <U+043C><U+0430><U+0442><U+0440><U+0438><U+0446><U+044B>
CARET: <U+043F><U+043B><U+043E><U+0442><U+043D><U+043E><U+0441><U+0442><U+0438> <U+043F><U+0440><U+0438><U+0437><U+043D><U+0430><U+043A><U+043E><U+0432> <U+043F><U+043E> <U+043A><U+043B><U+0430><U+0441><U+0441><U+0430><U+043C> A <U+0438> B
Вывод. Выраженного разделения классов нет, что ожидаемо: признаки сгенерированы из одного распределения и не содержат искусственной зависимости от класса.
Используется встроенный открытый набор iris: 150
наблюдений трёх видов ириса и четыре числовых признака. Важность
вычислена методом Gain Ratio.
library(FSelector)
data(iris)
weights <- gain.ratio(Species ~ ., iris)
weights <- weights[order(weights$attr_importance, decreasing = TRUE), , drop = FALSE]
weightsbarplot(weights$attr_importance, names.arg = rownames(weights), las = 1,
col = "steelblue", ylim = c(0, max(weights$attr_importance) * 1.15),
main = "Важность признаков Iris: Gain Ratio", ylab = "Gain Ratio")
text(seq_along(weights$attr_importance), weights$attr_importance,
labels = sprintf("%.3f", weights$attr_importance), pos = 3)<U+0412><U+0430><U+0436><U+043D><U+043E><U+0441><U+0442><U+044C> <U+043F><U+0440><U+0438><U+0437><U+043D><U+0430><U+043A><U+043E><U+0432> iris <U+043F><U+043E> Gain Ratio
Вывод. Наиболее полезны размеры лепестка:
Petal.Width (0.871) и Petal.Length (0.858).
Sepal.Width (0.247) имеет наименьшую важность.
Сравниваются четыре стратегии дискретизации: равная ширина интервалов, равная частота, кластерное разбиение и заранее фиксированные границы.
library(arules)
v <- iris$Sepal.Length
d_interval <- discretize(v, method = "interval", categories = 3)
d_frequency <- discretize(v, method = "frequency", categories = 3)
d_cluster <- discretize(v, method = "cluster", categories = 3)
d_fixed <- discretize(v, method = "fixed", breaks = c(4.0, 5.2, 6.3, 8.0))
disc <- data.frame(interval = d_interval, frequency = d_frequency,
cluster = d_cluster, fixed = d_fixed)
lapply(disc, table)## $interval
##
## [4.3,5.5) [5.5,6.7) [6.7,7.9]
## 52 70 28
##
## $frequency
##
## [4.3,5.4) [5.4,6.3) [6.3,7.9]
## 46 53 51
##
## $cluster
##
## [4.3,5.33) [5.33,6.27) [6.27,7.9]
## 46 53 51
##
## $fixed
##
## [4,5.2) [5.2,6.3) [6.3,8]
## 41 58 51
par(mfrow = c(2, 2), mar = c(8, 4, 3, 1))
for (nm in names(disc)) {
barplot(table(disc[[nm]]), las = 2, col = "darkseagreen3",
main = nm, ylab = "Число наблюдений")
}<U+0427><U+0438><U+0441><U+043B><U+0435><U+043D><U+043D><U+043E><U+0441><U+0442><U+044C> <U+043A><U+0430><U+0442><U+0435><U+0433><U+043E><U+0440><U+0438><U+0439> <U+043F><U+0440><U+0438> <U+0447><U+0435><U+0442><U+044B><U+0440><U+0451><U+0445> <U+0441><U+043F><U+043E><U+0441><U+043E><U+0431><U+0430><U+0445> <U+0434><U+0438><U+0441><U+043A><U+0440><U+0435><U+0442><U+0438><U+0437><U+0430><U+0446><U+0438><U+0438>
Вывод. Метод frequency даёт почти
одинаковые по численности категории; interval делит
диапазон на равные по ширине части; cluster подбирает
границы по структуре данных; fixed нужен, когда границы
определяются предметной областью.
Используется открытый набор Ozone из
mlbench. После удаления строк с пропусками остаётся 203
полных наблюдения. Целевой переменной является V4.
library(mlbench)
library(Boruta)
data(Ozone)
oz <- na.omit(Ozone)
set.seed(20260912)
bor <- Boruta(V4 ~ ., data = oz, doTrace = 0, maxRuns = 100)
data.frame(attribute = names(bor$finalDecision),
decision = as.character(bor$finalDecision))Boruta: <U+0437><U+043D><U+0430><U+0447><U+0438><U+043C><U+043E><U+0441><U+0442><U+044C> <U+043F><U+0440><U+0438><U+0437><U+043D><U+0430><U+043A><U+043E><U+0432> <U+0434><U+043B><U+044F> <U+0446><U+0435><U+043B><U+0435><U+0432><U+043E><U+0439> <U+043F><U+0435><U+0440><U+0435><U+043C><U+0435><U+043D><U+043D><U+043E><U+0439> V4 <U+0432> Ozone
Вывод. Подтверждены признаки V1,
V5, V7–V13; отклонены
V2, V3 и V6. Подтверждённые
признаки устойчиво превосходят случайные «теневые» признаки и подходят
для дальнейшего моделирования.
В работе выполнен EDA с CARET, определена важность признаков Iris, сопоставлены четыре варианта дискретизации и проведён отбор Boruta для Ozone. Все результаты получены запуском приведённых воспроизводимых фрагментов R-кода.