Изучить методы разведочного анализа данных, оценки значимости и отбора признаков, а также способы дискретизации непрерывных переменных с использованием пакетов caret, FSelector, arules и Boruta языка R.
library(caret)
# Список доступных моделей
model_names <- names(getModelInfo())
print(model_names)
## [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"
# Создание набора данных
set.seed(123)
x <- matrix(rnorm(50 * 5), ncol = 5)
colnames(x) <- paste0("X", 1:5)
y <- factor(rep(c("A", "B"), 25))
# Графический анализ
featurePlot(x = x, y = y, plot = "box")
featurePlot(x = x, y = y, plot = "density")
featurePlot(x = x, y = y, plot = "pairs")
# Сохранение графиков в JPG
jpeg("LR2_box.jpg", width = 1200, height = 800)
print(featurePlot(x = x, y = y, plot = "box"))
dev.off()
## png
## 2
jpeg("LR2_density.jpg", width = 1200, height = 800)
print(featurePlot(x = x, y = y, plot = "density"))
dev.off()
## png
## 2
jpeg("LR2_pairs.jpg", width = 1200, height = 1200)
print(featurePlot(x = x, y = y, plot = "pairs"))
dev.off()
## png
## 2
В ходе выполнения задания были изучены возможности пакета caret и
получен список доступных моделей машинного обучения с помощью функции
getModelInfo().
С использованием функции featurePlot() построены графики
типа boxplot, density и pairs для пяти числовых признаков и двух классов
A и B.
Анализ графиков показал, что распределения значений признаков двух классов в значительной степени пересекаются. Выраженного разделения классов по отдельным признакам не наблюдается. Это объясняется тем, что исходные данные были сформированы случайным образом и не содержат специально заданной зависимости между признаками и классами.
Полученные графики сохранены в формате JPG.
В данном задании используется встроенный набор данных iris, содержащий характеристики цветков трёх видов ирисов. Для оценки информативности признаков применяется метод Information Gain.
library(FSelector)
data(iris)
# Просмотр структуры данных
str(iris)
## 'data.frame': 150 obs. of 5 variables:
## $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
## $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
## $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
## $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
## $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
# Оценка важности признаков
importance <- information.gain(Species ~ ., data = iris)
# Вывод результатов
print(importance)
## attr_importance
## Sepal.Length 0.4521286
## Sepal.Width 0.2672750
## Petal.Length 0.9402853
## Petal.Width 0.9554360
# Сортировка признаков по важности
importance_sorted <- importance[
order(importance$attr_importance, decreasing = TRUE),
,
drop = FALSE
]
print(importance_sorted)
## attr_importance
## Petal.Width 0.9554360
## Petal.Length 0.9402853
## Sepal.Length 0.4521286
## Sepal.Width 0.2672750
# График важности признаков
par(mar = c(10, 5, 4, 2))
barplot(
importance_sorted$attr_importance,
names.arg = rownames(importance_sorted),
col = "skyblue",
main = "Важность признаков набора iris",
ylab = "Information Gain",
las = 2,
cex.names = 0.8
)
В ходе выполнения задания была проведена оценка важности признаков набора данных iris с использованием пакета FSelector и метода Information Gain.
Наиболее информативными признаками для классификации видов ирисов являются длина и ширина лепестков (Petal.Length и Petal.Width). Признаки, характеризующие чашелистики (Sepal.Length и Sepal.Width), обладают меньшей информативностью.
Таким образом, использование методов оценки важности признаков позволяет определить характеристики, оказывающие наибольшее влияние на качество классификации, и сократить количество используемых признаков.
В данном задании выполняется преобразование непрерывной переменной
Sepal.Length набора данных iris в категориальную с помощью функции
discretize() пакета arules.
Рассматриваются четыре метода дискретизации: interval, frequency, cluster и fixed.
library(arules)
data(iris)
# Выбор непрерывной переменной
x_disc <- iris$Sepal.Length
# 1. Равная ширина интервалов
disc_interval <- discretize(
x_disc, method = "interval", categories = 3
)
# 2. Равная частота
disc_frequency <- discretize(
x_disc, method = "frequency", categories = 3
)
# 3. Кластеризация
disc_cluster <- discretize(
x_disc, method = "cluster", categories = 3
)
# 4. Фиксированные границы
disc_fixed <- discretize(
x_disc,
method = "fixed",
breaks = c(-Inf, 5.5, 6.5, Inf)
)
# Таблица результатов
results <- data.frame(
Original = x_disc,
Interval = disc_interval,
Frequency = disc_frequency,
Cluster = disc_cluster,
Fixed = disc_fixed
)
head(results, 15)
## Original Interval Frequency Cluster Fixed
## 1 5.1 [4.3,5.5) [4.3,5.4) [4.3,5.33) [-Inf,5.5)
## 2 4.9 [4.3,5.5) [4.3,5.4) [4.3,5.33) [-Inf,5.5)
## 3 4.7 [4.3,5.5) [4.3,5.4) [4.3,5.33) [-Inf,5.5)
## 4 4.6 [4.3,5.5) [4.3,5.4) [4.3,5.33) [-Inf,5.5)
## 5 5.0 [4.3,5.5) [4.3,5.4) [4.3,5.33) [-Inf,5.5)
## 6 5.4 [4.3,5.5) [5.4,6.3) [5.33,6.27) [-Inf,5.5)
## 7 4.6 [4.3,5.5) [4.3,5.4) [4.3,5.33) [-Inf,5.5)
## 8 5.0 [4.3,5.5) [4.3,5.4) [4.3,5.33) [-Inf,5.5)
## 9 4.4 [4.3,5.5) [4.3,5.4) [4.3,5.33) [-Inf,5.5)
## 10 4.9 [4.3,5.5) [4.3,5.4) [4.3,5.33) [-Inf,5.5)
## 11 5.4 [4.3,5.5) [5.4,6.3) [5.33,6.27) [-Inf,5.5)
## 12 4.8 [4.3,5.5) [4.3,5.4) [4.3,5.33) [-Inf,5.5)
## 13 4.8 [4.3,5.5) [4.3,5.4) [4.3,5.33) [-Inf,5.5)
## 14 4.3 [4.3,5.5) [4.3,5.4) [4.3,5.33) [-Inf,5.5)
## 15 5.8 [5.5,6.7) [5.4,6.3) [5.33,6.27) [5.5,6.5)
# Количество значений в каждой категории
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.33) [5.33,6.27) [6.27,7.9]
## 46 53 51
table(disc_fixed)
## disc_fixed
## [-Inf,5.5) [5.5,6.5) [6.5, Inf]
## 52 63 35
# Визуальное сравнение
par(mfrow = c(2, 2), mar = c(7, 4, 3, 1))
barplot(table(disc_interval),
main = "Interval",
col = "lightblue",
las = 2)
barplot(table(disc_frequency),
main = "Frequency",
col = "lightgreen",
las = 2)
barplot(table(disc_cluster),
main = "Cluster",
col = "lightpink",
las = 2)
barplot(table(disc_fixed),
main = "Fixed",
col = "lightyellow",
las = 2)
par(mfrow = c(1, 1))
В ходе выполнения задания были изучены четыре метода дискретизации
непрерывных переменных с использованием функции
discretize() пакета arules.
Метод interval разделяет диапазон значений на интервалы одинаковой ширины. Метод frequency формирует категории с приблизительно одинаковым количеством наблюдений. Метод cluster группирует близкие значения на основе кластеризации. Метод fixed позволяет самостоятельно задавать границы категорий.
Таким образом, выбор метода дискретизации влияет на распределение наблюдений по категориям. Метод frequency подходит для получения более сбалансированных групп, interval — для равномерного разделения диапазона значений, cluster — для выделения групп близких значений, а fixed — для использования заранее определённых границ.
В данном задании выполняется отбор информативных признаков с помощью алгоритма Boruta. Для анализа используется набор данных Ozone из пакета mlbench.
Алгоритм Boruta оценивает значимость признаков путём сравнения их важности с важностью случайно перемешанных теневых признаков.
library(Boruta)
library(mlbench)
# Загрузка данных
data("Ozone", package = "mlbench")
# Просмотр структуры данных
str(Ozone)
## 'data.frame': 366 obs. of 13 variables:
## $ V1 : Factor w/ 12 levels "1","2","3","4",..: 1 1 1 1 1 1 1 1 1 1 ...
## $ V2 : Factor w/ 31 levels "1","2","3","4",..: 1 2 3 4 5 6 7 8 9 10 ...
## $ V3 : Factor w/ 7 levels "1","2","3","4",..: 4 5 6 7 1 2 3 4 5 6 ...
## $ V4 : num 3 3 3 5 5 6 4 4 6 7 ...
## $ V5 : num 5480 5660 5710 5700 5760 5720 5790 5790 5700 5700 ...
## $ V6 : num 8 6 4 3 3 4 6 3 3 3 ...
## $ V7 : num 20 NA 28 37 51 69 19 25 73 59 ...
## $ V8 : num NA 38 40 45 54 35 45 55 41 44 ...
## $ V9 : num NA NA NA NA 45.3 ...
## $ V10: num 5000 NA 2693 590 1450 ...
## $ V11: num -15 -14 -25 -24 25 15 -33 -28 23 -2 ...
## $ V12: num 30.6 NA 47.7 55 57 ...
## $ V13: num 200 300 250 100 60 60 100 250 120 120 ...
# Удаление наблюдений с пропущенными значениями
ozone_clean <- na.omit(Ozone)
# Проверка количества наблюдений
cat("Количество наблюдений:", nrow(ozone_clean), "\n")
## Количество наблюдений: 203
# Запуск алгоритма Boruta
set.seed(123)
boruta_result <- Boruta(
V4 ~ .,
data = ozone_clean,
doTrace = 0,
maxRuns = 100
)
# Результаты отбора признаков
print(boruta_result)
## Boruta performed 18 iterations in 1.259849 secs.
## 9 attributes confirmed important: V1, V10, V11, V12, V13 and 4 more;
## 3 attributes confirmed unimportant: V2, V3, V6;
# Статистика важности признаков
print(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
# График boxplot
plot(
boruta_result,
main = "Результаты отбора признаков Boruta",
las = 2,
cex.axis = 0.7
)
В ходе выполнения задания был применён алгоритм Boruta для отбора информативных признаков набора данных Ozone.
По результатам анализа были выделены девять значимых признаков: V5, V1, V10, V13, V7, V11, V12, V8 и V9. Наибольшую важность продемонстрировали признаки V9, V8 и V12.
Признаки V2, V3 и V6 были признаны неинформативными. На графике boxplot наглядно представлены распределения оценок важности признаков и результаты их сравнения с теневыми признаками.
Таким образом, алгоритм Boruta позволяет выявить значимые характеристики набора данных и исключить признаки, не обладающие достаточной информативностью для решения рассматриваемой задачи.
В ходе выполнения практической работы № 2 были изучены методы разведочного анализа данных, оценки значимости признаков, дискретизации непрерывных переменных и отбора информативных характеристик с использованием языка программирования R.
С помощью пакета caret выполнен графический анализ данных и построены графики распределения признаков. Пакет FSelector позволил оценить информативность характеристик набора iris. С использованием пакета arules проведено сравнение четырёх методов дискретизации: interval, frequency, cluster и fixed.
Алгоритм Boruta был применён для определения значимых признаков набора Ozone. Результаты представлены в виде графика boxplot.
Все поставленные задачи выполнены. Полученные результаты демонстрируют возможности языка R и специализированных библиотек для предварительной обработки, исследования и анализа данных.