В данной лабораторной работе рассматриваются методы классификации и анализа данных в языке R.
В работе используются:
KNN;SVM;PCA.Для выполнения заданий используется встроенный набор данных
iris.
Этот набор содержит информацию о цветках ириса: длину и ширину
чашелистика, длину и ширину лепестка, а также вид цветка.
Перед запуском отчета пакеты нужно один раз установить в консоли RStudio:
# Этот блок не выполняется при Knit, потому что стоит eval=FALSE.
# Команды ниже нужно выполнить один раз вручную в консоли RStudio.
install.packages("class")
install.packages("gmodels")
install.packages("caret")
install.packages("e1071")
install.packages("vegan")
Выполнить классификацию k-ближайших соседей с использованием функции
knn() из пакета class на наборе данных
iris.
Необходимо:
CrossTable() из пакета
gmodels;# Подключаем пакет class.
# В нем находится функция knn(), которая выполняет классификацию
# методом k-ближайших соседей.
library(class)
# Подключаем пакет gmodels.
# Он нужен для функции CrossTable(), которая строит перекрестную таблицу
# реальных и предсказанных классов.
library(gmodels)
# Подключаем пакет caret.
# Он нужен для функции confusionMatrix(),
# которая строит матрицу ошибок и считает метрики качества.
library(caret)
# Загружаем встроенный набор данных iris.
# Обычно он уже доступен в R, но data(iris) явно подгружает его.
data(iris)
# Смотрим структуру набора данных.
# str() показывает типы столбцов и общее устройство таблицы.
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 ...
# Выводим краткую статистику по каждому столбцу.
# Для числовых признаков показываются минимум, максимум, среднее, медиана и квартили.
# Для Species показывается количество объектов каждого класса.
summary(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100
## 1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300
## Median :5.800 Median :3.000 Median :4.350 Median :1.300
## Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199
## 3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
## Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500
## Species
## setosa :50
## versicolor:50
## virginica :50
##
##
##
В наборе iris содержится 150 объектов.
Первые четыре столбца являются числовыми признаками, а столбец
Species содержит класс цветка.
Метод KNN работает на основе расстояний между
объектами.
Если признаки находятся в разных масштабах, то признаки с большим
диапазоном значений могут сильнее влиять на результат.
Поэтому перед применением KNN данные нормализуются.
# Создаем функцию нормализации.
# Эта функция переводит значения признака в диапазон от 0 до 1.
#
# min(x) — минимальное значение признака.
# max(x) — максимальное значение признака.
# x - min(x) — сдвигает значения так, чтобы минимум стал равен 0.
# max(x) - min(x) — диапазон значений признака.
# Деление на диапазон приводит значения к масштабу от 0 до 1.
normalize <- function(x) {
(x - min(x)) / (max(x) - min(x))
}
# Берем только первые четыре столбца iris.
# Это числовые признаки: Sepal.Length, Sepal.Width, Petal.Length, Petal.Width.
# Столбец Species не нормализуем, потому что это не число, а класс.
iris_numeric <- iris[, 1:4]
# lapply() применяет функцию normalize к каждому числовому столбцу.
# as.data.frame() превращает результат обратно в таблицу.
iris_norm <- as.data.frame(
lapply(iris_numeric, normalize)
)
# Выводим первые строки нормализованных данных.
head(iris_norm)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## 1 0.22222222 0.6250000 0.06779661 0.04166667
## 2 0.16666667 0.4166667 0.06779661 0.04166667
## 3 0.11111111 0.5000000 0.05084746 0.04166667
## 4 0.08333333 0.4583333 0.08474576 0.04166667
## 5 0.19444444 0.6666667 0.06779661 0.04166667
## 6 0.30555556 0.7916667 0.11864407 0.12500000
# Проверим нормализацию на примере Sepal.Length.
# До нормализации значения были в исходном диапазоне.
min(iris$Sepal.Length)
## [1] 4.3
max(iris$Sepal.Length)
## [1] 7.9
# После нормализации минимум должен быть 0, максимум должен быть 1.
min(iris_norm$Sepal.Length)
## [1] 0
max(iris_norm$Sepal.Length)
## [1] 1
# Фиксируем генератор случайных чисел.
# Это нужно, чтобы при каждом запуске отчета выборка делилась одинаково.
set.seed(123)
# Создаем случайные индексы строк для обучающей выборки.
# nrow(iris_norm) — количество строк в таблице.
# 0.7 * nrow(iris_norm) — 70% всех строк.
# sample() случайно выбирает номера строк.
train_index <- sample(
1:nrow(iris_norm),
size = 0.7 * nrow(iris_norm)
)
# По выбранным индексам формируем обучающую выборку.
# Она будет использоваться алгоритмом KNN как известные примеры.
train_data <- iris_norm[train_index, ]
# Все строки, которые не попали в train_index, попадут в тестовую выборку.
# Минус перед train_index означает "взять все строки, кроме этих".
test_data <- iris_norm[-train_index, ]
# Отдельно сохраняем правильные классы для обучающей выборки.
# Они нужны функции knn(), чтобы знать, к какому классу относится каждый объект.
train_labels <- iris$Species[train_index]
# Отдельно сохраняем правильные классы для тестовой выборки.
# Потом мы сравним их с предсказаниями модели.
test_labels <- iris$Species[-train_index]
# Выводим размеры обучающей и тестовой выборок.
nrow(train_data)
## [1] 105
nrow(test_data)
## [1] 45
# Выбираем количество соседей k.
# Часто для простого примера берут корень из размера обучающей выборки.
# round() округляет результат до целого числа.
k_value <- round(sqrt(nrow(train_data)))
k_value
## [1] 10
# Выполняем классификацию методом KNN.
#
# train = train_data — обучающие данные.
# test = test_data — объекты, для которых нужно предсказать класс.
# cl = train_labels — правильные классы обучающей выборки.
# k = k_value — количество ближайших соседей.
#
# Результат knn_result — предсказанные классы для объектов тестовой выборки.
knn_result <- knn(
train = train_data,
test = test_data,
cl = train_labels,
k = k_value
)
# Выводим предсказанные классы.
knn_result
## [1] setosa setosa setosa setosa setosa setosa
## [7] setosa setosa setosa setosa setosa setosa
## [13] setosa setosa versicolor versicolor versicolor versicolor
## [19] versicolor versicolor versicolor versicolor versicolor versicolor
## [25] versicolor versicolor versicolor virginica versicolor versicolor
## [31] versicolor versicolor virginica virginica virginica virginica
## [37] virginica virginica virginica virginica virginica versicolor
## [43] virginica virginica virginica
## Levels: setosa versicolor virginica
# CrossTable() строит таблицу сравнения:
# x = test_labels — реальные классы;
# y = knn_result — предсказанные классы.
#
# В идеальном случае все значения должны находиться на главной диагонали.
# Значения вне диагонали показывают ошибки классификации.
#
# prop.chisq = FALSE отключает лишнюю статистику хи-квадрат,
# потому что в этом задании она не требуется.
CrossTable(
x = test_labels,
y = knn_result,
prop.chisq = FALSE
)
##
##
## Cell Contents
## |-------------------------|
## | N |
## | N / Row Total |
## | N / Col Total |
## | N / Table Total |
## |-------------------------|
##
##
## Total Observations in Table: 45
##
##
## | knn_result
## test_labels | setosa | versicolor | virginica | Row Total |
## -------------|------------|------------|------------|------------|
## setosa | 14 | 0 | 0 | 14 |
## | 1.000 | 0.000 | 0.000 | 0.311 |
## | 1.000 | 0.000 | 0.000 | |
## | 0.311 | 0.000 | 0.000 | |
## -------------|------------|------------|------------|------------|
## versicolor | 0 | 17 | 1 | 18 |
## | 0.000 | 0.944 | 0.056 | 0.400 |
## | 0.000 | 0.944 | 0.077 | |
## | 0.000 | 0.378 | 0.022 | |
## -------------|------------|------------|------------|------------|
## virginica | 0 | 1 | 12 | 13 |
## | 0.000 | 0.077 | 0.923 | 0.289 |
## | 0.000 | 0.056 | 0.923 | |
## | 0.000 | 0.022 | 0.267 | |
## -------------|------------|------------|------------|------------|
## Column Total | 14 | 18 | 13 | 45 |
## | 0.311 | 0.400 | 0.289 | |
## -------------|------------|------------|------------|------------|
##
##
# confusionMatrix() строит матрицу ошибок.
# Первый аргумент — предсказанные классы.
# Второй аргумент — реальные классы.
#
# Матрица ошибок показывает, сколько объектов каждого класса
# было классифицировано правильно и неправильно.
knn_matrix <- confusionMatrix(
knn_result,
test_labels
)
knn_matrix
## Confusion Matrix and Statistics
##
## Reference
## Prediction setosa versicolor virginica
## setosa 14 0 0
## versicolor 0 17 1
## virginica 0 1 12
##
## Overall Statistics
##
## Accuracy : 0.9556
## 95% CI : (0.8485, 0.9946)
## No Information Rate : 0.4
## P-Value [Acc > NIR] : 2.842e-15
##
## Kappa : 0.9326
##
## Mcnemar's Test P-Value : NA
##
## Statistics by Class:
##
## Class: setosa Class: versicolor Class: virginica
## Sensitivity 1.0000 0.9444 0.9231
## Specificity 1.0000 0.9630 0.9688
## Pos Pred Value 1.0000 0.9444 0.9231
## Neg Pred Value 1.0000 0.9630 0.9688
## Prevalence 0.3111 0.4000 0.2889
## Detection Rate 0.3111 0.3778 0.2667
## Detection Prevalence 0.3111 0.4000 0.2889
## Balanced Accuracy 1.0000 0.9537 0.9459
# В матрице ошибок главная диагональ содержит правильные ответы.
# Например, если объект был setosa и предсказан как setosa,
# он попадает на главную диагональ.
diag_values <- diag(knn_matrix$table)
# Выводим количество правильно классифицированных объектов по каждому классу.
diag_values
## setosa versicolor virginica
## 14 17 12
# colSums(knn_matrix$table) считает общее количество объектов каждого реального класса.
# Делим количество правильных ответов на общее количество объектов класса.
# Получаем качество прогноза отдельно по каждому классу.
diag_quality <- diag(knn_matrix$table) / colSums(knn_matrix$table)
# Умножаем на 100, чтобы получить проценты.
diag_quality_percent <- round(diag_quality * 100, 2)
diag_quality_percent
## setosa versicolor virginica
## 100.00 94.44 92.31
# Общая точность модели хранится в knn_matrix$overall["Accuracy"].
# Она показывает долю всех правильно классифицированных объектов.
knn_accuracy <- knn_matrix$overall["Accuracy"]
knn_accuracy
## Accuracy
## 0.9555556
В задании была выполнена классификация методом k-ближайших соседей.
Сначала данные были нормализованы, потому что KNN
использует расстояния между объектами. После этого набор данных был
разделен на обучающую и тестовую выборки в соотношении 70% и 30%.
С помощью функции knn() были получены предсказания для
тестовой выборки. Для оценки качества использовались
CrossTable() и confusionMatrix().
Диагональная оценка качества показала, сколько объектов каждого
класса было классифицировано правильно. В целом метод KNN
хорошо справился с классификацией набора данных iris.
Рассмотреть пример реализации метода опорных векторов с
использованием функции svm() из пакета
e1071.
Необходимо:
cross = 10).# Подключаем пакет e1071.
# Он содержит функцию svm(), которая реализует метод опорных векторов.
library(e1071)
# Пакет caret уже использовался выше.
# Здесь он снова нужен для confusionMatrix().
library(caret)
# Фиксируем случайность для воспроизводимости результата.
set.seed(42)
# Формируем случайные индексы для обучающей выборки.
# Используем 70% данных для обучения и 30% для тестирования.
svm_index <- sample(
1:nrow(iris),
size = 0.7 * nrow(iris)
)
# Создаем обучающую выборку.
train_svm <- iris[svm_index, ]
# Создаем тестовую выборку.
test_svm <- iris[-svm_index, ]
# Проверяем размеры выборок.
nrow(train_svm)
## [1] 105
nrow(test_svm)
## [1] 45
# Создаем SVM-модель.
#
# Species ~ . означает:
# Species — целевая переменная,
# точка означает, что все остальные столбцы используются как признаки.
#
# data = train_svm — модель обучается на обучающей выборке.
# kernel = "linear" — используется линейное ядро.
# Это значит, что модель строит линейную разделяющую границу.
#
# scale = TRUE — признаки автоматически масштабируются.
# Это полезно, потому что SVM чувствителен к масштабу признаков.
svm_model <- svm(
Species ~ .,
data = train_svm,
kernel = "linear",
scale = TRUE
)
# Выводим краткую информацию о модели.
svm_model
##
## Call:
## svm(formula = Species ~ ., data = train_svm, kernel = "linear", scale = TRUE)
##
##
## Parameters:
## SVM-Type: C-classification
## SVM-Kernel: linear
## cost: 1
##
## Number of Support Vectors: 25
# nSV показывает количество опорных векторов по каждому классу.
# sum() считает общее количество опорных векторов.
#
# Опорные векторы — это важные точки,
# которые находятся ближе всего к границе между классами.
sum(svm_model$nSV)
## [1] 25
# Строим график SVM-модели.
# Для визуализации выбираем два признака:
# Petal.Length и Petal.Width.
#
# На графике видно, как модель делит пространство признаков
# на области разных классов.
plot(
svm_model,
data = train_svm,
formula = Petal.Width ~ Petal.Length,
main = "SVM: линейный классификатор"
)
# predict() применяет обученную модель к тестовой выборке.
# В результате получаем предсказанный вид ириса для каждой строки test_svm.
svm_prediction <- predict(
svm_model,
test_svm
)
svm_prediction
## 7 11 12 19 23 25 28
## setosa setosa setosa setosa setosa setosa setosa
## 31 37 39 45 46 51 52
## setosa setosa setosa setosa setosa versicolor versicolor
## 56 59 62 63 66 67 70
## versicolor versicolor versicolor versicolor versicolor versicolor versicolor
## 75 78 79 82 91 95 101
## versicolor virginica versicolor versicolor versicolor versicolor virginica
## 102 106 108 112 113 116 117
## virginica virginica virginica virginica virginica virginica virginica
## 119 125 127 133 134 137 141
## virginica virginica virginica virginica versicolor virginica virginica
## 143 147 148
## virginica virginica virginica
## Levels: setosa versicolor virginica
# Строим матрицу ошибок для SVM.
# Сравниваем предсказания модели с реальными классами.
svm_matrix <- confusionMatrix(
svm_prediction,
test_svm$Species
)
svm_matrix
## Confusion Matrix and Statistics
##
## Reference
## Prediction setosa versicolor virginica
## setosa 12 0 0
## versicolor 0 14 1
## virginica 0 1 17
##
## Overall Statistics
##
## Accuracy : 0.9556
## 95% CI : (0.8485, 0.9946)
## No Information Rate : 0.4
## P-Value [Acc > NIR] : 2.842e-15
##
## Kappa : 0.9324
##
## Mcnemar's Test P-Value : NA
##
## Statistics by Class:
##
## Class: setosa Class: versicolor Class: virginica
## Sensitivity 1.0000 0.9333 0.9444
## Specificity 1.0000 0.9667 0.9630
## Pos Pred Value 1.0000 0.9333 0.9444
## Neg Pred Value 1.0000 0.9667 0.9630
## Prevalence 0.2667 0.3333 0.4000
## Detection Rate 0.2667 0.3111 0.3778
## Detection Prevalence 0.2667 0.3333 0.4000
## Balanced Accuracy 1.0000 0.9500 0.9537
# Выводим общую точность SVM-модели.
svm_accuracy <- svm_matrix$overall["Accuracy"]
svm_accuracy
## Accuracy
## 0.9555556
# Выполняем кросс-валидацию.
#
# cross = 10 означает, что обучающая выборка делится на 10 частей.
# Модель обучается на 9 частях и проверяется на оставшейся части.
# Это повторяется 10 раз.
#
# Такой подход дает более надежную оценку качества модели,
# чем одно случайное разбиение.
svm_cross <- svm(
Species ~ .,
data = train_svm,
kernel = "linear",
scale = TRUE,
cross = 10
)
# accuracies содержит точность для каждого из 10 разбиений.
svm_cross$accuracies
## [1] 100.00000 90.90909 90.00000 100.00000 100.00000 90.90909 100.00000
## [8] 100.00000 90.00000 90.90909
# Считаем среднюю точность по всем 10 разбиениям.
mean_cross_accuracy <- mean(svm_cross$accuracies)
mean_cross_accuracy
## [1] 95.27273
# tot.acc — итоговая точность кросс-валидации,
# которую возвращает сама функция svm().
svm_cross$tot.acc
## [1] 95.2381
В задании был рассмотрен метод опорных векторов.
С помощью функции svm() была построена модель линейной
классификации. Для обучения использовалась обучающая выборка, а качество
проверялось на тестовой выборке.
Матрица ошибок показала, что SVM хорошо классифицирует объекты из
набора iris.
Также была выполнена перекрестная проверка с параметром
cross = 10. Она позволяет оценить качество модели более
надежно, потому что модель проверяется на разных частях данных.
Выполнить расчет главных компонент с использованием пакета
vegan и функции rda().
Необходимо:
# Подключаем пакет vegan.
# В нем находится функция rda().
# В данном задании она используется для расчета PCA.
library(vegan)
# Для PCA берем только числовые признаки.
# Столбец Species не используется, потому что он является категориальным классом.
iris_num <- iris[, 1:4]
# Выводим первые строки числовых данных.
head(iris_num)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## 1 5.1 3.5 1.4 0.2
## 2 4.9 3.0 1.4 0.2
## 3 4.7 3.2 1.3 0.2
## 4 4.6 3.1 1.5 0.2
## 5 5.0 3.6 1.4 0.2
## 6 5.4 3.9 1.7 0.4
# Смотрим описательную статистику числовых признаков.
summary(iris_num)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100
## 1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300
## Median :5.800 Median :3.000 Median :4.350 Median :1.300
## Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199
## 3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
## Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500
# Считаем корреляцию между признаками.
# Корреляция показывает, насколько признаки связаны друг с другом.
#
# Значения, близкие к 1, означают сильную положительную связь.
# Значения, близкие к -1, означают сильную отрицательную связь.
# Значения около 0 означают слабую связь.
cor(iris_num)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## Sepal.Length 1.0000000 -0.1175698 0.8717538 0.8179411
## Sepal.Width -0.1175698 1.0000000 -0.4284401 -0.3661259
## Petal.Length 0.8717538 -0.4284401 1.0000000 0.9628654
## Petal.Width 0.8179411 -0.3661259 0.9628654 1.0000000
# rda() из пакета vegan может выполнять PCA.
#
# scale = TRUE означает, что признаки будут масштабированы.
# Это важно, потому что признаки имеют разные диапазоны значений.
#
# PCA создает новые переменные — главные компоненты.
# Они являются комбинациями исходных признаков.
pca_result <- rda(
iris_num,
scale = TRUE
)
pca_result
##
## Call: rda(X = iris_num, scale = TRUE)
##
## Inertia Rank
## Total 4
## Unconstrained 4 4
##
## Inertia is correlations
##
## Eigenvalues for unconstrained axes:
## PC1 PC2 PC3 PC4
## 2.9185 0.9140 0.1468 0.0207
# summary() показывает подробную информацию о PCA:
# собственные значения,
# долю объясняемой дисперсии,
# вклад главных компонент.
summary(pca_result)
##
## Call:
## rda(X = iris_num, scale = TRUE)
##
## Partitioning of correlations:
## Inertia Proportion
## Total 4 1
## Unconstrained 4 1
##
## Eigenvalues, and their contribution to the correlations
##
## Importance of components:
## PC1 PC2 PC3 PC4
## Eigenvalue 2.9185 0.9140 0.14676 0.020715
## Proportion Explained 0.7296 0.2285 0.03669 0.005179
## Cumulative Proportion 0.7296 0.9581 0.99482 1.000000
# eigenvals() возвращает собственные значения главных компонент.
# Собственные значения показывают, сколько информации содержит каждая компонента.
#
# as.numeric() нужен, чтобы превратить результат eigenvals()
# в обычный числовой вектор. Без этого barplot() может выдать ошибку.
eigen_values <- as.numeric(eigenvals(pca_result))
# Считаем долю дисперсии каждой компоненты в процентах.
variance_percent <- eigen_values / sum(eigen_values) * 100
# Считаем накопленную долю дисперсии.
# Она показывает, сколько информации объясняют первые компоненты вместе.
cumulative_percent <- cumsum(variance_percent)
# Собираем результаты в таблицу.
variance_table <- data.frame(
component = paste0("PC", 1:length(eigen_values)),
eigenvalue = round(eigen_values, 3),
variance_percent = round(variance_percent, 2),
cumulative_percent = round(cumulative_percent, 2)
)
variance_table
## component eigenvalue variance_percent cumulative_percent
## 1 PC1 2.918 72.96 72.96
## 2 PC2 0.914 22.85 95.81
## 3 PC3 0.147 3.67 99.48
## 4 PC4 0.021 0.52 100.00
# Строим столбчатый график.
# Он показывает, какую долю информации объясняет каждая главная компонента.
#
# Обычно первые компоненты объясняют большую часть информации,
# а следующие компоненты дают все меньше нового.
barplot(
height = variance_percent,
names.arg = paste0("PC", 1:length(variance_percent)),
main = "Доля объясняемой дисперсии",
xlab = "Главная компонента",
ylab = "Дисперсия, %",
ylim = c(0, 100)
)
# Строим ординационную диаграмму.
# На ней объекты располагаются в пространстве главных компонент.
#
# Близко расположенные точки похожи друг на друга.
# Далеко расположенные точки отличаются сильнее.
plot(
pca_result,
scaling = 2,
main = "Ординационная диаграмма PCA"
)
# Получаем координаты объектов на главных компонентах.
# display = "sites" означает, что нужны координаты наблюдений.
# scaling = 2 используется для удобного отображения на PCA-графике.
pca_scores <- scores(
pca_result,
display = "sites",
scaling = 2
)
# Превращаем виды ириса в числовые значения для цветов.
# setosa, versicolor и virginica будут окрашены разными цветами.
species_colors <- as.numeric(iris$Species)
# Строим график объектов по первым двум главным компонентам.
# PC1 — первая главная компонента.
# PC2 — вторая главная компонента.
plot(
pca_scores[, 1],
pca_scores[, 2],
col = species_colors,
pch = 19,
main = "PCA: расположение объектов по главным компонентам",
xlab = "PC1",
ylab = "PC2"
)
# Добавляем легенду, чтобы было понятно,
# какой цвет соответствует какому виду ириса.
legend(
"topright",
legend = levels(iris$Species),
col = 1:3,
pch = 19
)
В задании был выполнен расчет главных компонент с помощью функции
rda() из пакета vegan.
Для анализа использовались только числовые признаки набора
iris. Столбец Species не использовался при
расчете PCA, потому что он является категориальной переменной.
Главные компоненты позволяют уменьшить размерность данных. Вместо четырех исходных признаков можно рассматривать первые две главные компоненты, которые сохраняют большую часть информации.
По ординационной диаграмме видно, что вид setosa хорошо
отделяется от остальных видов. Виды versicolor и
virginica расположены ближе друг к другу, поэтому они могут
частично пересекаться.
Метод PCA полезен для визуализации многомерных данных и понимания структуры признаков.
В лабораторной работе были выполнены задания по классификации и анализу данных в R.
В задании 2 был использован метод k-ближайших соседей. Данные были
нормализованы, разделены на обучающую и тестовую выборки, после чего
была построена модель классификации. Качество модели было оценено с
помощью CrossTable(), матрицы ошибок и диагональной оценки
качества прогноза.
В задании 3 был рассмотрен метод опорных векторов. С помощью функции
svm() был построен линейный классификатор. Также была
выполнена перекрестная проверка с делением выборки на 10 частей.
В задании 4 был выполнен расчет главных компонент методом PCA с
использованием функции rda() из пакета vegan.
Были построены график объясняемой дисперсии и ординационная
диаграмма.
В результате работы были получены практические навыки классификации, оценки качества моделей, кросс-валидации и визуализации многомерных данных.