217 lines
130 KiB
Plaintext
Raw Normal View History

2025-02-28 16:43:15 +04:00
{
"cells": [
{
"cell_type": "code",
"execution_count": 113,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"from pandas import DataFrame\n",
"import numpy as np\n",
"import skfuzzy as fuzz\n",
"import matplotlib.pyplot as plt\n",
"\n",
"df: DataFrame = pd.read_csv(\".//static//csv//Starbucks Dataset.csv\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Формирование базы нечетких правил\n",
"Сформируем базу нечетких правил, которые связывают входные и выходные переменные."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 800x900 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Определение диапазонов значений для входных переменных\n",
"x_high = np.linspace(0, 0.95, 100)\n",
"x_open = np.linspace(0, 0.95, 100)\n",
"x_volume = np.linspace(0, 3000000, 100)\n",
"\n",
"# Определение функций принадлежности для high\n",
"high_low = fuzz.trapmf(x_high, [0, 0, 0.1, 0.45])\n",
"high_medium = fuzz.trimf(x_high, [0.4, 0.5, 0.75])\n",
"high_high = fuzz.smf(x_high, 0.7, 0.9)\n",
"\n",
"# Определение функций принадлежности для Open\n",
"open_low = fuzz.trapmf(x_open, [0, 0, 0.1, 0.55])\n",
"open_medium = fuzz.trimf(x_open, [0.4, 0.6, 0.85])\n",
"open_high = fuzz.smf(x_open, 0.7, 0.9)\n",
"\n",
"# Определение функций принадлежности для Value\n",
"volume_low = fuzz.trapmf(x_volume, [0, 0, 500000, 1000000])\n",
"volume_medium = fuzz.trimf(x_volume, [800000, 1500000, 2000000])\n",
"volume_high = fuzz.smf(x_volume, 1800000, 3000000)\n",
"\n",
"# Определение нечетких правил\n",
"fuzzy_rules = [\n",
" (\"Низкий\", \"Мало\", \"Низкий\"),\n",
" (\"Низкий\", \"Средне\", \"Средний\"),\n",
" (\"Низкий\", \"Много\", \"Высокий\"),\n",
" (\"Средний\", \"Мало\", \"Средний\"),\n",
" (\"Средний\", \"Средне\", \"Высокий\"),\n",
" (\"Средний\", \"Много\", \"Высокий\"),\n",
" (\"Высокий\", \"Мало\", \"Высокий\"),\n",
" (\"Высокий\", \"Средне\", \"Высокий\"),\n",
" (\"Высокий\", \"Много\", \"Высокий\")\n",
"]\n",
"\n",
"# Визуализация функций принадлежности\n",
"fig, (ax0, ax1, ax2) = plt.subplots(nrows=3, figsize=(8, 9))\n",
"\n",
"ax0.plot(x_high, high_low, 'b', linewidth=1.5, label='Низкий')\n",
"ax0.plot(x_high, high_medium, 'g', linewidth=1.5, label='Средний')\n",
"ax0.plot(x_high, high_high, 'r', linewidth=1.5, label='Высокий')\n",
"ax0.set_title('Функции принадлежности для Hight')\n",
"ax0.legend()\n",
"\n",
"ax1.plot(x_open, open_low, 'b', linewidth=1.5, label='Мало')\n",
"ax1.plot(x_open, open_medium, 'g', linewidth=1.5, label='Средне')\n",
"ax1.plot(x_open, open_high, 'r', linewidth=1.5, label='Много')\n",
"ax1.set_title('Функции принадлежности для Open')\n",
"ax1.legend()\n",
"\n",
"ax2.plot(x_volume, volume_low, 'b', linewidth=1.5, label='Низкий')\n",
"ax2.plot(x_volume, volume_medium, 'g', linewidth=1.5, label='Средний')\n",
"ax2.plot(x_volume, volume_high, 'r', linewidth=1.5, label='Высокий')\n",
"ax2.set_title('Функции принадлежности для Value')\n",
"ax2.legend() \n",
"\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## База нечётких правил\n",
"\n",
"\n",
"\n",
"\n",
"Для оценки качества системы создадим тестовые данные и применим нечеткие правила для получения предсказанных значений. Затем сравним их с реальными значениями."
]
},
{
"cell_type": "code",
"execution_count": 115,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"High | Open | Value | Оцененная Value\n",
"0.347656 | 0.328125 | 224358400 | 464215.53\n",
"0.367188 | 0.339844 | 58732800 | 470894.11\n",
"0.367188 | 0.371094 | 34777600 | 470894.11\n",
"0.644531 | 0.640625 | 11148800 | 1419002.85\n",
"\n",
"Средняя абсолютная ошибка (MAE): 81548148.35\n",
"Среднеквадратичная ошибка (RMSE): 117041311.66\n"
]
}
],
"source": [
"# Функция для вычисления нечеткой оценки\n",
"def fuzzy_inference(high, open):\n",
" # Определение степени принадлежности\n",
" high_low_degree = fuzz.interp_membership(x_high, high_low, high)\n",
" high_medium_degree = fuzz.interp_membership(x_high, high_medium, high)\n",
" high_high_degree = fuzz.interp_membership(x_high, high_high, high)\n",
"\n",
" open_low_degree = fuzz.interp_membership(x_open, open_low, open)\n",
" open_medium_degree = fuzz.interp_membership(x_open, open_medium, open)\n",
" open_high_degree = fuzz.interp_membership(x_open, open_high, open)\n",
"\n",
" # Применяем правила\n",
" # Активируем термы выходной переменной с использованием степени принадлежности\n",
" volume_low_activated = np.fmin(high_low_degree, volume_low)\n",
" volume_medium_activated = np.fmin(high_medium_degree, volume_medium)\n",
" volume_high_activated = np.fmin(high_high_degree, volume_high)\n",
"\n",
" # Агрегируем все активированные термы\n",
" aggregated = np.fmax(volume_low_activated, np.fmax(volume_medium_activated, volume_high_activated))\n",
"\n",
" # Дефуззификация\n",
" volume_defuzz = fuzz.defuzz(x_volume, aggregated, 'centroid')\n",
"\n",
" return volume_defuzz\n",
"\n",
"# Оценка системы на тестовом наборе данных\n",
"results = []\n",
"test_data = [\n",
" (0.347656, 224358400, 0.328125),\n",
" (0.367188, 58732800, 0.339844),\n",
" (0.367188, 34777600, 0.371094),\n",
" (0.644531, 11148800, 0.640625),\n",
"]\n",
"for high, actual_volume, open in test_data:\n",
" inferred_volume = fuzzy_inference(high, open)\n",
" results.append((high, open, actual_volume, inferred_volume))\n",
"\n",
"# Вывод результатов\n",
"print(\"High | Open | Value | Оцененная Value\")\n",
"for high, open, actual_volume, inferred_volume in results:\n",
" print(f\"{high:4} | {open:6} | {actual_volume:15} | {inferred_volume:.2f}\")\n",
"\n",
"# Вычисление метрик качества\n",
"actual_volumes = [actual for _, _, actual, _ in results]\n",
"inferred_volumes = [inferred for _, _, _, inferred in results]\n",
"\n",
"mae = np.mean(np.abs(np.array(actual_volumes) - np.array(inferred_volumes)))\n",
"rmse = np.sqrt(np.mean((np.array(actual_volumes) - np.array(inferred_volumes)) ** 2))\n",
"\n",
"print(f\"\\nСредняя абсолютная ошибка (MAE): {mae:.2f}\")\n",
"print(f\"Среднеквадратичная ошибка (RMSE): {rmse:.2f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"В результате выполнения лабораторной работы была создана нечеткая система, которая позволяет оценивать общую стоимость транзакции на основе открытия акции и количества продаж акций. Система была протестирована на тестовых данных, и были вычислены метрики качества (MAE и RMSE). Полученные результаты указывают на необходимость дальнейшей настройки системы для повышения точности предсказаний."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "aisenv",
"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.6"
}
},
"nbformat": 4,
"nbformat_minor": 2
}