4laba/week4_scikit_learn.ipynb

179 lines
7.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "6a97f4da",
"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
}