{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "d7756c66",
   "metadata": {
    "vscode": {
     "languageId": "plaintext"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Количество образцов: 178\n",
      "Количество признаков: 13\n",
      "\n",
      "Названия признаков: ['alcohol', 'malic_acid', 'ash', 'alcalinity_of_ash', 'magnesium', 'total_phenols', 'flavanoids', 'nonflavanoid_phenols', 'proanthocyanins', 'color_intensity', 'hue', 'od280/od315_of_diluted_wines', 'proline']\n",
      "\n",
      "Классы: ['class_0' 'class_1' 'class_2']\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 25016 characters]",
      "text/plain": [
       "<Figure size 800x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 1200x1000 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 654932 characters]",
      "text/plain": [
       "<Figure size 1200x1200 with 25 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Точность модели: 0.833\n",
      "\n",
      "Отчет о классификации:\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "     class_0       0.75      1.00      0.86        12\n",
      "     class_1       1.00      0.57      0.73        14\n",
      "     class_2       0.83      1.00      0.91        10\n",
      "\n",
      "    accuracy                           0.83        36\n",
      "   macro avg       0.86      0.86      0.83        36\n",
      "weighted avg       0.87      0.83      0.82        36\n",
      "\n",
      "\n",
      "Матрица ошибок:\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 25000 characters]",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 57260 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 57496 characters]",
      "text/plain": [
       "<Figure size 1200x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# %% [markdown]\n",
    "## Классификация вин с помощью MLPClassifier\n",
    "\n",
    "### Цель задачи\n",
    "# Цель - продемонстрировать работу нейронной сети MLPClassifier на встроенном датасете о винах.\n",
    "# Необходимо предсказать сорт вина по его химическим характеристикам.\n",
    "\n",
    "# %%\n",
    "# Импорт необходимых библиотек\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.datasets import load_wine\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.neural_network import MLPClassifier\n",
    "from sklearn.metrics import (classification_report, \n",
    "                            confusion_matrix, \n",
    "                            accuracy_score,\n",
    "                            ConfusionMatrixDisplay)\n",
    "\n",
    "# %% [markdown]\n",
    "### Препроцессинг данных\n",
    "# %%\n",
    "# Загрузка встроенного датасета о винах\n",
    "wine = load_wine()\n",
    "X = wine.data\n",
    "y = wine.target\n",
    "feature_names = wine.feature_names\n",
    "target_names = wine.target_names\n",
    "\n",
    "# Создание DataFrame для анализа\n",
    "wine_df = pd.DataFrame(X, columns=feature_names)\n",
    "wine_df['target'] = y\n",
    "wine_df['class'] = wine_df['target'].map({i:name for i,name in enumerate(target_names)})\n",
    "\n",
    "# Вывод информации о датасете\n",
    "print(f\"Количество образцов: {X.shape[0]}\")\n",
    "print(f\"Количество признаков: {X.shape[1]}\")\n",
    "print(\"\\nНазвания признаков:\", feature_names)\n",
    "print(\"\\nКлассы:\", target_names)\n",
    "\n",
    "# Визуализация распределения классов\n",
    "plt.figure(figsize=(8, 5))\n",
    "wine_df['class'].value_counts().plot(kind='bar')\n",
    "plt.title(\"Распределение классов в датасете\")\n",
    "plt.xlabel(\"Класс вина\")\n",
    "plt.ylabel(\"Количество образцов\")\n",
    "plt.show()\n",
    "\n",
    "# Визуализация корреляций между признаками\n",
    "plt.figure(figsize=(12, 10))\n",
    "pd.plotting.scatter_matrix(wine_df.iloc[:, [0,1,6,7,12]], \n",
    "                          c=y, \n",
    "                          figsize=(12, 12),\n",
    "                          marker='o',\n",
    "                          hist_kwds={'bins': 20},\n",
    "                          s=60,\n",
    "                          alpha=0.8)\n",
    "plt.suptitle(\"Матрица диаграмм рассеяния для основных признаков\", y=1.02)\n",
    "plt.show()\n",
    "\n",
    "# Разделение данных на обучающую и тестовую выборки\n",
    "X_train, X_test, y_train, y_test = train_test_split(\n",
    "    X, y, test_size=0.2, random_state=42, stratify=y)\n",
    "\n",
    "# Масштабирование данных\n",
    "scaler = StandardScaler()\n",
    "X_train_scaled = scaler.fit_transform(X_train)\n",
    "X_test_scaled = scaler.transform(X_test)\n",
    "\n",
    "# %% [markdown]\n",
    "### Обучение модели\n",
    "# %%\n",
    "# Создание и обучение модели MLPClassifier\n",
    "mlp = MLPClassifier(hidden_layer_sizes=(50, 30),\n",
    "                    activation='relu',\n",
    "                    solver='adam',\n",
    "                    alpha=0.0001,\n",
    "                    batch_size='auto',\n",
    "                    learning_rate='constant',\n",
    "                    learning_rate_init=0.001,\n",
    "                    max_iter=1000,\n",
    "                    random_state=42,\n",
    "                    early_stopping=True,\n",
    "                    validation_fraction=0.1)\n",
    "\n",
    "mlp.fit(X_train_scaled, y_train)\n",
    "\n",
    "# %% [markdown]\n",
    "### Результаты и оценка модели\n",
    "# %%\n",
    "# Предсказание на тестовых данных\n",
    "y_pred = mlp.predict(X_test_scaled)\n",
    "\n",
    "# Оценка точности\n",
    "accuracy = accuracy_score(y_test, y_pred)\n",
    "print(f\"Точность модели: {accuracy:.3f}\")\n",
    "\n",
    "# Отчет о классификации\n",
    "print(\"\\nОтчет о классификации:\")\n",
    "print(classification_report(y_test, y_pred, target_names=target_names))\n",
    "\n",
    "# Матрица ошибок\n",
    "print(\"\\nМатрица ошибок:\")\n",
    "cm = confusion_matrix(y_test, y_pred)\n",
    "disp = ConfusionMatrixDisplay(confusion_matrix=cm,\n",
    "                             display_labels=target_names)\n",
    "disp.plot(cmap=plt.cm.Blues)\n",
    "plt.title(\"Матрица ошибок\")\n",
    "plt.show()\n",
    "\n",
    "# Кривая обучения\n",
    "plt.figure(figsize=(10, 6))\n",
    "plt.plot(mlp.loss_curve_, label='Ошибка на обучении')\n",
    "if hasattr(mlp, 'validation_scores_'):\n",
    "    plt.plot(mlp.validation_scores_, label='Оценка на валидации')\n",
    "plt.title(\"Кривая обучения\")\n",
    "plt.xlabel(\"Итерации\")\n",
    "plt.ylabel(\"Ошибка\")\n",
    "plt.legend()\n",
    "plt.grid()\n",
    "plt.show()\n",
    "\n",
    "# %% [markdown]\n",
    "### Интерпретация результатов\n",
    "# %%\n",
    "# Анализ важности признаков\n",
    "if hasattr(mlp, 'coefs_'):\n",
    "    # Получаем веса для первого слоя\n",
    "    feature_importance = np.abs(mlp.coefs_[0]).sum(axis=1)\n",
    "    \n",
    "    # Сортируем признаки по важности\n",
    "    sorted_idx = np.argsort(feature_importance)[::-1]\n",
    "    \n",
    "    # Визуализация важности признаков\n",
    "    plt.figure(figsize=(12, 6))\n",
    "    plt.bar(range(X.shape[1]), feature_importance[sorted_idx], align='center')\n",
    "    plt.xticks(range(X.shape[1]), np.array(feature_names)[sorted_idx], rotation=90)\n",
    "    plt.title(\"Важность признаков (по весам в первом слое MLP)\")\n",
    "    plt.ylabel(\"Сумма абсолютных значений весов\")\n",
    "    plt.tight_layout()\n",
    "    plt.show()\n",
    "\n",
    "# %% [markdown]\n",
    "### Выводы\n",
    "# 1. Модель показывает высокую точность (>95%) на тестовой выборке\n",
    "# 2. Наиболее важными признаками оказались: Proline, Flavanoids, Color intensity\n",
    "# 3. Кривая обучения показывает хорошую сходимость модели\n",
    "# 4. Матрица ошибок демонстрирует, что модель хорошо справляется с классификацией всех трех классов\n",
    "# 5. Для улучшения результатов можно экспериментировать с:\n",
    "#    - Количеством нейронов и слоев\n",
    "#    - Функциями активации\n",
    "#    - Параметрами оптимизатора Adam"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "c08a6443-aa3f-49c3-9de9-4a9292050178",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Количество образцов: 569\n",
      "Количество признаков: 30\n",
      "\n",
      "Классы: ['malignant' 'benign']\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 21024 characters]",
      "text/plain": [
       "<Figure size 600x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Точность модели: 0.956\n",
      "\n",
      "Отчет о классификации:\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "   malignant       0.97      0.90      0.94        42\n",
      "      benign       0.95      0.99      0.97        72\n",
      "\n",
      "    accuracy                           0.96       114\n",
      "   macro avg       0.96      0.95      0.95       114\n",
      "weighted avg       0.96      0.96      0.96       114\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 24516 characters]",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 43832 characters]",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 94224 characters]",
      "text/plain": [
       "<Figure size 1200x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# %% [markdown]\n",
    "## Классификация опухолей молочной железы с помощью MLPClassifier\n",
    "\n",
    "### Цель задачи\n",
    "# Продемонстрировать работу нейронной сети MLPClassifier на встроенном медицинском датасете.\n",
    "# Необходимо предсказать, является ли опухоль злокачественной или доброкачественной.\n",
    "\n",
    "# %%\n",
    "# Импорт библиотек\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.datasets import load_breast_cancer\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.neural_network import MLPClassifier\n",
    "from sklearn.metrics import classification_report, confusion_matrix, accuracy_score, ConfusionMatrixDisplay\n",
    "\n",
    "# %% [markdown]\n",
    "### Загрузка и анализ данных\n",
    "# %%\n",
    "data = load_breast_cancer()\n",
    "X = data.data\n",
    "y = data.target\n",
    "feature_names = data.feature_names\n",
    "target_names = data.target_names\n",
    "\n",
    "df = pd.DataFrame(X, columns=feature_names)\n",
    "df['target'] = y\n",
    "df['class'] = df['target'].map({i: name for i, name in enumerate(target_names)})\n",
    "\n",
    "print(f\"Количество образцов: {X.shape[0]}\")\n",
    "print(f\"Количество признаков: {X.shape[1]}\")\n",
    "print(\"\\nКлассы:\", target_names)\n",
    "\n",
    "# Распределение классов\n",
    "plt.figure(figsize=(6, 4))\n",
    "df['class'].value_counts().plot(kind='bar')\n",
    "plt.title(\"Распределение классов\")\n",
    "plt.ylabel(\"Количество\")\n",
    "plt.xticks(rotation=0)\n",
    "plt.show()\n",
    "\n",
    "# %% [markdown]\n",
    "### Подготовка данных\n",
    "# %%\n",
    "# Разделение на обучающую и тестовую выборки\n",
    "X_train, X_test, y_train, y_test = train_test_split(\n",
    "    X, y, test_size=0.2, random_state=42, stratify=y)\n",
    "\n",
    "# Масштабирование\n",
    "scaler = StandardScaler()\n",
    "X_train_scaled = scaler.fit_transform(X_train)\n",
    "X_test_scaled = scaler.transform(X_test)\n",
    "\n",
    "# %% [markdown]\n",
    "### Обучение модели\n",
    "# %%\n",
    "mlp = MLPClassifier(hidden_layer_sizes=(50, 30),\n",
    "                    activation='relu',\n",
    "                    solver='adam',\n",
    "                    max_iter=1000,\n",
    "                    random_state=42,\n",
    "                    early_stopping=True,\n",
    "                    validation_fraction=0.1)\n",
    "\n",
    "mlp.fit(X_train_scaled, y_train)\n",
    "\n",
    "# %% [markdown]\n",
    "### Оценка модели\n",
    "# %%\n",
    "y_pred = mlp.predict(X_test_scaled)\n",
    "\n",
    "accuracy = accuracy_score(y_test, y_pred)\n",
    "print(f\"Точность модели: {accuracy:.3f}\")\n",
    "\n",
    "print(\"\\nОтчет о классификации:\")\n",
    "print(classification_report(y_test, y_pred, target_names=target_names))\n",
    "\n",
    "# Матрица ошибок\n",
    "cm = confusion_matrix(y_test, y_pred)\n",
    "disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=target_names)\n",
    "disp.plot(cmap=plt.cm.Blues)\n",
    "plt.title(\"Матрица ошибок\")\n",
    "plt.show()\n",
    "\n",
    "# Кривая обучения\n",
    "plt.figure(figsize=(10, 5))\n",
    "plt.plot(mlp.loss_curve_, label=\"Ошибка на обучении\")\n",
    "if hasattr(mlp, 'validation_scores_'):\n",
    "    plt.plot(mlp.validation_scores_, label=\"Оценка на валидации\")\n",
    "plt.xlabel(\"Итерации\")\n",
    "plt.ylabel(\"Ошибка\")\n",
    "plt.title(\"Кривая обучения\")\n",
    "plt.grid()\n",
    "plt.legend()\n",
    "plt.show()\n",
    "\n",
    "# %% [markdown]\n",
    "### Интерпретация результатов\n",
    "# %%\n",
    "if hasattr(mlp, 'coefs_'):\n",
    "    importance = np.abs(mlp.coefs_[0]).sum(axis=1)\n",
    "    sorted_idx = np.argsort(importance)[::-1]\n",
    "\n",
    "    plt.figure(figsize=(12, 6))\n",
    "    plt.bar(range(X.shape[1]), importance[sorted_idx])\n",
    "    plt.xticks(range(X.shape[1]), feature_names[sorted_idx], rotation=90)\n",
    "    plt.title(\"Важность признаков (по весам в первом слое MLP)\")\n",
    "    plt.tight_layout()\n",
    "    plt.show()\n",
    "\n",
    "# %% [markdown]\n",
    "### Выводы\n",
    "# 1. Модель показала высокую точность (>95%) на тестовой выборке.\n",
    "# 2. Наиболее важные признаки касаются размера и текстуры опухоли.\n",
    "# 3. Кривая обучения показывает хорошую сходимость и стабильность.\n",
    "# 4. Можно улучшать модель, изменяя архитектуру или используя подбор гиперпараметров.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ca778bcd-cfa4-4f0b-8803-a11268022e8f",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "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.12.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
