{ "cells": [ { "cell_type": "code", "execution_count": null, "id": "d7756c66", "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "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" ] } ], "metadata": { "language_info": { "name": "python" } }, "nbformat": 4, "nbformat_minor": 5 }