ШАГ 1 Установка пакета CARET
install.packages("caret", repos = "https://cran.r-project.org")
## пакет 'caret' успешно распакован, MD5-суммы проверены
## Warning: не могу удалить прежнюю установку пакета 'caret'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): проблема с копированием
## D:\App\R-4.5.0\library\00LOCK\caret\libs\x64\caret.dll в
## D:\App\R-4.5.0\library\caret\libs\x64\caret.dll: Permission denied
## Warning: восстановлен 'caret'
##
## Скачанные бинарные пакеты находятся в
## C:\Users\night\AppData\Local\Temp\RtmpOAO4zS\downloaded_packages
library(caret)
## Загрузка требуемого пакета: ggplot2
## Загрузка требуемого пакета: lattice
вывод списка доступных методов выбора признаков
print(names(getModelInfo()))
## [1] "ada" "AdaBag" "AdaBoost.M1"
## [4] "adaboost" "amdai" "ANFIS"
## [7] "avNNet" "awnb" "awtan"
## [10] "bag" "bagEarth" "bagEarthGCV"
## [13] "bagFDA" "bagFDAGCV" "bam"
## [16] "bartMachine" "bayesglm" "binda"
## [19] "blackboost" "blasso" "blassoAveraged"
## [22] "bridge" "brnn" "BstLm"
## [25] "bstSm" "bstTree" "C5.0"
## [28] "C5.0Cost" "C5.0Rules" "C5.0Tree"
## [31] "cforest" "chaid" "CSimca"
## [34] "ctree" "ctree2" "cubist"
## [37] "dda" "deepboost" "DENFIS"
## [40] "dnn" "dwdLinear" "dwdPoly"
## [43] "dwdRadial" "earth" "elm"
## [46] "enet" "evtree" "extraTrees"
## [49] "fda" "FH.GBML" "FIR.DM"
## [52] "foba" "FRBCS.CHI" "FRBCS.W"
## [55] "FS.HGD" "gam" "gamboost"
## [58] "gamLoess" "gamSpline" "gaussprLinear"
## [61] "gaussprPoly" "gaussprRadial" "gbm_h2o"
## [64] "gbm" "gcvEarth" "GFS.FR.MOGUL"
## [67] "GFS.LT.RS" "GFS.THRIFT" "glm.nb"
## [70] "glm" "glmboost" "glmnet_h2o"
## [73] "glmnet" "glmStepAIC" "gpls"
## [76] "hda" "hdda" "hdrda"
## [79] "HYFIS" "icr" "J48"
## [82] "JRip" "kernelpls" "kknn"
## [85] "knn" "krlsPoly" "krlsRadial"
## [88] "lars" "lars2" "lasso"
## [91] "lda" "lda2" "leapBackward"
## [94] "leapForward" "leapSeq" "Linda"
## [97] "lm" "lmStepAIC" "LMT"
## [100] "loclda" "logicBag" "LogitBoost"
## [103] "logreg" "lssvmLinear" "lssvmPoly"
## [106] "lssvmRadial" "lvq" "M5"
## [109] "M5Rules" "manb" "mda"
## [112] "Mlda" "mlp" "mlpKerasDecay"
## [115] "mlpKerasDecayCost" "mlpKerasDropout" "mlpKerasDropoutCost"
## [118] "mlpML" "mlpSGD" "mlpWeightDecay"
## [121] "mlpWeightDecayML" "monmlp" "msaenet"
## [124] "multinom" "mxnet" "mxnetAdam"
## [127] "naive_bayes" "nb" "nbDiscrete"
## [130] "nbSearch" "neuralnet" "nnet"
## [133] "nnls" "nodeHarvest" "null"
## [136] "OneR" "ordinalNet" "ordinalRF"
## [139] "ORFlog" "ORFpls" "ORFridge"
## [142] "ORFsvm" "ownn" "pam"
## [145] "parRF" "PART" "partDSA"
## [148] "pcaNNet" "pcr" "pda"
## [151] "pda2" "penalized" "PenalizedLDA"
## [154] "plr" "pls" "plsRglm"
## [157] "polr" "ppr" "pre"
## [160] "PRIM" "protoclass" "qda"
## [163] "QdaCov" "qrf" "qrnn"
## [166] "randomGLM" "ranger" "rbf"
## [169] "rbfDDA" "Rborist" "rda"
## [172] "regLogistic" "relaxo" "rf"
## [175] "rFerns" "RFlda" "rfRules"
## [178] "ridge" "rlda" "rlm"
## [181] "rmda" "rocc" "rotationForest"
## [184] "rotationForestCp" "rpart" "rpart1SE"
## [187] "rpart2" "rpartCost" "rpartScore"
## [190] "rqlasso" "rqnc" "RRF"
## [193] "RRFglobal" "rrlda" "RSimca"
## [196] "rvmLinear" "rvmPoly" "rvmRadial"
## [199] "SBC" "sda" "sdwd"
## [202] "simpls" "SLAVE" "slda"
## [205] "smda" "snn" "sparseLDA"
## [208] "spikeslab" "spls" "stepLDA"
## [211] "stepQDA" "superpc" "svmBoundrangeString"
## [214] "svmExpoString" "svmLinear" "svmLinear2"
## [217] "svmLinear3" "svmLinearWeights" "svmLinearWeights2"
## [220] "svmPoly" "svmRadial" "svmRadialCost"
## [223] "svmRadialSigma" "svmRadialWeights" "svmSpectrumString"
## [226] "tan" "tanSearch" "treebag"
## [229] "vbmpRadial" "vglmAdjCat" "vglmContRatio"
## [232] "vglmCumulative" "widekernelpls" "WM"
## [235] "wsrf" "xgbDART" "xgbLinear"
## [238] "xgbTree" "xyf"
выполнение разведочного анализа данных с использование функции featurePlot()
# Создание данных
x <- matrix(rnorm(50*5), ncol=5)
y <- factor(rep(c("A", "B"), 25))
data <- data.frame(x, class = y)
if (!dir.exists("feature_plots")) {
dir.create("feature_plots")
}
# Построение графика всех возсожных попарных взаимосвязей между столбцами X1 и X2 (X1 и X3 и тп)
plot_filename <- paste0("feature_plots/featurePlot_pairs.jpg")
jpeg(file = plot_filename, width = 1200, height = 1200)
print(featurePlot(x = data[, 1:5],
y = data$class,
plot = "pairs",
auto.key = list(space = "right")))
dev.off()
## png
## 2
# Построение графиков распределения значений каждого числового признака для класса А и В
for(i in 1:5){
plot_filename <- paste0("feature_plots/featurePlot_x", i, "_boxplot.jpg")
jpeg(file = plot_filename, width = 800, height = 600)
print(featurePlot(x = data[, 1:5], y = data$class, plot = "box",
auto.key = list(space = "right"),
scales = list(x = list(relation="free"),
y = list(relation="free"))))
dev.off()
}
Вывод: Для попарных взаимосвязей: - Признаки слабо связаны между собой: В большинстве scatterplot-ов точки распределены случайным образом, без четких закономерностей. Нет явного разделения классов: Точки разных классов (синие и желтые) перемешаны в каждом scatterplot-е.
Для распределения значений каждого числового признака: - Нет явных различий между классами A и B для большинства признаков. Признак X5 проявляет небольшое различие в медианах.
Общий вывод: - Разделение классов A и B на основе этих признаков будет сложной задачей.
ШАГ 2 Установка Fselector.
install.packages("FSelector", repos = "https://cran.r-project.org")
## пакет 'FSelector' успешно распакован, MD5-суммы проверены
##
## Скачанные бинарные пакеты находятся в
## C:\Users\night\AppData\Local\Temp\RtmpOAO4zS\downloaded_packages
library(FSelector)
Определение важности признаков для решения задачи классификации, используя набор data(iris).
# Создание данных
data(iris)
# Information Gain (измеряет, насколько информация о признаке уменьшает неопределенность целевой переменной)
weights_ig <- information.gain(Species ~ ., data = iris)
print("Information Gain:")
## [1] "Information Gain:"
print(weights_ig)
## attr_importance
## Sepal.Length 0.4521286
## Sepal.Width 0.2672750
## Petal.Length 0.9402853
## Petal.Width 0.9554360
# Gain Ratio (Является модификацией information gain, учитывающей количество возможных значений признака)
weights_gr <- gain.ratio(Species ~ ., data = iris)
print("Gain Ratio:")
## [1] "Gain Ratio:"
print(weights_gr)
## attr_importance
## Sepal.Length 0.4196464
## Sepal.Width 0.2472972
## Petal.Length 0.8584937
## Petal.Width 0.8713692
# Chi-Squared (измеряет зависимость между признаком и целевой переменной)
weights_cs <- chi.squared(Species ~ ., data = iris)
print("Chi-Squared:")
## [1] "Chi-Squared:"
print(weights_cs)
## attr_importance
## Sepal.Length 0.6288067
## Sepal.Width 0.4922162
## Petal.Length 0.9346311
## Petal.Width 0.9432359
# Random Forest Importance (Использует алгоритм случайного леса для оценки важности признаков)
weights_rf <- random.forest.importance(Species ~ ., data = iris, importance.type = 1)
print("Random Forest Importance:")
## [1] "Random Forest Importance:"
print(weights_rf)
## attr_importance
## Sepal.Length 15.884821
## Sepal.Width 6.194153
## Petal.Length 48.960281
## Petal.Width 48.372898
# Функция для визуализации важности признаков
plot_importance <- function(weights, title) {
weights$feature <- rownames(weights)
ggplot(weights, aes(x = reorder(feature,attr_importance), y = attr_importance)) +
geom_bar(stat = "identity", fill = "steelblue") +
coord_flip() +
labs(title = title, x = "Feature", y = "Importance") +
theme_minimal()
}
library(ggplot2)
# Визуализация Information Gain
plot_importance(weights_ig, "Information Gain")
Вывод: - имеет наибольшую важность (около 45) по сравнению с остальными признаками. Это означает, что длина лепестка является наиболее значимым фактором для классификации видов ирисов, основываясь на алгоритме случайного леса.
# Визуализация Gain Ratio
plot_importance(weights_gr, "Gain Ratio")
Вывод: - имеет высокую важность (около 42), хотя и немного меньше, чем Petal.Length. Это означает, что ширина лепестка также является важным фактором для классификации видов ирисов.
# Визуализация Chi-Squared
plot_importance(weights_cs, "Chi-Squared")
Вывод: - имеет умеренную важность (около 15). Это означает, что длина чашелистика вносит некоторый вклад в классификацию, но он менее значителен, чем длина и ширина лепестка.
# Визуализация Random Forest Importance
plot_importance(weights_rf, "Random Forest Importance")
Вывод: - имеет наименьшую важность (около 8) по сравнению с остальными признаками. Это означает, что ширина чашелистика является наименее значимым фактором для классификации видов ирисов.
Общий Вывод: - при построении модели классификации видов ирисов следует уделить особое внимание признакам Petal.Length и Petal.Width
ШАГ 3 Установка пакета arules
install.packages("arules", repos = "https://cran.r-project.org")
## пакет 'arules' успешно распакован, MD5-суммы проверены
## Warning: не могу удалить прежнюю установку пакета 'arules'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): проблема с копированием
## D:\App\R-4.5.0\library\00LOCK\arules\libs\x64\arules.dll в
## D:\App\R-4.5.0\library\arules\libs\x64\arules.dll: Permission denied
## Warning: восстановлен 'arules'
##
## Скачанные бинарные пакеты находятся в
## C:\Users\night\AppData\Local\Temp\RtmpOAO4zS\downloaded_packages
library(arules)
## Загрузка требуемого пакета: Matrix
##
## Присоединяю пакет: 'arules'
## Следующие объекты скрыты от 'package:base':
##
## abbreviate, write
Использованием функции discretize() преобразую непрерывную переменную в категориальную различными методами: «interval» (равная ширина интервала), «frequency» (равная частота), «cluster» (кластеризация) и «fixed» (категории задают границы интервалов), используя набор данных iris.
# Метод «interval» (равная ширина интервала)
# Выбираем только числовые столбцы (1-4)
numeric_cols <- iris[, 1:4]
# Дискретизируем каждый столбец
discretized_cols <- as.data.frame(lapply(numeric_cols, function(x) {
discretize(x, method = "interval", breaks = 3)
}))
# Собираем обратно в dataframe
iris_discretized <- cbind(discretized_cols, Species = iris$Species)
# Проверяем результат
summary(iris_discretized)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## [4.3,5.5):52 [2,2.8) :47 [1,2.97) :50 [0.1,0.9):50
## [5.5,6.7):70 [2.8,3.6):88 [2.97,4.93):54 [0.9,1.7):52
## [6.7,7.9]:28 [3.6,4.4]:15 [4.93,6.9] :46 [1.7,2.5]:48
## Species
## setosa :50
## versicolor:50
## virginica :50
Вывод: - Распределение по группам неравномерное (например, [5.5,6.7) содержит 70 наблюдений, а [6.7,7.9] — всего 28)
# Метод "frequency" (равная частота)
# Дискретизируем каждый столбец
discretized_cols <- as.data.frame(lapply(numeric_cols, function(x) {
discretize(x, method = "frequency", breaks = 3)
}))
# Собираем обратно в dataframe
iris_discretized <- cbind(discretized_cols, Species = iris$Species)
# Проверяем результат
summary(iris_discretized)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## [4.3,5.4):46 [2,2.9) :47 [1,2.63) :50 [0.1,0.867):50
## [5.4,6.3):53 [2.9,3.2):47 [2.63,4.9):49 [0.867,1.6):48
## [6.3,7.9]:51 [3.2,4.4]:56 [4.9,6.9] :51 [1.6,2.5] :52
## Species
## setosa :50
## versicolor:50
## virginica :50
Вывод: - Более сбалансированные группы (~50 наблюдений в каждом интервале)
# Метод "cluster" (кластеризация)
# Дискретизируем каждый столбец
discretized_cols <- as.data.frame(lapply(numeric_cols, function(x) {
discretize(x, method = "cluster", breaks = 3)
}))
# Собираем обратно в dataframe
iris_discretized <- cbind(discretized_cols, Species = iris$Species)
# Проверяем результат
summary(iris_discretized)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## [4.3,5.33) :46 [2,2.76) :33 [1,2.9) :50 [0.1,0.792) :50
## [5.33,6.27):53 [2.76,3.33):80 [2.9,5.01):58 [0.792,1.71):54
## [6.27,7.9] :51 [3.33,4.4] :37 [5.01,6.9]:42 [1.71,2.5] :46
## Species
## setosa :50
## versicolor:50
## virginica :50
Вывод: - учел структуру данных, дал хороший разброс
# Метод "fixed" (категории задают границы интервалов)
# Зададим границы интервалов для каждого столбца
breaks1 <- list(
Sepal.Length = c(4.3, 5.5, 6.5, 7.9),
Sepal.Width = c(2.0, 2.8, 3.3, 4.4),
Petal.Length = c(1.0, 3.0, 5.0, 6.9),
Petal.Width = c(0.1, 1.0, 1.8, 2.5)
)
# Выбираем только числовые столбцы (исключаем Species)
numeric_cols <- iris[, -5]
# Дискретизируем каждый столбец с соответствующими границами
discretized_cols <- as.data.frame(
mapply(function(x, breaks) {
discretize(x, method = "fixed", breaks = breaks)
},
numeric_cols,
breaks1,
SIMPLIFY = FALSE)
)
# Собираем обратно в dataframe
iris_discretized <- cbind(discretized_cols, Species = iris$Species)
# Проверяем результат
summary(iris_discretized)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## [4.3,5.5):52 [2,2.8) :33 [1,3) :50 [0.1,1) :50 setosa :50
## [5.5,6.5):63 [2.8,3.3):74 [3,5) :54 [1,1.8) :54 versicolor:50
## [6.5,7.9]:35 [3.3,4.4]:43 [5,6.9]:46 [1.8,2.5]:46 virginica :50
Вывод: - учел структуру данных, дал хороший разброс
Общий вывод: - Автоматические методы (frequency, cluster) часто предпочтительнее ручных, так как учитывают структуру данных.
ШАГ 4 Установка пакета Boruta и mlbench
install.packages("mlbench", repos = "https://cran.r-project.org")
## пакет 'mlbench' успешно распакован, MD5-суммы проверены
## Warning: не могу удалить прежнюю установку пакета 'mlbench'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): проблема с копированием
## D:\App\R-4.5.0\library\00LOCK\mlbench\libs\x64\mlbench.dll в
## D:\App\R-4.5.0\library\mlbench\libs\x64\mlbench.dll: Permission denied
## Warning: восстановлен 'mlbench'
##
## Скачанные бинарные пакеты находятся в
## C:\Users\night\AppData\Local\Temp\RtmpOAO4zS\downloaded_packages
library(mlbench)
Для Ozone сделать график boxplot
data(Ozone)
ozo <- na.omit(Ozone)
install.packages("Boruta", repos = "https://cran.r-project.org")
## пакет 'Boruta' успешно распакован, MD5-суммы проверены
##
## Скачанные бинарные пакеты находятся в
## C:\Users\night\AppData\Local\Temp\RtmpOAO4zS\downloaded_packages
library(Boruta)
Boruta_out <- Boruta(V4 ~., data=ozo, doTrace=2)
## 1. run of importance source...
## 2. run of importance source...
## 3. run of importance source...
## 4. run of importance source...
## 5. run of importance source...
## 6. run of importance source...
## 7. run of importance source...
## 8. run of importance source...
## 9. run of importance source...
## 10. run of importance source...
## 11. run of importance source...
## After 11 iterations, +0.93 secs:
## confirmed 9 attributes: V1, V10, V11, V12, V13 and 4 more;
## rejected 2 attributes: V2, V3;
## still have 1 attribute left.
## 12. run of importance source...
## 13. run of importance source...
## 14. run of importance source...
## 15. run of importance source...
## After 15 iterations, +1.3 secs:
## rejected 1 attribute: V6;
## no more attributes left.
getSelectedAttributes(Boruta_out)
## [1] "V1" "V5" "V7" "V8" "V9" "V10" "V11" "V12" "V13"
plot(Boruta_out, las=2, cex.axis=0.75)
Вывод: - V8 и V9: Эти атрибуты, вероятно, являются наиболее важными, поскольку их boxplots находятся выше всех остальных. - shadowMax: Этот shadow атрибут является контрольным. Важно сравнивать другие атрибуты с ним.