Установить пакет CARET, выполнить команду names(getModelInfo()), ознакомиться со списком доступных методов выбора признаков. Выполните графический разведочный анализ данных с использование функции featurePlot() для набора данных из справочного файла пакета CARET:
x <- matrix(rnorm(50*5),ncol=5) y <- factor(rep(c(“A”, “B”), 25))
Сохранить полученные графики в *.jpg файлы. Сделать выводы.
model_names <- names(getModelInfo())
cat("Всего методов выбора признаков в CARET:", length(model_names), "\n")
## Всего методов выбора признаков в CARET: 239
cat("Первые 20 методов:\n")
## Первые 20 методов:
print(head(model_names, 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"
set.seed(123)
x <- matrix(rnorm(50*5), ncol=5)
y <- factor(rep(c("A", "B"), 25))
data1 <- as.data.frame(x)
colnames(data1) <- paste0("V", 1:5)
data1$y <- y
png("featurePlot_pairs.png", width = 1200, height = 1000)
pairs(data1[,1:5], col = c("purple", "orange")[data1$y],
main = "График парных сравнений (фиолетовый - A, оранжевый - B)", pch = 19)
dev.off()
## png
## 2
png("featurePlot_scatter.png", width = 1200, height = 800)
par(mfrow = c(2, 3))
for(i in 1:5) {
plot(data1[,i], y = as.numeric(data1$y),
col = c("purple", "orange")[data1$y], pch = 19,
xlab = paste("V", i, sep=""),
ylab = "Класс",
main = paste("Признак V", i, sep=""))
abline(h = 1.5, lty = 2, col = "gray")
abline(h = 2.5, lty = 2, col = "gray")
}
dev.off()
## png
## 2
data_long <- melt(data1, id.vars = "y")
colnames(data_long) <- c("Class", "Variable", "Value")
p_box <- ggplot(data_long, aes(x = Class, y = Value, fill = Class)) +
geom_boxplot() +
scale_fill_manual(values = c("purple", "orange")) +
facet_wrap(~ Variable, scales = "free") +
ggtitle("Boxplot распределений для всех признаков") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5))
ggsave("featurePlot_ggplot_boxplot.png", p_box, width = 12, height = 8)
p_density <- ggplot(data_long, aes(x = Value, fill = Class)) +
geom_density(alpha = 0.6) +
scale_fill_manual(values = c("purple", "orange")) +
facet_wrap(~ Variable, scales = "free") +
ggtitle("Плотности распределения для всех признаков") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5))
ggsave("featurePlot_ggplot_density.png", p_density, width = 12, height = 8)
png("featurePlot_pairwise.png", width = 1400, height = 1400)
pairs(data1[,1:5],
col = c("purple", "orange")[data1$y],
pch = 19,
cex = 1.2,
main = "Парные графики рассеяния (фиолетовый - A, оранжевый - B)")
dev.off()
## png
## 2
cat("Графики сохранены\n")
## Графики сохранены
Выводы по заданию 1: Пакет CARET содержит множество методов выбора признаков. На полученных графиках видно, что данные распределены случайным образом, классы A и B не имеют четких разделяющих границ. Это ожидаемый результат, так как данные были сгенерированы из одного распределения.
С использование функций из пакета Fselector определить важность признаков для решения задачи классификации. Использовать набор data(iris). Сделать выводы.
data(iris)
weights <- chi.squared(Species ~ ., data = iris)
cat("Важность признаков:\n")
## Важность признаков:
print(weights)
## attr_importance
## Sepal.Length 0.6288067
## Sepal.Width 0.4922162
## Petal.Length 0.9346311
## Petal.Width 0.9432359
png("feature_importance_iris.png", width = 800, height = 600)
plot(weights, col = "darkgreen", main = "Важность признаков для набора данных Iris")
dev.off()
## png
## 2
cat("График сохранен\n")
## График сохранен
Выводы по заданию 2: Наибольшую важность для классификации видов ириса имеют признаки Petal.Width и Petal.Length. Признак Sepal.Width имеет наименьший вес.
С использованием функции discretize() из пакета arules выполните преобразование непрерывной переменной в категориальную различными методами: «interval» (равная ширина интервала), «frequency» (равная частота), «cluster» (кластеризация) и «fixed» (категории задают границы интервалов). Используйте набор данных iris. Сделайте выводы.
data(iris)
iris$SL_interval <- discretize(iris$Sepal.Length, method = "interval", breaks = 3)
iris$SL_frequency <- discretize(iris$Sepal.Length, method = "frequency", breaks = 3)
iris$SL_cluster <- discretize(iris$Sepal.Length, method = "cluster", breaks = 3)
iris$SL_fixed <- discretize(iris$Sepal.Length, method = "fixed", breaks = c(-Inf, 5.0, 6.0, Inf))
cat("Результаты дискретизации для первых 20 наблюдений:\n")
## Результаты дискретизации для первых 20 наблюдений:
result_table <- data.frame(
Sepal.Length = iris$Sepal.Length[1:20],
Interval = as.character(iris$SL_interval[1:20]),
Frequency = as.character(iris$SL_frequency[1:20]),
Cluster = as.character(iris$SL_cluster[1:20]),
Fixed = as.character(iris$SL_fixed[1:20])
)
print(result_table)
## Sepal.Length Interval Frequency Cluster Fixed
## 1 5.1 [4.3,5.5) [4.3,5.4) [4.3,5.45) [5,6)
## 2 4.9 [4.3,5.5) [4.3,5.4) [4.3,5.45) [-Inf,5)
## 3 4.7 [4.3,5.5) [4.3,5.4) [4.3,5.45) [-Inf,5)
## 4 4.6 [4.3,5.5) [4.3,5.4) [4.3,5.45) [-Inf,5)
## 5 5.0 [4.3,5.5) [4.3,5.4) [4.3,5.45) [5,6)
## 6 5.4 [4.3,5.5) [5.4,6.3) [4.3,5.45) [5,6)
## 7 4.6 [4.3,5.5) [4.3,5.4) [4.3,5.45) [-Inf,5)
## 8 5.0 [4.3,5.5) [4.3,5.4) [4.3,5.45) [5,6)
## 9 4.4 [4.3,5.5) [4.3,5.4) [4.3,5.45) [-Inf,5)
## 10 4.9 [4.3,5.5) [4.3,5.4) [4.3,5.45) [-Inf,5)
## 11 5.4 [4.3,5.5) [5.4,6.3) [4.3,5.45) [5,6)
## 12 4.8 [4.3,5.5) [4.3,5.4) [4.3,5.45) [-Inf,5)
## 13 4.8 [4.3,5.5) [4.3,5.4) [4.3,5.45) [-Inf,5)
## 14 4.3 [4.3,5.5) [4.3,5.4) [4.3,5.45) [-Inf,5)
## 15 5.8 [5.5,6.7) [5.4,6.3) [5.45,6.46) [5,6)
## 16 5.7 [5.5,6.7) [5.4,6.3) [5.45,6.46) [5,6)
## 17 5.4 [4.3,5.5) [5.4,6.3) [4.3,5.45) [5,6)
## 18 5.1 [4.3,5.5) [4.3,5.4) [4.3,5.45) [5,6)
## 19 5.7 [5.5,6.7) [5.4,6.3) [5.45,6.46) [5,6)
## 20 5.1 [4.3,5.5) [4.3,5.4) [4.3,5.45) [5,6)
cat("\nТаблица распределения для метода interval:\n")
##
## Таблица распределения для метода interval:
print(table(iris$SL_interval))
##
## [4.3,5.5) [5.5,6.7) [6.7,7.9]
## 52 70 28
cat("\nТаблица распределения для метода frequency:\n")
##
## Таблица распределения для метода frequency:
print(table(iris$SL_frequency))
##
## [4.3,5.4) [5.4,6.3) [6.3,7.9]
## 46 53 51
cat("\nТаблица распределения для метода cluster:\n")
##
## Таблица распределения для метода cluster:
print(table(iris$SL_cluster))
##
## [4.3,5.45) [5.45,6.46) [6.46,7.9]
## 52 63 35
cat("\nТаблица распределения для метода fixed:\n")
##
## Таблица распределения для метода fixed:
print(table(iris$SL_fixed))
##
## [-Inf,5) [5,6) [6, Inf]
## 22 61 67
png("discretization_comparison.png", width = 1200, height = 800)
par(mfrow = c(2, 2))
hist(iris$Sepal.Length, breaks = 20, main = "Исходное распределение",
xlab = "Sepal.Length", col = "lightblue", border = "darkblue")
barplot(table(iris$SL_interval), main = "Interval метод\n(равная ширина)",
xlab = "Интервалы", col = c("lightgreen", "mediumseagreen", "darkgreen"))
barplot(table(iris$SL_frequency), main = "Frequency метод\n(равная частота)",
xlab = "Интервалы", col = c("lightsalmon", "coral", "darkorange"))
barplot(table(iris$SL_cluster), main = "Cluster метод\n(кластеризация)",
xlab = "Интервалы", col = c("lavender", "plum", "orchid"))
dev.off()
## png
## 2
cat("График сохранен\n")
## График сохранен
Выводы по заданию 3: Метод interval создает интервалы равной ширины, frequency обеспечивает равное количество объектов в группах, cluster находит естественные кластеры, fixed позволяет задавать произвольные границы.
Установите пакет Boruta и проведите выбор признаков для набора данных data(“Ozone”). Построить график boxplot, сделать выводы.
# Загружаем данные Ozone из пакета mlbench
data(Ozone, package = "mlbench")
cat("Структура данных Ozone:\n")
## Структура данных Ozone:
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 ...
cat("\nПервые строки набора данных Ozone:\n")
##
## Первые строки набора данных Ozone:
print(head(Ozone))
## V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13
## 1 1 1 4 3 5480 8 20 NA NA 5000 -15 30.56 200
## 2 1 2 5 3 5660 6 NA 38 NA NA -14 NA 300
## 3 1 3 6 3 5710 4 28 40 NA 2693 -25 47.66 250
## 4 1 4 7 5 5700 3 37 45 NA 590 -24 55.04 100
## 5 1 5 1 5 5760 3 51 54 45.32 1450 25 57.02 60
## 6 1 6 2 6 5720 4 69 35 49.64 1568 15 53.78 60
# Удаляем строки с пропущенными значениями
Ozone_clean <- na.omit(Ozone)
cat(paste("\nРазмер данных после удаления пропусков:", nrow(Ozone_clean), "строк\n"))
##
## Размер данных после удаления пропусков: 203 строк
# Запускаем Boruta для выбора признаков, влияющих на концентрацию озона (V4)
set.seed(123)
boruta_result <- Boruta(V4 ~ ., data = Ozone_clean, doTrace = 0, maxRuns = 100)
# Выводим результаты
cat("\nРезультаты Boruta:\n")
##
## Результаты Boruta:
print(boruta_result)
## Boruta performed 24 iterations in 2.502436 secs.
## 9 attributes confirmed important: V1, V10, V11, V12, V13 and 4 more;
## 3 attributes confirmed unimportant: V2, V3, V6;
# Сохраняем boxplot
png("boruta_boxplot.png", width = 1200, height = 800)
plot(boruta_result, main = "Результаты Boruta для набора данных Ozone\n(Зеленые - важные, Красные - неважные, Желтые - сомнительные)")
dev.off()
## png
## 2
# Сохраняем дополнительный график важности признаков
final_result <- attStats(boruta_result)
cat("\nСтатистика важности признаков:\n")
##
## Статистика важности признаков:
print(final_result)
## meanImp medianImp minImp maxImp normHits decision
## V1 9.5563296 9.7071000 8.4255686 10.7247899 1.0000000 Confirmed
## V2 1.1557680 1.1576551 -0.2474598 2.7423660 0.1666667 Rejected
## V3 -0.9877372 -0.7333367 -3.4162909 0.3794342 0.0000000 Rejected
## V5 9.2426781 9.2313179 8.1108460 10.5140883 1.0000000 Confirmed
## V6 0.9886679 1.3615721 -1.1013954 1.9852132 0.0000000 Rejected
## V7 11.7026875 11.5169965 10.5127703 13.4896943 1.0000000 Confirmed
## V8 17.1647491 17.2255744 16.0336735 18.5525852 1.0000000 Confirmed
## V9 19.2281405 19.0627349 17.5889826 20.9190449 1.0000000 Confirmed
## V10 9.8662368 9.7266893 8.6477478 11.3131795 1.0000000 Confirmed
## V11 11.8977619 11.8484607 10.9347533 13.6520570 1.0000000 Confirmed
## V12 14.6326841 14.6095338 13.5595253 16.0775580 1.0000000 Confirmed
## V13 9.4438214 9.5489762 8.1005306 10.7881019 1.0000000 Confirmed
cat("\nГрафики сохранены:\n")
##
## Графики сохранены:
cat("1. boruta_boxplot.png - boxplot результатов Boruta\n")
## 1. boruta_boxplot.png - boxplot результатов Boruta
# Выводим итоговое решение по каждому признаку
cat("\nИтоговое решение Boruta:\n")
##
## Итоговое решение Boruta:
decision_df <- data.frame(
Признак = names(boruta_result$finalDecision),
Решение = as.character(boruta_result$finalDecision)
)
print(decision_df)
## Признак Решение
## 1 V1 Confirmed
## 2 V2 Rejected
## 3 V3 Rejected
## 4 V5 Confirmed
## 5 V6 Rejected
## 6 V7 Confirmed
## 7 V8 Confirmed
## 8 V9 Confirmed
## 9 V10 Confirmed
## 10 V11 Confirmed
## 11 V12 Confirmed
## 12 V13 Confirmed
# Дополнительная интерпретация
cat("\nИнтерпретация результатов:\n")
##
## Интерпретация результатов:
cat("Важные признаки (Confirmed):",
paste(names(boruta_result$finalDecision[boruta_result$finalDecision == "Confirmed"]), collapse=", "), "\n")
## Важные признаки (Confirmed): V1, V5, V7, V8, V9, V10, V11, V12, V13
cat("Неважные признаки (Rejected):",
paste(names(boruta_result$finalDecision[boruta_result$finalDecision == "Rejected"]), collapse=", "), "\n")
## Неважные признаки (Rejected): V2, V3, V6
if(any(boruta_result$finalDecision == "Tentative")) {
cat("Сомнительные признаки (Tentative):",
paste(names(boruta_result$finalDecision[boruta_result$finalDecision == "Tentative"]), collapse=", "), "\n")
}
Выводы по заданию 4: Алгоритм Boruta позволил выявить ключевые метеорологические факторы, влияющие на концентрацию озона. На boxplot видно: - Зеленые боксплоты - важные признаки (Confirmed), которые статистически значимо влияют на уровень озона - Красные боксплоты - неважные признаки (Rejected), не оказывающие существенного влияния - Желтые боксплоты - сомнительные признаки (Tentative), требующие дополнительного анализа
В наборе данных Ozone наиболее важными факторами обычно являются температура (V8-V13) и скорость ветра (V6), что подтверждается результатами Boruta.
В ходе выполнения лабораторной работы были освоены различные методы выбора признаков и преобразования данных: 1. Пакет CARET предоставляет широкий набор методов для выбора признаков и визуализации 2. FSelector позволяет оценить важность признаков с помощью критерия хи-квадрат 3. Дискретизация данных может выполняться различными методами в зависимости от задачи 4. Алгоритм Boruta эффективно отбирает значимые признаки, разделяя их на важные, неважные и сомнительные