Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 89b4c578ee | |||
|
|
b805d91ae6 | ||
| 0fcd0efa60 | |||
|
|
0db842cd11 | ||
| 621b1f50d7 | |||
| fc5995f2d4 | |||
| 0a588978cd | |||
| 3c69eda7c6 | |||
|
|
f42b24151d | ||
|
|
3691f9ca37 | ||
|
|
34a85c2013 | ||
|
|
4529156634 | ||
|
|
c7b33aedfd | ||
|
|
6040221601 | ||
|
|
1c8157e520 | ||
|
|
df4751eebc | ||
|
|
13e62b0406 | ||
|
|
574c67c6c1 | ||
|
|
1143392584 | ||
|
|
47b3d624c4 | ||
|
|
d151cef7cc | ||
|
|
4656cab9ec | ||
|
|
d62e3e99b3 | ||
|
|
7f6a2db5de | ||
|
|
4013b50cdc | ||
|
|
893772e7b6 | ||
| 887495b613 | |||
| 95127d29eb | |||
| cde1133b24 | |||
| 1af29b1532 | |||
| 33222e5f86 | |||
|
|
71d153c21c | ||
|
|
089d9ebafc | ||
|
|
32331e3cd5 | ||
| 2e67d19a5b |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -12,3 +12,5 @@ ipython_config.py
|
||||
# Remove previous ipynb_checkpoints
|
||||
# git rm -r .ipynb_checkpoints/
|
||||
|
||||
aimvenv
|
||||
Static
|
||||
114
.idea/workspace.xml
generated
Normal file
114
.idea/workspace.xml
generated
Normal file
@@ -0,0 +1,114 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="1e90e204-2b42-4731-959d-143b8c797e7b" name="Changes" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/lab_9/lab9.ipynb" beforeDir="false" afterPath="$PROJECT_DIR$/lab_9/lab9.ipynb" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="FlaskConsoleOptions" custom-start-script="import sys sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS]) from flask.cli import ScriptInfo locals().update(ScriptInfo(create_app=None).load_app().make_shell_context()) print("Python %s on %s\nApp: %s [%s]\nInstance: %s" % (sys.version, sys.platform, app.import_name, app.env, app.instance_path))">
|
||||
<envs>
|
||||
<env key="FLASK_APP" value="app" />
|
||||
</envs>
|
||||
<option name="myCustomStartScript" value="import sys sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS]) from flask.cli import ScriptInfo locals().update(ScriptInfo(create_app=None).load_app().make_shell_context()) print("Python %s on %s\nApp: %s [%s]\nInstance: %s" % (sys.version, sys.platform, app.import_name, app.env, app.instance_path))" />
|
||||
<option name="myEnvs">
|
||||
<map>
|
||||
<entry key="FLASK_APP" value="app" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_BRANCH_BY_REPOSITORY">
|
||||
<map>
|
||||
<entry key="$PROJECT_DIR$" value="main" />
|
||||
</map>
|
||||
</option>
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="MarkdownSettingsMigration">
|
||||
<option name="stateVersion" value="1" />
|
||||
</component>
|
||||
<component name="ProjectId" id="2xWCKLKy9V2G8DVjAk5ogaemRw4" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">{
|
||||
"keyToString": {
|
||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"WebServerToolWindowFactoryState": "false",
|
||||
"last_opened_file_path": "D:/study/3_course/6_sem/mii",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"settings.editor.selected.configurable": "org.jetbrains.plugins.notebooks.jupyter.connections.configuration.JupyterServerConfigurable",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}</component>
|
||||
<component name="RecentsManager">
|
||||
<key name="MoveFile.RECENT_KEYS">
|
||||
<recent name="D:\study\3_course\6_sem\mii" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="1e90e204-2b42-4731-959d-143b8c797e7b" name="Changes" comment="" />
|
||||
<created>1748044377532</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1748044377532</updated>
|
||||
<workItem from="1748044380495" duration="945000" />
|
||||
<workItem from="1748050653656" duration="1173000" />
|
||||
<workItem from="1748052024629" duration="1122000" />
|
||||
<workItem from="1748053175509" duration="1592000" />
|
||||
<workItem from="1748054799103" duration="694000" />
|
||||
</task>
|
||||
<task id="LOCAL-00001" summary="lab7">
|
||||
<option name="closed" value="true" />
|
||||
<created>1748054595930</created>
|
||||
<option name="number" value="00001" />
|
||||
<option name="presentableId" value="LOCAL-00001" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1748054595930</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00002" summary="lab8">
|
||||
<option name="closed" value="true" />
|
||||
<created>1748054954060</created>
|
||||
<option name="number" value="00002" />
|
||||
<option name="presentableId" value="LOCAL-00002" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1748054954060</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="3" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
<component name="Vcs.Log.Tabs.Properties">
|
||||
<option name="TAB_STATES">
|
||||
<map>
|
||||
<entry key="MAIN">
|
||||
<value>
|
||||
<State />
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
<component name="VcsManagerConfiguration">
|
||||
<MESSAGE value="lab7" />
|
||||
<MESSAGE value="lab8" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="lab8" />
|
||||
</component>
|
||||
</project>
|
||||
487
lab4/lab4.ipynb
Normal file
487
lab4/lab4.ipynb
Normal file
@@ -0,0 +1,487 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Лабораторная работа 4"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<b> 1. Выбрать бизнес-цели для набора данных </b> <br><br>\n",
|
||||
"\n",
|
||||
"Классификация. Цель: определить, откликнется ли клиент на маркетинговую кампанию. Столбец целевой переменной - Response, 1 - откликнулся, 0 - нет. Признаки - Возраст, Уровень дохода. (Age, Income) <br>\n",
|
||||
"\n",
|
||||
"Регрессия. Цель: прогноз расходов клиента. Столбец целевой переменной: Total_Spending - общие расходы, будут считаться по всем расходам. Признаки такие же."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<b>2. Определить достижимый уровень качества модели</b><br><br>\n",
|
||||
"<b>Классификация:</b> <br>\n",
|
||||
"Оценка метрики accuracy: ориентир 70-80% (с учетом ограниченных признаков).<br>\n",
|
||||
"<b>Регрессия:</b><br>\n",
|
||||
"MSE (среднеквадратичная ошибка): минимизация, ориентир в зависимости от разброса целевой переменной.<br>\n",
|
||||
"R^2 > 0.6"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<b>3.Выбрать ориентир </b><br><br>\n",
|
||||
"<b>Классификация:</b><br>\n",
|
||||
"DummyClassifier, предсказывающий самый частый класс, даст accuracy ~50-60%.<br>\n",
|
||||
"<b>Регрессия:</b><br>\n",
|
||||
"Прогноз среднего значения целевой переменной."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 40,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"X_class_train: (1568, 2), y_class_train: (1568,)\n",
|
||||
"X_reg_train: (1568, 2), y_reg_train: (1568,)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"from sklearn.model_selection import train_test_split\n",
|
||||
"from sklearn.preprocessing import StandardScaler\n",
|
||||
"\n",
|
||||
"data = pd.read_csv(\"..//..//static//csv//marketing_campaign.csv\", sep=\"\\t\")\n",
|
||||
"data2 = pd.read_csv(\"..//..//static//csv//marketing_campaign2.csv\", sep=\"\\t\")\n",
|
||||
"\n",
|
||||
"# Преобразуем данные для классификации (дата для отклика на кампанию)\n",
|
||||
"data['Age'] = 2024 - data['Year_Birth'] \n",
|
||||
"data = data[['Age', 'Income', 'Response']] \n",
|
||||
"\n",
|
||||
"X_class = data[['Age', 'Income']]\n",
|
||||
"y_class = data['Response']\n",
|
||||
"\n",
|
||||
"# Преобразуем данные для регрессии (прогноз расходов)\n",
|
||||
"data2['Age'] = 2024 - data2['Year_Birth'] \n",
|
||||
"data2['Total_Spending'] = (data2['MntWines'] + data2['MntFruits'] + data2['MntMeatProducts'] +\n",
|
||||
" data2['MntFishProducts'] + data2['MntSweetProducts'] + data2['MntGoldProds'])\n",
|
||||
"data2 = data2[['Age', 'Income', 'Total_Spending']] \n",
|
||||
"\n",
|
||||
"# Разделение на признаки и целевую переменную для регрессии\n",
|
||||
"X_reg = data2[['Age', 'Income']]\n",
|
||||
"y_reg = data2['Total_Spending']\n",
|
||||
"\n",
|
||||
"# Масштабирование данных и преобразование обратно в DataFrame\n",
|
||||
"scaler = StandardScaler()\n",
|
||||
"X_class_scaled = pd.DataFrame(scaler.fit_transform(X_class), columns=X_class.columns)\n",
|
||||
"X_reg_scaled = pd.DataFrame(scaler.fit_transform(X_reg), columns=X_reg.columns)\n",
|
||||
"\n",
|
||||
"# Разделение на тренировочные и тестовые выборки\n",
|
||||
"X_train_class, X_test_class, y_train_class, y_test_class = train_test_split(X_class_scaled, y_class, test_size=0.3, random_state=42)\n",
|
||||
"X_train_reg, X_test_reg, y_train_reg, y_test_reg = train_test_split(X_reg_scaled, y_reg, test_size=0.3, random_state=42)\n",
|
||||
"\n",
|
||||
"# Проверим, что все выглядит правильно\n",
|
||||
"print(f\"X_class_train: {X_train_class.shape}, y_class_train: {y_train_class.shape}\")\n",
|
||||
"print(f\"X_reg_train: {X_train_reg.shape}, y_reg_train: {y_train_reg.shape}\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<b>5-6. Выбрать не менее трёх моделей и пострить конвейер </b>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 41,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Logistic Regression - Средняя точность модели: 0.8475 ± 0.0027\n",
|
||||
"Random Forest - Средняя точность модели: 0.8267 ± 0.0090\n",
|
||||
"SVM - Средняя точность модели: 0.8529 ± 0.0027\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"from sklearn.model_selection import train_test_split, cross_val_score\n",
|
||||
"from sklearn.preprocessing import StandardScaler\n",
|
||||
"from sklearn.impute import SimpleImputer\n",
|
||||
"from sklearn.linear_model import LogisticRegression\n",
|
||||
"from sklearn.ensemble import RandomForestClassifier\n",
|
||||
"from sklearn.svm import SVC\n",
|
||||
"from sklearn.pipeline import Pipeline\n",
|
||||
"\n",
|
||||
"# Удаляем строки с пропущенными значениями\n",
|
||||
"X_class_scaled = X_class_scaled.dropna()\n",
|
||||
"y_class = y_class[X_class_scaled.index]\n",
|
||||
"\n",
|
||||
"models = [\n",
|
||||
" ('Logistic Regression', LogisticRegression(max_iter=1000)),\n",
|
||||
" ('Random Forest', RandomForestClassifier(n_estimators=100)),\n",
|
||||
" ('SVM', SVC())\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"# Создаем конвейер\n",
|
||||
"imputer = SimpleImputer(strategy='mean') \n",
|
||||
"scaler = StandardScaler()\n",
|
||||
"\n",
|
||||
"for name, model in models:\n",
|
||||
" pipe = Pipeline([\n",
|
||||
" ('imputer', imputer),\n",
|
||||
" ('scaler', scaler),\n",
|
||||
" ('classifier', model)\n",
|
||||
" ])\n",
|
||||
" \n",
|
||||
" scores = cross_val_score(pipe, X_class_scaled, y_class, cv=5, scoring='accuracy')\n",
|
||||
" print(f\"{name} - Средняя точность модели: {scores.mean():.4f} ± {scores.std():.4f}\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<b>Выбрал</b><br><br>\n",
|
||||
"Imputer: Заполняет пропущенные значения средним (если они есть).<br>\n",
|
||||
"Scaler: Масштабирует данные с помощью StandardScaler.<br>\n",
|
||||
"Classifier: Используются три модели:<br>\n",
|
||||
"LogisticRegression: Логистическая регрессия.<br>\n",
|
||||
"RandomForestClassifier: Случайный лес.<br>\n",
|
||||
"SVC: Метод опорных векторов (SVM)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<b>7. Реализовать настройку гиперпараметров</b><br><br>\n",
|
||||
"\n",
|
||||
"Делаем настройку гиперпараметров"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 42,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Fitting 5 folds for each of 6 candidates, totalling 30 fits\n",
|
||||
"Logistic Regression - Лучшие гиперпараметры: {'classifier__C': 0.1, 'classifier__solver': 'lbfgs'}\n",
|
||||
"Logistic Regression - Лучшая точность: 0.8484\n",
|
||||
"--------------------------------------------------\n",
|
||||
"Fitting 5 folds for each of 9 candidates, totalling 45 fits\n",
|
||||
"Random Forest - Лучшие гиперпараметры: {'classifier__max_depth': 10, 'classifier__n_estimators': 100}\n",
|
||||
"Random Forest - Лучшая точность: 0.8506\n",
|
||||
"--------------------------------------------------\n",
|
||||
"Fitting 5 folds for each of 6 candidates, totalling 30 fits\n",
|
||||
"SVM - Лучшие гиперпараметры: {'classifier__C': 1, 'classifier__kernel': 'rbf'}\n",
|
||||
"SVM - Лучшая точность: 0.8529\n",
|
||||
"--------------------------------------------------\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from sklearn.model_selection import GridSearchCV\n",
|
||||
"\n",
|
||||
"models = [\n",
|
||||
" ('Logistic Regression', LogisticRegression(max_iter=1000), {'classifier__C': [0.1, 1, 10], 'classifier__solver': ['lbfgs', 'liblinear']}),\n",
|
||||
" ('Random Forest', RandomForestClassifier(n_estimators=100), {'classifier__n_estimators': [50, 100, 200], 'classifier__max_depth': [10, 20, None]}),\n",
|
||||
" ('SVM', SVC(), {'classifier__C': [0.1, 1, 10], 'classifier__kernel': ['linear', 'rbf']})\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"for name, model, param_grid in models:\n",
|
||||
" pipe = Pipeline([\n",
|
||||
" ('imputer', imputer),\n",
|
||||
" ('scaler', scaler),\n",
|
||||
" ('classifier', model)\n",
|
||||
" ])\n",
|
||||
" \n",
|
||||
" grid_search = GridSearchCV(pipe, param_grid, cv=5, scoring='accuracy', n_jobs=-1, verbose=1)\n",
|
||||
" grid_search.fit(X_class_scaled, y_class)\n",
|
||||
"\n",
|
||||
" print(f\"{name} - Лучшие гиперпараметры: {grid_search.best_params_}\")\n",
|
||||
" print(f\"{name} - Лучшая точность: {grid_search.best_score_:.4f}\")\n",
|
||||
" print(\"-\" * 50)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Проходим по моделям и настраиваем гиперпараметры с помощью GridSearchCV с помощью кросс-валидации. <br>\n",
|
||||
"Параметры: cv=5: 5 фолдов для кросс-валидации.<br>\n",
|
||||
"scoring='accuracy': Мы используем точность как метрику.<br>\n",
|
||||
"n_jobs=-1: Используем все доступные процессоры для ускорения вычислений.<br>\n",
|
||||
"verbose=1: Подробный вывод процесса."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<b>8. Обучить модели</b>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 43,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Fitting 5 folds for each of 6 candidates, totalling 30 fits\n",
|
||||
"Fitting 5 folds for each of 6 candidates, totalling 30 fits\n",
|
||||
"Fitting 5 folds for each of 6 candidates, totalling 30 fits\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"best_models = {} \n",
|
||||
"for name, model, param_grid in models: \n",
|
||||
" grid_search.fit(X_class_scaled, y_class)\n",
|
||||
" best_models[name] = grid_search.best_estimator_ \n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<b>9. Оценить качество моделей </b>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 44,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score\n",
|
||||
"from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score\n",
|
||||
"\n",
|
||||
"# Оценка качества классификации\n",
|
||||
"for name, model in best_models.items():\n",
|
||||
" y_pred_class = model.predict(X_class_scaled) # Предсказание для классификации\n",
|
||||
"\n",
|
||||
" \n",
|
||||
"# Оценка качества регрессии\n",
|
||||
"for name, model in best_models.items():\n",
|
||||
" y_pred_reg = model.predict(X_reg_scaled) # Предсказание для регрессии\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Вывод слишком длинный, приложу его тут <br><br>\n",
|
||||
"<b>Оценка качества для модели Logistic Regression:</b><br><br>\n",
|
||||
"Accuracy: 0.8528880866425993<br>\n",
|
||||
"Precision: 0.8181818181818182<br>\n",
|
||||
"Recall: 0.02702702702702703<br>\n",
|
||||
"F1-Score: 0.05232558139534884<br>\n",
|
||||
"ROC AUC: Не поддерживается для этой модели<br>\n",
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<b>Оценка качества для модели Random Forest:</b><br><br>\n",
|
||||
"Accuracy: 0.8528880866425993<br>\n",
|
||||
"Precision: 0.8181818181818182<br>\n",
|
||||
"Recall: 0.02702702702702703<br>\n",
|
||||
"F1-Score: 0.05232558139534884<br>\n",
|
||||
"ROC AUC: Не поддерживается для этой модели<br>\n",
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<b>Оценка качества для модели SVM:</b><br><br>\n",
|
||||
"Accuracy: 0.8528880866425993<br>\n",
|
||||
"Precision: 0.8181818181818182<br>\n",
|
||||
"Recall: 0.02702702702702703<br>\n",
|
||||
"F1-Score: 0.05232558139534884<br>\n",
|
||||
"ROC AUC: Не поддерживается для этой модели<br>\n",
|
||||
"<br>\n",
|
||||
"<br>Задача регрессии: <br>\n",
|
||||
"<b>Оценка качества для модели Logistic Regression:</b><br><br>\n",
|
||||
"MAE: 605.7982142857143<br>\n",
|
||||
"MSE: 729533.7598214286<br>\n",
|
||||
"RMSE: 854.1274845252485<br>\n",
|
||||
"R²: -1.0122722045012051<br>\n",
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<b>Оценка качества для модели Random Forest:</b><br><br>\n",
|
||||
"MAE: 605.7982142857143<br>\n",
|
||||
"MSE: 729533.7598214286<br>\n",
|
||||
"RMSE: 854.1274845252485<br>\n",
|
||||
"R²: -1.0122722045012051<br>\n",
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<b>Оценка качества для модели SVM:</b><br><br>\n",
|
||||
"MAE: 605.7982142857143<br>\n",
|
||||
"MSE: 729533.7598214286<br>\n",
|
||||
"RMSE: 854.1274845252485<br>\n",
|
||||
"R²: -1.0122722045012051<br>\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<b>Почему выбрал эти метирки:</b><br><br><b>Классификация (Отклик на предложение)</b><br>\n",
|
||||
"Целевая переменная — бинарная (0 и 1), где 1 — откликнулся, а 0 — не откликнулся. Для классификации подходящими метриками являются:\n",
|
||||
"<br><br>\n",
|
||||
"<b>Accuracy (Точность):</b><br><br>\n",
|
||||
"Это доля правильно классифицированных объектов среди всех. \n",
|
||||
"Подходит для оценки общей эффективности модели. Однако важно учитывать, что если классы несбалансированы, точность может быть обманчивой.<br><br>\n",
|
||||
"<b>Precision (Точность):</b>\n",
|
||||
"\n",
|
||||
"Это доля истинных положительных случаев среди всех предсказанных положительных случаев.\n",
|
||||
"Важна для задач, где важно минимизировать количество ложных срабатываний, например, когда модель ошибочно классифицирует клиента как откликнувшегося (True Positive).<br><br>\n",
|
||||
"<b>Recall (Полнота):</b><br><br>\n",
|
||||
"\n",
|
||||
"Это доля истинных положительных случаев среди всех истинных положительных случаев.\n",
|
||||
"Важно для задач, где важно не пропустить откликнувшихся клиентов (False Negatives).<br><br>\n",
|
||||
"<b>F1-Score:</b><br><br>\n",
|
||||
"\n",
|
||||
"Это гармоническое среднее между точностью и полнотой.\n",
|
||||
"Подходит для оценки моделей в случаях, когда важно иметь баланс между точностью и полнотой, особенно в ситуациях с несбалансированными классами.<br><br>\n",
|
||||
"<b>ROC AUC:</b><br><br>\n",
|
||||
"Площадь под кривой ROC, которая отображает способность модели различать положительные и отрицательные классы.\n",
|
||||
"Чем выше значение AUC, тем лучше модель справляется с разделением классов."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<b>Регрессия (Прогноз расходов)</b><br><br>\n",
|
||||
"Целевая переменная — это числовое значение (расходы клиента). Для задач регрессии используются другие метрики:<br><br>\n",
|
||||
"\n",
|
||||
"<b>Mean Absolute Error (MAE):</b><br><br>\n",
|
||||
"\n",
|
||||
"Это средняя абсолютная ошибка предсказания.\n",
|
||||
"Простой и интерпретируемый показатель, который описывает среднее отклонение предсказанных значений от фактических.<br><br>\n",
|
||||
"<b>Mean Squared Error (MSE):</b><br><br>\n",
|
||||
"\n",
|
||||
"Это средняя квадратичная ошибка.\n",
|
||||
"Чувствителен к большим ошибкам, так как квадратичный штраф увеличивает вес больших отклонений, что полезно, если вы хотите минимизировать большие ошибки.<br><br>\n",
|
||||
"<b>Root Mean Squared Error (RMSE):</b><br><br>\n",
|
||||
"\n",
|
||||
"Это квадратный корень из MSE.\n",
|
||||
"Подходит для задач, где важно учитывать большие ошибки, так как более чувствителен к выбросам.<br><br>\n",
|
||||
"<b>R-squared (R²):</b><br><br>\n",
|
||||
"\n",
|
||||
"Это коэффициент детерминации, который показывает, какая доля дисперсии целевой переменной объясняется моделью.\n",
|
||||
"R² может быть полезен для оценки того, насколько хорошо модель объясняет вариацию целевой переменной, но не всегда подходит, если модель имеет много выбросов или некорректно подогнана.<br>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<b>9. Оценить качество моделей</b>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 45,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Evaluating model: Logistic Regression\n",
|
||||
"Train Accuracy: 0.8501, Test Accuracy: 0.8631\n",
|
||||
"Bias: 0.0045, Variance: 0.0104\n",
|
||||
"Train Error (MSE): 732193.2283, Test Error (MSE): 723279.6414\n",
|
||||
"Bias: 0.0045, Variance: 0.0104\n",
|
||||
"Evaluating model: Random Forest\n",
|
||||
"Train Accuracy: 0.8501, Test Accuracy: 0.8631\n",
|
||||
"Bias: 0.0045, Variance: 0.0104\n",
|
||||
"Train Error (MSE): 732193.2283, Test Error (MSE): 723279.6414\n",
|
||||
"Bias: 0.0045, Variance: 0.0104\n",
|
||||
"Evaluating model: SVM\n",
|
||||
"Train Accuracy: 0.8501, Test Accuracy: 0.8631\n",
|
||||
"Bias: 0.0045, Variance: 0.0104\n",
|
||||
"Train Error (MSE): 732193.2283, Test Error (MSE): 723279.6414\n",
|
||||
"Bias: 0.0045, Variance: 0.0104\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"from sklearn.metrics import mean_squared_error, accuracy_score\n",
|
||||
"\n",
|
||||
"# Оценка смещения и дисперсии для классификации и регрессии\n",
|
||||
"def evaluate_bias_variance(model, X_train, y_train, X_test, y_test, task='classification'):\n",
|
||||
" # Прогнозы на обучающих и тестовых данных\n",
|
||||
" y_train_pred = model.predict(X_train)\n",
|
||||
" y_test_pred = model.predict(X_test)\n",
|
||||
"\n",
|
||||
" if task == 'classification':\n",
|
||||
" # Для классификации считаем точность\n",
|
||||
" train_accuracy = accuracy_score(y_train, y_train_pred)\n",
|
||||
" test_accuracy = accuracy_score(y_test, y_test_pred)\n",
|
||||
" print(f\"Train Accuracy: {train_accuracy:.4f}, Test Accuracy: {test_accuracy:.4f}\")\n",
|
||||
" elif task == 'regression':\n",
|
||||
" # Для регрессии считаем среднеквадратичную ошибку (MSE)\n",
|
||||
" train_error = mean_squared_error(y_train, y_train_pred)\n",
|
||||
" test_error = mean_squared_error(y_test, y_test_pred)\n",
|
||||
" print(f\"Train Error (MSE): {train_error:.4f}, Test Error (MSE): {test_error:.4f}\")\n",
|
||||
"\n",
|
||||
" # Для оценки смещения и дисперсии на тестовых данных\n",
|
||||
" bias = np.mean(y_test_pred - y_train_pred[:len(y_test_pred)]) # Смещение: разница между тестом и обучением\n",
|
||||
" variance = np.var(y_test_pred - y_train_pred[:len(y_test_pred)]) # Дисперсия: варьирование прогнозов\n",
|
||||
"\n",
|
||||
" print(f\"Bias: {bias:.4f}, Variance: {variance:.4f}\")\n",
|
||||
"\n",
|
||||
"# Оценим для каждой из моделей\n",
|
||||
"for name, model in best_models.items():\n",
|
||||
" print(f\"Evaluating model: {name}\")\n",
|
||||
" # Для классификации\n",
|
||||
" evaluate_bias_variance(model, X_train_class, y_train_class, X_test_class, y_test_class, task='classification') \n",
|
||||
" # Для регрессии\n",
|
||||
" evaluate_bias_variance(model, X_train_reg, y_train_reg, X_test_reg, y_test_reg, task='regression') \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "aimenv",
|
||||
"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.7"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
281
lab5/lab5.ipynb
Normal file
281
lab5/lab5.ipynb
Normal file
File diff suppressed because one or more lines are too long
5144
lab6/lab6.ipynb
Normal file
5144
lab6/lab6.ipynb
Normal file
File diff suppressed because it is too large
Load Diff
367
lab_10/lab10.ipynb
Normal file
367
lab_10/lab10.ipynb
Normal file
File diff suppressed because one or more lines are too long
472
lab_11/lab11.ipynb
Normal file
472
lab_11/lab11.ipynb
Normal file
File diff suppressed because one or more lines are too long
1952
lab_12/lab12.ipynb
Normal file
1952
lab_12/lab12.ipynb
Normal file
File diff suppressed because one or more lines are too long
387
lab_7/lab7.ipynb
Normal file
387
lab_7/lab7.ipynb
Normal file
@@ -0,0 +1,387 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Лабораторная работа №7: Разработка нечеткой логической модели для оценки отклика клиентов на маркетинговую кампанию\n",
|
||||
"\n",
|
||||
"## Исходный датасет — Marketing Campaign Dataset (Маркетинговая кампания)\n",
|
||||
"\n",
|
||||
"---\n",
|
||||
"\n",
|
||||
"## Основы нечеткой логики\n",
|
||||
"\n",
|
||||
"Нечеткая логика — это подход, расширяющий границы классической логики, позволяя моделировать ситуации, где невозможно чётко сказать «да» или «нет», «0» или «1». Вместо этого вводятся **степени принадлежности** — насколько объект соответствует определённому понятию.\n",
|
||||
"\n",
|
||||
"Например, такие выражения, как **\"высокий доход\"**, **\"недавняя покупка\"** или **\"часто покупает вино\"** — субъективны. С помощью нечеткой логики можно задать формальные правила, отражающие такие понятия через **функции принадлежности**.\n",
|
||||
"\n",
|
||||
"Основные шаги построения нечеткой логической модели:\n",
|
||||
"1. Каждой переменной (например, доходу) присваиваются лингвистические категории: \"низкий\", \"средний\", \"высокий\".\n",
|
||||
"2. Каждой категории сопоставляется функция принадлежности (обычно треугольная), которая отображает степень принадлежности значения к категории.\n",
|
||||
"3. Формируются логические правила, например: \n",
|
||||
" _Если доход высокий, траты на вино высокие, а последняя покупка была недавно → клиент откликнется на кампанию._\n",
|
||||
"4. Система агрегирует правила, выполняет логический вывод и преобразует результат в чёткое значение (дефаззификация).\n",
|
||||
"\n",
|
||||
"---\n",
|
||||
"\n",
|
||||
"## Цель\n",
|
||||
"\n",
|
||||
"Разработать и исследовать нечеткую логическую модель, которая по данным клиента (`Income`, `MntWines`, `Recency`) будет предсказывать вероятность **отклика** на маркетинговую кампанию (`Response`).\n",
|
||||
"\n",
|
||||
"Такая модель позволяет понять, как поведение клиентов можно описывать с помощью нечетких понятий и как это помогает в принятии решений в маркетинге — даже если данные неточны или размыты, а признаки нельзя выразить жёсткими границами.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"### Импорт необходимых библиотек и загрузка исходных данных\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-05-24T02:37:55.895461100Z",
|
||||
"start_time": "2025-05-24T02:37:54.115157200Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" ID Year_Birth Education Marital_Status Income Kidhome Teenhome \\\n",
|
||||
"0 5524 1957 Graduation Single 58138.0 0 0 \n",
|
||||
"1 2174 1954 Graduation Single 46344.0 1 1 \n",
|
||||
"2 4141 1965 Graduation Together 71613.0 0 0 \n",
|
||||
"3 6182 1984 Graduation Together 26646.0 1 0 \n",
|
||||
"4 5324 1981 PhD Married 58293.0 1 0 \n",
|
||||
"\n",
|
||||
" Dt_Customer Recency MntWines ... NumWebVisitsMonth AcceptedCmp3 \\\n",
|
||||
"0 04-09-2012 58 635 ... 7 0 \n",
|
||||
"1 08-03-2014 38 11 ... 5 0 \n",
|
||||
"2 21-08-2013 26 426 ... 4 0 \n",
|
||||
"3 10-02-2014 26 11 ... 6 0 \n",
|
||||
"4 19-01-2014 94 173 ... 5 0 \n",
|
||||
"\n",
|
||||
" AcceptedCmp4 AcceptedCmp5 AcceptedCmp1 AcceptedCmp2 Complain \\\n",
|
||||
"0 0 0 0 0 0 \n",
|
||||
"1 0 0 0 0 0 \n",
|
||||
"2 0 0 0 0 0 \n",
|
||||
"3 0 0 0 0 0 \n",
|
||||
"4 0 0 0 0 0 \n",
|
||||
"\n",
|
||||
" Z_CostContact Z_Revenue Response \n",
|
||||
"0 3 11 1 \n",
|
||||
"1 3 11 0 \n",
|
||||
"2 3 11 0 \n",
|
||||
"3 3 11 0 \n",
|
||||
"4 3 11 0 \n",
|
||||
"\n",
|
||||
"[5 rows x 29 columns]\n",
|
||||
"['ID', 'Year_Birth', 'Education', 'Marital_Status', 'Income', 'Kidhome', 'Teenhome', 'Dt_Customer', 'Recency', 'MntWines', 'MntFruits', 'MntMeatProducts', 'MntFishProducts', 'MntSweetProducts', 'MntGoldProds', 'NumDealsPurchases', 'NumWebPurchases', 'NumCatalogPurchases', 'NumStorePurchases', 'NumWebVisitsMonth', 'AcceptedCmp3', 'AcceptedCmp4', 'AcceptedCmp5', 'AcceptedCmp1', 'AcceptedCmp2', 'Complain', 'Z_CostContact', 'Z_Revenue', 'Response']\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"import pandas as pd\n",
|
||||
"import skfuzzy as fuzz\n",
|
||||
"from skfuzzy import control as ctrl\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"\n",
|
||||
"df = pd.read_csv(\"../Static/marketing_campaign.csv\", sep=\"\\t\")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"print(df.head())\n",
|
||||
"df.columns = df.columns.str.strip() # Удалим случайные пробелы\n",
|
||||
"print(df.columns.tolist()) # Проверим результат\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1. Выбор входных и выходных переменных\n",
|
||||
"\n",
|
||||
"В качестве задачи классификации мы будем предсказывать, откликнется ли клиент на маркетинговую кампанию (`Response` = 1 или 0).\n",
|
||||
"\n",
|
||||
"Для построения нечеткой логической системы выберем следующие переменные:\n",
|
||||
"\n",
|
||||
"- `Income` — годовой доход клиента.\n",
|
||||
"- `Recency` — количество дней с последней покупки.\n",
|
||||
"- `MntWines` — сумма, потраченная на вино за последние 2 года.\n",
|
||||
"\n",
|
||||
"**Целевая переменная:** `Response` — отклик на последнюю маркетинговую кампанию (1 — да, 0 — нет).\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Income</th>\n",
|
||||
" <th>Recency</th>\n",
|
||||
" <th>MntWines</th>\n",
|
||||
" <th>Response</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>0.084832</td>\n",
|
||||
" <td>0.585859</td>\n",
|
||||
" <td>0.425318</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>0.067095</td>\n",
|
||||
" <td>0.383838</td>\n",
|
||||
" <td>0.007368</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>0.105097</td>\n",
|
||||
" <td>0.262626</td>\n",
|
||||
" <td>0.285332</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>0.037471</td>\n",
|
||||
" <td>0.262626</td>\n",
|
||||
" <td>0.007368</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>0.085065</td>\n",
|
||||
" <td>0.949495</td>\n",
|
||||
" <td>0.115874</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" Income Recency MntWines Response\n",
|
||||
"0 0.084832 0.585859 0.425318 1.0\n",
|
||||
"1 0.067095 0.383838 0.007368 0.0\n",
|
||||
"2 0.105097 0.262626 0.285332 0.0\n",
|
||||
"3 0.037471 0.262626 0.007368 0.0\n",
|
||||
"4 0.085065 0.949495 0.115874 0.0"
|
||||
]
|
||||
},
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"\n",
|
||||
"# Выбор нужных столбцов и удаление строк с пропусками\n",
|
||||
"df_clean = df[['Income', 'Recency', 'MntWines', 'Response']].dropna()\n",
|
||||
"\n",
|
||||
"# Нормализация данных (для удобства задания функций принадлежности)\n",
|
||||
"from sklearn.preprocessing import MinMaxScaler\n",
|
||||
"\n",
|
||||
"scaler = MinMaxScaler()\n",
|
||||
"df_scaled = pd.DataFrame(scaler.fit_transform(df_clean), columns=df_clean.columns)\n",
|
||||
"\n",
|
||||
"df_scaled.head()\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 2. Настройка параметров лингвистических переменных\n",
|
||||
"\n",
|
||||
"Для каждой входной переменной зададим по 3 терма: 'низкий', 'средний', 'высокий'.\n",
|
||||
"\n",
|
||||
"Тип функции принадлежности: треугольная (triangular).\n",
|
||||
"\n",
|
||||
"Переменные:\n",
|
||||
"- `Income` — Доход\n",
|
||||
"- `Recency` — Давность последней покупки\n",
|
||||
"- `MntWines` — Траты на вино\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"import skfuzzy as fuzz\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"\n",
|
||||
"# Создание универсума\n",
|
||||
"x_income = np.linspace(0, 1, 100)\n",
|
||||
"x_recency = np.linspace(0, 1, 100)\n",
|
||||
"x_wines = np.linspace(0, 1, 100)\n",
|
||||
"\n",
|
||||
"# Функции принадлежности\n",
|
||||
"income_lo = fuzz.trimf(x_income, [0, 0, 0.5])\n",
|
||||
"income_md = fuzz.trimf(x_income, [0.25, 0.5, 0.75])\n",
|
||||
"income_hi = fuzz.trimf(x_income, [0.5, 1, 1])\n",
|
||||
"\n",
|
||||
"recency_lo = fuzz.trimf(x_recency, [0, 0, 0.5])\n",
|
||||
"recency_md = fuzz.trimf(x_recency, [0.25, 0.5, 0.75])\n",
|
||||
"recency_hi = fuzz.trimf(x_recency, [0.5, 1, 1])\n",
|
||||
"\n",
|
||||
"wine_lo = fuzz.trimf(x_wines, [0, 0, 0.5])\n",
|
||||
"wine_md = fuzz.trimf(x_wines, [0.25, 0.5, 0.75])\n",
|
||||
"wine_hi = fuzz.trimf(x_wines, [0.5, 1, 1])\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 3. Сформировать базу нечетких правил\n",
|
||||
"\n",
|
||||
"Пример нечетких правил:\n",
|
||||
"- ЕСЛИ `Income` высокий И `MntWines` высокий И `Recency` низкий, ТО `Response` = отклик\n",
|
||||
"- ЕСЛИ `Income` низкий И `MntWines` низкий И `Recency` высокий, ТО `Response` = отказ\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Оценка принадлежности классу 'Отклик': 0.000\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Пример реализации простого правила на одном наблюдении\n",
|
||||
"def fuzzy_response(income, recency, wine):\n",
|
||||
" # Степени принадлежности\n",
|
||||
" income_hi_val = fuzz.interp_membership(x_income, income_hi, income)\n",
|
||||
" wine_hi_val = fuzz.interp_membership(x_wines, wine_hi, wine)\n",
|
||||
" recency_lo_val = fuzz.interp_membership(x_recency, recency_lo, recency)\n",
|
||||
"\n",
|
||||
" # Пример одного правила: если income высокий И wine высокий И recency низкий → отклик\n",
|
||||
" rule_activation = np.fmin(np.fmin(income_hi_val, wine_hi_val), recency_lo_val)\n",
|
||||
" return rule_activation\n",
|
||||
"\n",
|
||||
"# Проверим на первом примере\n",
|
||||
"test = df_scaled.iloc[0]\n",
|
||||
"response_degree = fuzzy_response(test['Income'], test['Recency'], test['MntWines'])\n",
|
||||
"print(f\"Оценка принадлежности классу 'Отклик': {response_degree:.3f}\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 4. Оценка качества нечеткой системы\n",
|
||||
"\n",
|
||||
"Преобразуем оценку принадлежности к классу `Отклик` в бинарный результат с порогом 0.5.\n",
|
||||
"\n",
|
||||
"Оценим точность предсказания для всей выборки с помощью `accuracy_score`.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Точность нечеткой логической модели: 0.85\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from sklearn.metrics import accuracy_score\n",
|
||||
"\n",
|
||||
"# Предсказания на всей выборке\n",
|
||||
"predictions = df_scaled.apply(lambda row: 1 if fuzzy_response(row['Income'], row['Recency'], row['MntWines']) > 0.5 else 0, axis=1)\n",
|
||||
"\n",
|
||||
"# Оценка точности\n",
|
||||
"accuracy = accuracy_score(df_scaled['Response'], predictions)\n",
|
||||
"print(f\"Точность нечеткой логической модели: {accuracy:.2f}\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Интерпретация результатов\n",
|
||||
"\n",
|
||||
"Нечеткая логическая система была построена на основе трёх признаков:\n",
|
||||
"\n",
|
||||
"- `Income` — доход клиента\n",
|
||||
"- `Recency` — количество дней с последней покупки\n",
|
||||
"- `MntWines` — траты на вино\n",
|
||||
"\n",
|
||||
"Была реализована система с одним правилом: если клиент имеет **высокий доход**, **высокие траты на вино** и **недавно делал покупки**, то он с высокой вероятностью **откликнется на маркетинговую кампанию**.\n",
|
||||
"\n",
|
||||
"После тестирования на всей выборке мы получили:\n",
|
||||
"\n",
|
||||
"**Точность нечеткой логической модели: 0.85 (85%)**\n",
|
||||
"\n",
|
||||
"- Это означает, что система верно предсказала поведение клиентов в 85% случаев.\n",
|
||||
"\n",
|
||||
"- Учитывая, что мы использовали всего **одно простое нечеткое правило**, такая точность считается хорошим результатом и демонстрирует потенциал нечеткой логики для задач маркетинговой аналитики.\n",
|
||||
"\n",
|
||||
"- В дальнейшем систему можно расширить, добавив больше правил и переменных, чтобы повысить точность и охват различных сценариев поведения клиентов.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "aimvenv",
|
||||
"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.10"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
593
lab_8/lab8.ipynb
Normal file
593
lab_8/lab8.ipynb
Normal file
File diff suppressed because one or more lines are too long
452
lab_9/lab9.ipynb
Normal file
452
lab_9/lab9.ipynb
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user