2025-02-22 12:16:00 +04:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Настройка параметров лингвистических переменных\n",
"Для каждой переменной определим количество термов, типы и параметры функций принадлежности.\n",
"\n",
"Для переменной Cost:\n",
"- Термы: Низкий, Средний, Высокий\n",
"- Тип функции принадлежности: Треугольная\n",
"Параметры:\n",
"- Низкий: (0, 200, 400)\n",
"- Средний: (300, 600, 900)\n",
"- Высокий: (800, 1200, 1600)\n",
"\n",
"Для переменной Shares:\n",
"- Термы: Мало, Средне, Много\n",
"- Тип функции принадлежности: Треугольная\n",
"Параметры:\n",
"- Мало: (0, 5000, 10000)\n",
"- Средне: (8000, 15000, 20000)\n",
"- Много: (18000, 25000, 30000)\n",
"\n",
"Для переменной Value ($):\n",
"- Термы: Низкий, Средний, Высокий\n",
"- Тип функции принадлежности: Треугольная\n",
"\n",
"Параметры:\n",
"- Низкий: (0, 500000, 1000000)\n",
"- Средний: (800000, 1500000, 2000000)\n",
"- Высокий: (1800000, 2500000, 3000000)"
]
},
{
"cell_type": "code",
2025-02-22 13:01:52 +04:00
"execution_count": 33,
2025-02-22 12:16:00 +04:00
"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/TSLA.csv\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Формирование базы нечетких правил\n",
"Сформируем базу нечетких правил, которые связывают входные и выходные переменные."
]
},
{
"cell_type": "code",
2025-02-22 12:56:02 +04:00
"execution_count": null,
2025-02-22 12:16:00 +04:00
"metadata": {},
"outputs": [
{
"data": {
2025-02-22 13:01:52 +04:00
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAN6CAYAAAATiN+GAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3QV4FFcXBuAvjgd3d5fiUrxoKVAK/BTXFnd3dyvu0ALFWqSF4i7Ftbi7Q5BAEpL9n3OHDZuwCZFNZuV7n2fJ7LJyM7tJ5sy95xwng8FgABERERERUSQ4R+bBREREREREgoEFERERERFFGgMLIiIiIiKKNAYWREREREQUaQwsiIiIiIgo0hhYEBERERFRpDGwICIiIiKiSGNgQUREREREkcbAgoiIiIiIIo2BBRERERERRRoDCyIK1KxZM8SJE0fvYRCRDbt27Rp++uknZMyYETFixEC8ePFQsmRJTJ06Fe/evbP463l7e2PIkCHYvXu3xZ+biMLHNZz3JyI78+zZMyxbtgz79u3D3r171R/+KlWqoECBAqhXr576SkQUFhs3bkTdunXh4eGBJk2aIHfu3PD19cX+/fvRs2dP/Pfff5g7d67FA4uhQ4eq7bJly1r0uYkofBhYEDmwFStWoHXr1njz5g3Sp08PNzc3ODk5qWBj4sSJGDNmDJo2baoOBNzd3fUeLhFZsRs3buB///sf0qVLh507dyJFihSB/9e+fXtcvXpVBR5EZL+4FIrIQR04cACNGjVC8uTJ1bYcFFSsWFEtXTh69Cju37+PBg0aYMmSJejatat6jMFgUAFIzZo1P3u+9+/fw9PTUy2BELIsQYKUNWvWfHZfWW4ly66MFi9erO578+bNwNvkzGaCBAnw7bff4sOHD0Hud+zYsSDP9/TpU3W7LIcwZe628ePHq9tNz2waxxp8KUX16tXNPkdwxseHdDH3vcrskOyrRIkSqaUicnb3xYsXQZ5X9rXpY8Xq1avV4+X/jGS/yW0TJkz4bGxyxtj0e5Wzx4MGDULBggXV+xU7dmx8/fXX2LVrl9nvzTje4BfT1zcV0j4wfW/F0qVL1RhixoyJhAkTqgPSO3fuBBlnmTJl1HKaJ0+eBN4u74U8nyn5vl1dXbFp06bA2+R7lu89OLmvufHMnDkTuXLlUmfaU6ZMqQ6EX758+dnjDx8+jGrVqqnPpuy7vHnzqiU+Qt6r0D4Hpq8b1vc2NMb3PSz727hPzN1X3mNTs2bNUvsuVqxYQe5n7mfZ1Lhx49RJigULFgQJKowyZ86Mzp07B16Xn+vhw4cjU6ZMar/L992vXz/4+PgEeZz8vFeuXBmJEydWn5cMGTKgRYsWgfsgSZIkaltmLYxj/dLPLBFFDc5YEDkomY0ICAhQsxZygBec/BH/9ddfcf78ecyZMweDBw9G0qRJVTAiBxDPnz9XB4RGf/31F169eqX+P7LkAFOWY2XPnh2rVq1SB42WIAeKo0ePDtN95cDf9EA1LDp16oTChQsHua1Vq1Zm79uhQwfEjx9fHQBdunRJHczdunUrMEgxRw7E+vfvj8iQ92j+/PkqaJTZqtevX6sDQTlwO3LkCPLnz2/2ccOGDVMHdEJms4IHQaZq166N77//Xm3LErvgS19GjhyJgQMHqqV2sn8kcJg2bRpKly6NkydPqv0iM2R//vknihUrpp5vx44d6uAzuPXr16N3796YMmWKOuCPCHkP5KBUAuu2bdsGvh8SYEvQLTN5Ytu2bSrQlYNmOUCWoPzChQv4+++/1XUJFOU5jBo3bhxkXwjjQbAl31t5L43fu3xmf//99xDvKz9TxteRgNx40sBo5cqVaNeunQpCOnbsqIIn+R5HjRr1xXHI7wAJBEuUKBGmcct7LycufvjhB3Tv3l0FbfLzKa+3du1adZ/Hjx+jUqVKar/16dNHfTYkmJDPhpDb5b2S9810X0vAR0Q6MBCRQ0qYMKEhXbp0QW5r2rSpIXbs2EFuGzhwoEF+Vfz111/q+qVLl9T1WbNmBbnfd999Z0ifPr0hICBAXd+1a5e63+rVqz97bXkNeS2jRYsWqfveuHHD8Pz5c0POnDkN2bJlMzx9+jTI44z3O3r0aJDbnzx5om4fPHhwkNuD39arVy9D0qRJDQULFjSUKVMm8HbjWOWrUdGiRQ1Vq1Y1+7zBReR7lTH4+voG3j5u3Dh1+/r16wNvk/fH9LEzZ840eHh4GMqVKxfkvZP9Jo8dP378Z6+fK1euIN/rhw8fDD4+PkHu8+LFC0OyZMkMLVq0+Ozxc+fOVc997NixwNuqV6/+2WdH+Pn5qfsOHTr0s+9Xxihu3rxpcHFxMYwcOTLIY8+ePWtwdXX97Hb5vCVIkMDQqFEjdV3eC+OfrpMnT6r92759+8/GIt+zfO/ByT4yHc/jx48N7u7uhkqVKhn8/f0D7zd9+nR1v4ULFwbutwwZMqjvW/aXKeNnPrjQPjthfW9Dc/nyZfUaEyZMCPH7M1WyZEn1/ME/N/IeGTVo0MAQP358w7t378L0+Tby8vJS96lZs2aYxn7q1Cl1/1atWgW5vUePHur2nTt3qutr1641+zMflp9/Iop+XApF5KDkTLXMQHxJsmTJAs90i6xZs6Jo0aIq4dtIZi/++ecfNGzY8LOz7fI6cmbU9BISWU713XffqTPYmzdvVsuELOXevXvqrLicKf9S5Ss5Gypnq2VWJ6q0adMm8Ey4kDOuwZfzBE9QlVkDmelImzZtiPcJvq/9/f2D3MfFxSUwX0ZmrOS9k7PlhQoVwokTJ8y+J0KWyH2JLF8S5mYWTPetvK7MVpiOU87+Z8mS5bMlWfJ5++OPP9TnbcSIEYG3P3jwADVq1EDx4sUDlyIFJ9978P0h+8jU9u3b1bi7dOkCZ+dPfxJlNkeWqBlzAmQmRZYLyv3krLmpkGaYwios76054XlvhHyfob03xp9XWQIV1uc0Mv5+iBs3bpjub/ycd+vWLcjtMnMhjPvduK9lVsjPzy9cYyKi6MfAgshByTpyKQv5JZJwKVKlShV4m+QDyBIRWbpjXBsuf/Rl6UdwshZaliuYXt6+fWv2tZo3b66qx8jBjTGvwlJkKZd8z8YckJDIwais85YgKSqXU8hBtCkJdmSJjbm18WLSpEnqQFLGFtr3GHxfX7x48bP7yfIT+d7k4FGCN7mfHMh5eXl9dl9jICj5GF9izEkILXC7cuWKytWR7z/4WGUJjCx9CU4CTXmM5IYYDzglz+fu3btm728k33vw15B9ZMr4Gc6WLVuQ2yX4kmU9xv83/qyYy9uIrLC8t+aE570xvj9fCqolUJP8Klkedvv2bfUa5j4XwUkQJuRnNyxkv0ogJ3kXpiTAlGDCuN8lz6ZOnTpqqZosz5T3fdGiRZ/lYRCRdWCOBZGDkrXiM2bMUOvrW7ZsafY+jx49UgehckAma92NJNFW1mbLWWQ5GJJEXDnjHfzgTMjBoCQHm5IzzebIGXNZMy9nbuWMvlSWsQQ5YJUEVRmn6SyBObI/5OB+y5YtsBZycCdJ53379g2S1xKc7DMp9WlKzrybkn0gScO1atVS5T9l1kpmMWRtu7lAU/aF7DMJyr7k4cOHgQeHIZHZCjnDLzNc8rrBBT/wlWRgOasteQQSeMlBuHFc8lmRg06ZiZKZhOAkGXjevHlBbpMg2NLlTqPjvTXHNBE8LOT9kVya0MjPteSYSFK1sYRrWEhgIZ+Rc+fOITy+NNtjTBr/999/VQ6H/FzKyQrJ85Hb2HeHyLowsCByUAMGDMC6devUEhw5s/vjjz8GLpuRM5WSLCtBgSTpLl++PMgSCjkAkopJEljImX2ZvZDkWXPy5MkTJKFVmDugFJJULEuh5P8l8Akt6AkPOWiTpOT69euHqR6+JK9KycyoJGfuy5UrF+QAWpb3mEtAliVAssTEtKKOOTILEHxfS/KtKTlIkzPxsiTJ9KAu+Jl804o8X331VZBlQiGRRH+RI0eOEO8jFYBk9kESwWWZ05fIuOQsuBxIyrI8qRYmB5fy2ZUkYdknch95b4NXIpLvPfj+OHXqVJDrxvdZDqZlv5guGzJWSjO
2025-02-22 12:16:00 +04:00
"text/plain": [
"<Figure size 800x900 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Определение диапазонов значений для входных переменных\n",
"x_cost = np.linspace(0, 1600, 100)\n",
"x_shares = np.linspace(0, 30000, 100)\n",
"x_value = np.linspace(0, 3000000, 100)\n",
"\n",
"# Определение функций принадлежности для Cost\n",
2025-02-22 12:56:02 +04:00
"cost_low = fuzz.trapmf(x_cost, [0, 0, 200, 400])\n",
2025-02-22 12:16:00 +04:00
"cost_medium = fuzz.trimf(x_cost, [300, 600, 900])\n",
2025-02-22 12:56:02 +04:00
"cost_high = fuzz.smf(x_cost, 800, 1200)\n",
2025-02-22 12:16:00 +04:00
"\n",
"# Определение функций принадлежности для Shares\n",
2025-02-22 12:56:02 +04:00
"shares_low = fuzz.trapmf(x_shares, [0, 0, 5000, 10000])\n",
2025-02-22 12:16:00 +04:00
"shares_medium = fuzz.trimf(x_shares, [8000, 15000, 20000])\n",
2025-02-22 12:56:02 +04:00
"shares_high = fuzz.smf(x_shares, 18000, 25000)\n",
2025-02-22 12:16:00 +04:00
"\n",
"# Определение функций принадлежности для Value\n",
2025-02-22 12:56:02 +04:00
"value_low = fuzz.trapmf(x_value, [0, 0, 500000, 1000000])\n",
2025-02-22 12:16:00 +04:00
"value_medium = fuzz.trimf(x_value, [800000, 1500000, 2000000])\n",
2025-02-22 12:56:02 +04:00
"value_high = fuzz.smf(x_value, 1800000, 2500000)\n",
2025-02-22 12:16:00 +04:00
"\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_cost, cost_low, 'b', linewidth=1.5, label='Низкий')\n",
"ax0.plot(x_cost, cost_medium, 'g', linewidth=1.5, label='Средний')\n",
"ax0.plot(x_cost, cost_high, 'r', linewidth=1.5, label='Высокий')\n",
"ax0.set_title('Функции принадлежности для Cost')\n",
"ax0.legend()\n",
"\n",
"ax1.plot(x_shares, shares_low, 'b', linewidth=1.5, label='Мало')\n",
"ax1.plot(x_shares, shares_medium, 'g', linewidth=1.5, label='Средне')\n",
"ax1.plot(x_shares, shares_high, 'r', linewidth=1.5, label='Много')\n",
"ax1.set_title('Функции принадлежности для Shares')\n",
"ax1.legend()\n",
"\n",
"ax2.plot(x_value, value_low, 'b', linewidth=1.5, label='Низкий')\n",
"ax2.plot(x_value, value_medium, 'g', linewidth=1.5, label='Средний')\n",
"ax2.plot(x_value, value_high, 'r', linewidth=1.5, label='Высокий')\n",
"ax2.set_title('Функции принадлежности для Value')\n",
2025-02-22 13:01:52 +04:00
"ax2.legend() \n",
2025-02-22 12:16:00 +04:00
"\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Оценка качества полученной нечеткой системы\n",
"Для оценки качества системы создадим тестовые данные и применим нечеткие правила для получения предсказанных значений. Затем сравним их с реальными значениями."
]
},
{
"cell_type": "code",
2025-02-22 13:01:52 +04:00
"execution_count": 35,
2025-02-22 12:16:00 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Cost | Shares | Эталонная Value | Оцененная Value\n",
2025-02-22 12:56:02 +04:00
" 150 | 5000 | 750000 | 388854.87\n",
2025-02-22 12:16:00 +04:00
" 450 | 12000 | 1500000 | 1421901.23\n",
2025-02-22 13:01:52 +04:00
"1000 | 20000 | 2500000 | 2512975.52\n",
2025-02-22 12:16:00 +04:00
"\n",
2025-02-22 13:01:52 +04:00
"Средняя абсолютная ошибка (MAE): 150739.81\n",
"Среднеквадратичная ошибка (RMSE): 213458.50\n"
2025-02-22 12:16:00 +04:00
]
}
],
"source": [
"# Функция для вычисления нечеткой оценки\n",
"def fuzzy_inference(cost, shares):\n",
" # Определение степени принадлежности\n",
" cost_low_degree = fuzz.interp_membership(x_cost, cost_low, cost)\n",
" cost_medium_degree = fuzz.interp_membership(x_cost, cost_medium, cost)\n",
" cost_high_degree = fuzz.interp_membership(x_cost, cost_high, cost)\n",
"\n",
" shares_low_degree = fuzz.interp_membership(x_shares, shares_low, shares)\n",
" shares_medium_degree = fuzz.interp_membership(x_shares, shares_medium, shares)\n",
" shares_high_degree = fuzz.interp_membership(x_shares, shares_high, shares)\n",
"\n",
" # Применяем правила\n",
" # Активируем термы выходной переменной с использованием степени принадлежности\n",
" value_low_activated = np.fmin(cost_low_degree, value_low)\n",
" value_medium_activated = np.fmin(cost_medium_degree, value_medium)\n",
" value_high_activated = np.fmin(cost_high_degree, value_high)\n",
"\n",
" # Агрегируем все активированные термы\n",
" aggregated = np.fmax(value_low_activated, np.fmax(value_medium_activated, value_high_activated))\n",
"\n",
" # Дефуззификация\n",
" value_defuzz = fuzz.defuzz(x_value, aggregated, 'centroid')\n",
"\n",
" return value_defuzz\n",
"\n",
"# Оценка системы на тестовом наборе данных\n",
"results = []\n",
"for cost, shares, actual_value in test_data:\n",
" inferred_value = fuzzy_inference(cost, shares)\n",
" results.append((cost, shares, actual_value, inferred_value))\n",
"\n",
"# Вывод результатов\n",
"print(\"Cost | Shares | Эталонная Value | Оцененная Value\")\n",
"for cost, shares, actual_value, inferred_value in results:\n",
" print(f\"{cost:4} | {shares:6} | {actual_value:15} | {inferred_value:.2f}\")\n",
"\n",
"# Вычисление метрик качества\n",
"actual_values = [actual for _, _, actual, _ in results]\n",
"inferred_values = [inferred for _, _, _, inferred in results]\n",
"\n",
"mae = np.mean(np.abs(np.array(actual_values) - np.array(inferred_values)))\n",
"rmse = np.sqrt(np.mean((np.array(actual_values) - np.array(inferred_values)) ** 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": ".venv",
"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.13.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}