{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "176dffdb-49ec-48ab-8d73-13ffb4db75b6",
   "metadata": {},
   "source": [
    "## 1. Цель задачи\n",
    "   \n",
    "Задача: Разработка модели машинного обучения для распознавания рукописных цифр от 0 до 9.\n",
    "\n",
    "Датасеты:\n",
    "\n",
    "Встроенный датасет load_digits из scikit-learn (8x8 пикселей)\n",
    "https://scikit-learn.org/stable/auto_examples/classification/plot_digits_classification.html#sphx-glr-auto-examples-classification-plot-digits-classification-py\n",
    "\n",
    "Внешний датасет MNIST (28x28 пикселей), загруженный через CSV-файл\n",
    "внешний датасет - MNIST в CSV: https://www.kaggle.com/datasets/oddrationale/mnist-in-csv?resource=download\n",
    "Цель:\n",
    "\n",
    "Реализовать классификацию цифр на обоих датасетах\n",
    "\n",
    "Сравнить эффективность модели SVM на данных разного масштаба\n",
    "\n",
    "Проанализировать характерные ошибки распознавания\n",
    "\n",
    "\n",
    "## 2. Препроцессинг\n",
    "   \n",
    "Для load_digits:\n",
    "\n",
    "from sklearn.datasets import load_digits\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "digits = load_digits()\n",
    "X = digits.data\n",
    "y = digits.target\n",
    "\n",
    "# Разделение на train/test\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n",
    "\n",
    "\n",
    "Для MNIST (CSV):\n",
    "\n",
    "import pandas as pd\n",
    "from sklearn.preprocessing import MinMaxScaler\n",
    "\n",
    "# Загрузка данных\n",
    "data = pd.read_csv('mnist_train.csv')\n",
    "X = data.drop('label', axis=1).values\n",
    "y = data['label'].values\n",
    "\n",
    "# Нормализация (приведение к диапазону [0, 1])\n",
    "scaler = MinMaxScaler()\n",
    "X = scaler.fit_transform(X)\n",
    "\n",
    "# Разделение данных\n",
    "X_train_mnist, X_test_mnist, y_train_mnist, y_test_mnist = train_test_split(\n",
    "    X, y, test_size=0.2, random_state=42)\n",
    "\n",
    "    \n",
    "Особенности препроцессинга:\n",
    "\n",
    "MNIST требует нормализации (значения пикселей 0-255 → 0-1)\n",
    "\n",
    "load_digits уже имеет предобработанные данныеДля load_digits:\n",
    "\n",
    "## 3. Код реализации:\n",
    "\n",
    "from sklearn.svm import SVC\n",
    "from sklearn.metrics import accuracy_score\n",
    "\n",
    "# Модель для load_digits\n",
    "model_digits = SVC(kernel='rbf', C=10)\n",
    "model_digits.fit(X_train, y_train)\n",
    "\n",
    "# Модель для MNIST\n",
    "model_mnist = SVC(kernel='rbf', C=10)\n",
    "model_mnist.fit(X_train_mnist, y_train_mnist)\n",
    "\n",
    "# Оценка качества\n",
    "acc_digits = model_digits.score(X_test, y_test)\n",
    "acc_mnist = model_mnist.score(X_test_mnist, y_test_mnist)\n",
    "\n",
    "print(f\"Точность на load_digits: {acc_digits:.4f}\")\n",
    "print(f\"Точность на MNIST: {acc_mnist:.4f}\")\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "5b1b0aa5-9c86-4931-8977-d8ab20d11384",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Точность модели: 0.967\n",
      "\n",
      "Примеры ошибок (всего 67):\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 5508 characters]",
      "text/plain": [
       "<Figure size 400x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 5240 characters]",
      "text/plain": [
       "<Figure size 400x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 5512 characters]",
      "text/plain": [
       "<Figure size 400x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 5424 characters]",
      "text/plain": [
       "<Figure size 400x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 5664 characters]",
      "text/plain": [
       "<Figure size 400x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 5536 characters]",
      "text/plain": [
       "<Figure size 400x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 5560 characters]",
      "text/plain": [
       "<Figure size 400x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 5760 characters]",
      "text/plain": [
       "<Figure size 400x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 5668 characters]",
      "text/plain": [
       "<Figure size 400x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 5592 characters]",
      "text/plain": [
       "<Figure size 400x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Матрица ошибок:\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 36756 characters]",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.svm import SVC\n",
    "from sklearn.metrics import accuracy_score, confusion_matrix, ConfusionMatrixDisplay\n",
    "\n",
    "\n",
    "# Загрузка данных\n",
    "data = pd.read_csv('mnist_test.csv')\n",
    "X = data.drop('label', axis=1).values  # Пиксели изображений\n",
    "y = data['label'].values  # Метки цифр\n",
    "\n",
    "# Разделение данных на обучающую и тестовую выборки\n",
    "X_train, X_test, y_train, y_test = train_test_split(\n",
    "    X, y, \n",
    "    test_size=0.2, \n",
    "    random_state=42\n",
    ")\n",
    "\n",
    "# Масштабирование данных (нормализация пикселей)\n",
    "X_train = X_train / 255.0\n",
    "X_test = X_test / 255.0\n",
    "\n",
    "# Создание и обучение модели SVM\n",
    "model = SVC(kernel='rbf', C=10)  # Используем радиальное ядро\n",
    "model.fit(X_train, y_train)\n",
    "\n",
    "# Предсказание и оценка точности\n",
    "y_pred = model.predict(X_test)\n",
    "accuracy = accuracy_score(y_test, y_pred)\n",
    "print(f'Точность модели: {accuracy:.3f}')\n",
    "\n",
    "# Визуализация ошибок\n",
    "errors = np.where(y_pred != y_test)[0]\n",
    "\n",
    "print(f'\\nПримеры ошибок (всего {len(errors)}):')\n",
    "for i in errors[:10]:  # Показываем первые 10 ошибок\n",
    "    plt.figure(figsize=(4, 4))\n",
    "    plt.imshow(X_test[i].reshape(28, 28), cmap='gray')\n",
    "    plt.title(f'True: {y_test[i]}, Pred: {y_pred[i]}')\n",
    "    plt.axis('off')\n",
    "    plt.show()\n",
    "\n",
    "# Построение матрицы ошибок\n",
    "print('\\nМатрица ошибок:')\n",
    "cm = confusion_matrix(y_test, y_pred)\n",
    "disp = ConfusionMatrixDisplay(confusion_matrix=cm)\n",
    "disp.plot(cmap='Blues')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c0545b3-e4f1-4a16-84b8-137e93c43228",
   "metadata": {},
   "source": [
    "## 4. Результаты\n",
    "Метрики:\n",
    "\n",
    "Датасет\t      Размер изображения\t    Точность\n",
    "load_digits\t  8x8 пикселей\t            0.9889\n",
    "MNIST\t      28x28 пикселей\t        0.9671\n",
    "\n",
    "## 5. Интерпретация результатов\n",
    "Ключевые наблюдения:\n",
    "\n",
    "Модель показывает высокую точность на обоих датасетах (>96%)\n",
    "\n",
    "Наибольшие трудности возникают с цифрами:\n",
    "\n",
    "4 ↔ 9\n",
    "\n",
    "5 ↔ 6\n",
    "\n",
    "3 ↔ 8\n",
    "\n",
    "Основные причины ошибок:\n",
    "\n",
    "Схожесть начертания цифр\n",
    "\n",
    "Разный стиль написания (у некоторых людей цифры выглядят нетипично)\n",
    "\n",
    "Шум в данных (нечеткие или поврежденные изображения)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
