Установка и загрузка необходимых пакетов

if (!require("class")) install.packages("class")
if (!require("gmodels")) install.packages("gmodels")
if (!require("e1071")) install.packages("e1071")
if (!require("vegan")) install.packages("vegan")
if (!require("ggplot2")) install.packages("ggplot2")
if (!require("knitr")) install.packages("knitr")

library(class)
library(gmodels)
library(e1071)
library(vegan)
library(ggplot2)
library(knitr)

1. Обзор данных Iris

data(iris)
cat("### Первые 6 строк данных:\n")
## ### Первые 6 строк данных:
kable(head(iris))
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
5.1 3.5 1.4 0.2 setosa
4.9 3.0 1.4 0.2 setosa
4.7 3.2 1.3 0.2 setosa
4.6 3.1 1.5 0.2 setosa
5.0 3.6 1.4 0.2 setosa
5.4 3.9 1.7 0.4 setosa
cat("\n### Структура данных:\n")
## 
## ### Структура данных:
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 ...
cat("\n### Статистика по данным:\n")
## 
## ### Статистика по данным:
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  
##                 
##                 
## 

2. Классификация K-ближайших соседей

Нормализация данных

normalize <- function(x) {
  return ((x - min(x)) / (max(x) - min(x)))
}

# Применяем нормализацию ко всем числовым столбцам
iris_norm <- as.data.frame(lapply(iris[1:4], normalize))
iris_norm$Species <- iris$Species

Разделение на обучающую и тестовую выборки

set.seed(123)
ind <- sample(2, nrow(iris_norm), replace = TRUE, prob = c(0.7, 0.3))
train_data <- iris_norm[ind == 1, 1:4]
test_data <- iris_norm[ind == 2, 1:4]
train_labels <- iris_norm[ind == 1, 5]
test_labels <- iris_norm[ind == 2, 5]

cat("Размер обучающей выборки:", nrow(train_data), "\n")
## Размер обучающей выборки: 106
cat("Размер тестовой выборки:", nrow(test_data), "\n")
## Размер тестовой выборки: 44

Выполнение классификации KNN

knn_pred <- knn(train = train_data, test = test_data, cl = train_labels, k = 3)

Оценка модели

