Классификация цветков ириса с помощью машинного обучения

Набор данных по ирисам включает измерения для 150 цветков трех видов ириса: ирис щетинистый (Iris setosa), ирис виргинский (Iris virginica) и ирис разноцветный (Iris versicolor). Для каждого цветка имеются следующие признаки:

  • sepal length (длина чашелистика) в см
  • sepal width (ширина чашелистика) в см
  • petal length (длина лепестка) в см
  • petal width (ширина лепестка) в см

Задача состоит в том, чтобы построить модель, которая сможет по этим 4 параметрам предсказать вид ириса. Для ее решения я буду использовать библиотеки Scikit-learn и Pandas на языке Python. Сначала загрузим и подготовим данные:

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
col_names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'target']
iris = pd.read_csv(url, header=None, names=col_names)

X = iris.drop('target', axis=1)
y = iris['target']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

Данные загружены с UCI Machine Learning Repository. Целевая переменная (вид ириса) находится в столбце 'target'. Я разделил данные на обучающую и тестовую выборки в пропорции 80/20. Затем я отмасштабировал признаки с помощью StandardScaler, чтобы привести их к нулевому среднему и единичной дисперсии. Теперь обучим несколько классификаторов из Scikit-learn и сравним их точность:

from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

classifiers = [
    KNeighborsClassifier(),
    SVC(kernel='rbf', C=1, gamma=0.1),
    RandomForestClassifier(n_estimators=100) 
]

for clf in classifiers:
    clf.fit(X_train, y_train)
    y_pred = clf.predict(X_test)
    print(f"{clf.__class__.__name__} accuracy: {accuracy_score(y_test, y_pred):.3f}")

Вывод:

KNeighborsClassifier accuracy: 1.000
SVC accuracy: 0.967  
RandomForestClassifier accuracy: 0.967

Как видим, все три классификатора показали очень высокую точность на тестовых данных - от 96.7% у SVM и случайного леса до 100% у метода k ближайших соседей. Это говорит о том, что цветки ирисов хорошо разделяются в пространстве признаков и задача их классификации не вызывает затруднений.

Давайте построчно разберем этот код, который использует библиотеки NumPy, Matplotlib и Scikit-learn для создания и визуализации классификатора k-ближайших соседей на наборе данных Iris.

import numpy as np
from matplotlib import pyplot as plt
from sklearn import neighbors, datasets
from matplotlib.colors import ListedColormap

# Создаем цветовые отображения для 3-классовой классификации
cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF'])
cmap_bold = ListedColormap(['#FF0000', '#00FF00', '#0000FF'])

# Загружаем набор данных Iris
iris = datasets.load_iris()

# Извлекаем только первые два признака и целевые переменные
X = iris.data[:, :2]
y = iris.target

# Создаем экземпляр классификатора k-ближайших соседей с n_neighbors=1
knn = neighbors.KNeighborsClassifier(n_neighbors=1)

# Обучаем классификатор на данных X и y
knn.fit(X, y)

# Определяем минимальные и максимальные значения для первого и второго признаков с небольшим отступом
x_min, x_max = X[:, 0].min() - .1, X[:, 0].max() + .1
y_min, y_max = X[:, 1].min() - .1, X[:, 1].max() + .1

# Создаем сетку значений для первого и второго признаков
xx, yy = np.meshgrid(np.linspace(x_min, x_max, 100),
                     np.linspace(y_min, y_max, 100))

# Используем классификатор для предсказания классов для каждой точки на сетке xx и yy
Z = knn.predict(np.c_[xx.ravel(), yy.ravel()])

# Визуализируем результаты классификации
plt.figure(figsize=(8, 6))
plt.pcolormesh(xx, yy, Z, cmap=cmap_light)

# Отображаем точки данных с разными цветами для каждого класса
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_bold, edgecolor='k', s=20)

# Добавляем подписи осей и заголовок
plt.xlabel('Первый признак')
plt.ylabel('Второй признак')
plt.title('Классификация k-ближайших соседей (k=1)')

# Отображаем график
plt.show()

На графике видно, что разные виды ирисов образуют компактные, линейно разделимые облака точек. Алгоритм KNN безошибочно классифицирует цветки из тестового набора.

В заключение хочу сказать, что набор данных по ирисам - отличный выбор для первого знакомства с машинным обучением и библиотекой Scikit-learn. Он простой, наглядный, не требует сложной предобработки и дает высокое качество классификации даже на небольшом объеме данных. Рекомендую всем начинающим data scientist поэкспериментировать с этим датасетом и другими алгоритмами!