Spec-Zone.ru › scikit-learn

Примечание

Перейти в конец, чтобы скачать полный код примера или запустить этот пример в браузере с помощью JupyterLite или Binder.

Распознавание рукописных цифр

В этом примере показано, как scikit-learn можно использовать для распознавания изображений рукописных цифр от 0 до 9.

# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause

# Standard scientific Python imports
import matplotlib.pyplot as plt

# Import datasets, classifiers and performance metrics
from sklearn import datasets, metrics, svm
from sklearn.model_selection import train_test_split

Набор данных цифр

Набор данных цифр состоит из изображений цифр размером 8x8 пикселей. Атрибут images набора данных содержит массивы 8x8 со значениями оттенков серого для каждого изображения. Мы используем эти массивы, чтобы визуализировать первые 4 изображения. Атрибут target набора данных содержит цифру, изображённую на каждом изображении; она указана в заголовке каждого из 4 графиков ниже.

Примечание: если бы мы работали с файлами изображений (например, файлами «png»), мы бы загрузили их с помощью matplotlib.pyplot.imread.

digits = datasets.load_digits()

_, axes = plt.subplots(nrows=1, ncols=4, figsize=(10, 3))
for ax, image, label in zip(axes, digits.images, digits.target):
    ax.set_axis_off()
    ax.imshow(image, cmap=plt.cm.gray_r, interpolation="nearest")
    ax.set_title("Training: %i" % label)
Training: 0, Training: 1, Training: 2, Training: 3

Классификация

Чтобы применить классификатор к этим данным, нам нужно преобразовать изображения в одномерный массив, изменив форму каждого двумерного массива значений оттенков серого с (8, 8) на (64,). В результате весь набор данных будет иметь форму (n_samples, n_features), где n_samples — количество изображений, а n_features — общее количество пикселей в каждом изображении.

Затем мы можем разделить данные на обучающую и тестовую подвыборки и обучить классификатор опорных векторов на обучающих образцах. После этого обученный классификатор можно использовать для предсказания значения цифры для образцов из тестовой подвыборки.

# flatten the images
n_samples = len(digits.images)
data = digits.images.reshape((n_samples, -1))

# Create a classifier: a support vector classifier
clf = svm.SVC(gamma=0.001)

# Split data into 50% train and 50% test subsets
X_train, X_test, y_train, y_test = train_test_split(
    data, digits.target, test_size=0.5, shuffle=False
)

# Learn the digits on the train subset
clf.fit(X_train, y_train)

# Predict the value of the digit on the test subset
predicted = clf.predict(X_test)

Ниже мы визуализируем первые 4 тестовых образца и показываем предсказанное значение цифры в заголовке.

_, axes = plt.subplots(nrows=1, ncols=4, figsize=(10, 3))
for ax, image, prediction in zip(axes, X_test, predicted):
    ax.set_axis_off()
    image = image.reshape(8, 8)
    ax.imshow(image, cmap=plt.cm.gray_r, interpolation="nearest")
    ax.set_title(f"Prediction: {prediction}")
Prediction: 8, Prediction: 8, Prediction: 4, Prediction: 9

classification_report формирует текстовый отчёт с основными метриками классификации.

print(
    f"Classification report for classifier {clf}:\n"
    f"{metrics.classification_report(y_test, predicted)}\n"
)
Classification report for classifier SVC(gamma=0.001):
              precision    recall  f1-score   support

           0       1.00      0.99      0.99        88
           1       0.99      0.97      0.98        91
           2       0.99      0.99      0.99        86
           3       0.98      0.87      0.92        91
           4       0.99      0.96      0.97        92
           5       0.95      0.97      0.96        91
           6       0.99      0.99      0.99        91
           7       0.96      0.99      0.97        89
           8       0.94      1.00      0.97        88
           9       0.93      0.98      0.95        92

    accuracy                           0.97       899
   macro avg       0.97      0.97      0.97       899
weighted avg       0.97      0.97      0.97       899

Также можно построить матрицу ошибок для истинных и предсказанных значений цифр.

disp = metrics.ConfusionMatrixDisplay.from_predictions(y_test, predicted)
disp.figure_.suptitle("Confusion Matrix")
print(f"Confusion matrix:\n{disp.confusion_matrix}")

plt.show()
Confusion Matrix
Confusion matrix:
[[87  0  0  0  1  0  0  0  0  0]
 [ 0 88  1  0  0  0  0  0  1  1]
 [ 0  0 85  1  0  0  0  0  0  0]
 [ 0  0  0 79  0  3  0  4  5  0]
 [ 0  0  0  0 88  0  0  0  0  4]
 [ 0  0  0  0  0 88  1  0  0  2]
 [ 0  1  0  0  0  0 90  0  0  0]
 [ 0  0  0  0  0  1  0 88  0  0]
 [ 0  0  0  0  0  0  0  0 88  0]
 [ 0  0  0  1  0  1  0  0  0 90]]

Если результаты оценки классификатора представлены в виде матрицы ошибок, а не в виде y_true и y_pred, всё равно можно сформировать classification_report следующим образом:

# The ground truth and predicted lists
y_true = []
y_pred = []
cm = disp.confusion_matrix

# For each cell in the confusion matrix, add the corresponding ground truths
# and predictions to the lists
for gt in range(len(cm)):
    for pred in range(len(cm)):
        y_true += [gt] * cm[gt][pred]
        y_pred += [pred] * cm[gt][pred]

print(
    "Classification report rebuilt from confusion matrix:\n"
    f"{metrics.classification_report(y_true, y_pred)}\n"
)
Classification report rebuilt from confusion matrix:
              precision    recall  f1-score   support

           0       1.00      0.99      0.99        88
           1       0.99      0.97      0.98        91
           2       0.99      0.99      0.99        86
           3       0.98      0.87      0.92        91
           4       0.99      0.96      0.97        92
           5       0.95      0.97      0.96        91
           6       0.99      0.99      0.99        91
           7       0.96      0.99      0.97        89
           8       0.94      1.00      0.97        88
           9       0.93      0.98      0.95        92

    accuracy                           0.97       899
   macro avg       0.97      0.97      0.97       899
weighted avg       0.97      0.97      0.97       899

Общее время выполнения скрипта: (0 минут 0.389 секунды)

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_digits_classification.ipynb

Download Python source code: plot_digits_classification.py

Download zipped: plot_digits_classification.zip

Связанные примеры

Агломерация признаков

Распространение меток для цифр: демонстрация производительности

Распространение меток для цифр: активное обучение

Удаление шума с изображений с помощью ядерного PCA

© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/classification/plot_digits_classification.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API