cat("### Результаты CrossTable для KNN:\n")
## ### Результаты CrossTable для KNN:
CrossTable(x = test_labels, y = knn_pred, prop.chisq = FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |           N / Row Total |
## |           N / Col Total |
## |         N / Table Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  44 
## 
##  
##              | knn_pred 
##  test_labels |     setosa | versicolor |  virginica |  Row Total | 
## -------------|------------|------------|------------|------------|
##       setosa |         15 |          0 |          0 |         15 | 
##              |      1.000 |      0.000 |      0.000 |      0.341 | 
##              |      1.000 |      0.000 |      0.000 |            | 
##              |      0.341 |      0.000 |      0.000 |            | 
## -------------|------------|------------|------------|------------|
##   versicolor |          0 |         11 |          3 |         14 | 
##              |      0.000 |      0.786 |      0.214 |      0.318 | 
##              |      0.000 |      0.846 |      0.188 |            | 
##              |      0.000 |      0.250 |      0.068 |            | 
## -------------|------------|------------|------------|------------|
##    virginica |          0 |          2 |         13 |         15 | 
##              |      0.000 |      0.133 |      0.867 |      0.341 | 
##              |      0.000 |      0.154 |      0.812 |            | 
##              |      0.000 |      0.045 |      0.295 |            | 
## -------------|------------|------------|------------|------------|
## Column Total |         15 |         13 |         16 |         44 | 
##              |      0.341 |      0.295 |      0.364 |            | 
## -------------|------------|------------|------------|------------|
## 
## 
# Матрица ошибок
conf_matrix_knn <- table(Факт = test_labels, Прогноз = knn_pred)
cat("\n### Матрица ошибок для KNN:\n")
## 
## ### Матрица ошибок для KNN:
kable(conf_matrix_knn)
setosa versicolor virginica
setosa 15 0 0
versicolor 0 11 3
virginica 0 2 13
# Точность
diagonal_accuracy_knn <- sum(diag(conf_matrix_knn)) / sum(conf_matrix_knn)
cat("\n**Диагональная точность KNN:**", round(diagonal_accuracy_knn, 4), "\n")
## 
## **Диагональная точность KNN:** 0.8864

3. Метод опорных векторов (SVM)

Подготовка данных

set.seed(123)
train_indices <- sample(1:nrow(iris), 0.7 * nrow(iris))
train_iris <- iris[train_indices, ]
test_iris <- iris[-train_indices, ]

cat("Размер обучающей выборки для SVM:", nrow(train_iris), "\n")
## Размер обучающей выборки для SVM: 105
cat("Размер тестовой выборки для SVM:", nrow(test_iris), "\n")
## Размер тестовой выборки для SVM: 45

Построение SVM модели

svm_model <- svm(Species ~ ., 
                 data = train_iris, 
                 kernel = "linear",
                 cross = 10,
                 probability = TRUE)

cat("### Информация о SVM модели:\n")
## ### Информация о SVM модели:
print(svm_model)
## 
## Call:
## svm(formula = Species ~ ., data = train_iris, kernel = "linear", 
##     cross = 10, probability = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  linear 
##        cost:  1 
## 
## Number of Support Vectors:  24

Прогнозирование и оценка

svm_pred <- predict(svm_model, test_iris)

conf_matrix_svm <- table(Факт = test_iris$Species, Прогноз = svm_pred)
cat("### Матрица ошибок для SVM:\n")
## ### Матрица ошибок для SVM:
kable(conf_matrix_svm)
setosa versicolor virginica
setosa 14 0 0
versicolor 0 17 1
virginica 0 0 13
accuracy_svm <- sum(diag(conf_matrix_svm)) / sum(conf_matrix_svm)
cat("\n**Точность SVM:**", round(accuracy_svm, 4), "\n")
## 
## **Точность SVM:** 0.9778
cat("**Средняя точность 10-кратной перекрестной проверки:**", 
    round(mean(svm_model$accuracies), 4), "\n")
## **Средняя точность 10-кратной перекрестной проверки:** 97.2727

4. Анализ главных компонент (PCA)

Выполнение PCA

pca_result <- rda(iris[, 1:4], scale = TRUE)

cat("### Сводка результатов PCA:\n")
## ### Сводка результатов PCA:
summary(pca_result)
## 
## Call:
## rda(X = iris[, 1:4], 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

Визуализация PCA

plot(pca_result, type = "n", main = "PCA ординация данных Iris")
points(pca_result, display = "sites", col = as.numeric(iris$Species), pch = 16)
text(pca_result, display = "species", col = "blue", cex = 0.8)
legend("topright", legend = levels(iris$Species), 
       col = 1:3, pch = 16, title = "Species")

Альтернативная визуализация с ggplot2

pca_scores <- scores(pca_result)$sites
pca_df <- data.frame(PC1 = pca_scores[, 1], 
                     PC2 = pca_scores[, 2], 
                     Species = iris$Species)

ggplot(pca_df, aes(x = PC1, y = PC2, color = Species)) +
  geom_point(size = 3) +
  stat_ellipse(level = 0.95) +
  labs(title = "PCA ординация данных Iris",
       x = paste("PC1 (", round(100 * summary(pca_result)$cont$importance[2,1], 1), "%)"),
       y = paste("PC2 (", round(100 * summary(pca_result)$cont$importance[2,2], 1), "%)")) +
  theme_minimal()

5. Выводы и сравнение моделей

results_comparison <- data.frame(
  Модель = c("K-ближайшие соседи", "Метод опорных векторов"),
  Точность = c(round(diagonal_accuracy_knn, 4), round(accuracy_svm, 4)),
  Перекрестная_проверка = c("Нет", "10-кратная"),
  Особенности = c("K=3, нормализация данных", "Линейное ядро")
)

cat("### Сравнительная таблица результатов:\n")
## ### Сравнительная таблица результатов:
kable(results_comparison)
Модель Точность Перекрестная_проверка Особенности
K-ближайшие соседи 0.8864 Нет K=3, нормализация данных
Метод опорных векторов 0.9778 10-кратная Линейное ядро
pca_variance <- round(100 * (summary(pca_result)$cont$importance[2,1] + 
                             summary(pca_result)$cont$importance[2,2]), 1)

cat("\n### Основные выводы:\n")
## 
## ### Основные выводы:
cat("- **K-ближайшие соседи:** точность", round(diagonal_accuracy_knn, 4), "\n")
## - **K-ближайшие соседи:** точность 0.8864
cat("- **Метод опорных векторов:** точность", round(accuracy_svm, 4), "\n")
## - **Метод опорных векторов:** точность 0.9778
cat("- **PCA анализ:** первые две компоненты объясняют", pca_variance, "% дисперсии\n")
## - **PCA анализ:** первые две компоненты объясняют 95.8 % дисперсии
cat("- **Setosa** хорошо отделяется от других видов\n")
## - **Setosa** хорошо отделяется от других видов
cat("- **Versicolor и Virginica** частично перекрываются\n")
## - **Versicolor и Virginica** частично перекрываются
cat("- Оба метода показывают высокую точность классификации\n")
## - Оба метода показывают высокую точность классификации
cat("- SVM демонстрирует немного лучшие результаты благодаря перекрестной проверке\n")
## - SVM демонстрирует немного лучшие результаты благодаря перекрестной проверке