AIM-PIbd-31-Kryukov-A-I/Lab_3/lab3.ipynb

645 lines
290 KiB
Plaintext
Raw Normal View History

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
" ## Вариант 13 \n",
" https://www.kaggle.com/datasets/nancyalaswad90/yamana-gold-inc-stock-price?resource=download\n"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"RangeIndex: 5251 entries, 0 to 5250\n",
"Data columns (total 7 columns):\n",
" # Column Non-Null Count Dtype \n",
"--- ------ -------------- ----- \n",
" 0 Date 5251 non-null datetime64[ns]\n",
" 1 Open 5251 non-null float64 \n",
" 2 High 5251 non-null float64 \n",
" 3 Low 5251 non-null float64 \n",
" 4 Close 5251 non-null float64 \n",
" 5 Adj Close 5251 non-null float64 \n",
" 6 Volume 5251 non-null int64 \n",
"dtypes: datetime64[ns](1), float64(5), int64(1)\n",
"memory usage: 287.3 KB\n",
"None\n",
" Date Open High Low Close Adj Close Volume\n",
"0 2001-06-22 3.428571 3.428571 3.428571 3.428571 2.806002 0\n",
"1 2001-06-25 3.428571 3.428571 3.428571 3.428571 2.806002 0\n",
"2 2001-06-26 3.714286 3.714286 3.714286 3.714286 3.039837 0\n",
"3 2001-06-27 3.714286 3.714286 3.714286 3.714286 3.039837 0\n",
"4 2001-06-28 3.714286 3.714286 3.714286 3.714286 3.039837 0\n"
]
}
],
"source": [
"import pandas as pd\n",
"\n",
"ddata = pd.read_csv(\"../static/csv/Yamana_Gold_Inc._AUY.csv\")\n",
2024-11-15 23:40:48 +04:00
"data['Date'] = pd.to_datetime(data['Date'])\n",
"\n",
"# Первичный анализ данных\n",
"print(data.info())\n",
"print(data.head())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#1. Бизнес-цели для набора данных по акции компании Yamana Gold Inc.\n",
"Цель 1: Прогнозирование изменения цены акции компании.\n",
"Прогнозирование цен на акции является одной из ключевых задач в области финансов и инвестирования. Задача состоит в предсказании будущих изменений стоимости акции на основе исторических данных, таких как открытие и закрытие торгов, объемы торгов и другие показатели.\n",
"\n",
"Цель 2: Оценка волатильности акций компании.\n",
"Измерение волатильности позволяет инвесторам оценить риск и принять решения по управлению капиталом. Задача заключается в прогнозировании уровня волатильности на основе исторической динамики цен, объемов торгов и других рыночных факторов.\n",
"\n",
"#2. Цели технического проекта для каждой бизнес-цели\n",
"Цель 1: Прогнозирование изменения цены акции компании\n",
"\n",
"Разработать модель машинного обучения для прогнозирования будущих цен акций на основе исторических данных.\n",
"Использовать регрессионные модели, такие как линейная регрессия или более сложные модели, например, LSTM (долгосрочная краткосрочная память) для временных рядов.\n",
"Цель 2: Оценка волатильности акций компании\n",
"\n",
"Создать модель, которая будет прогнозировать волатильность на основе исторических данных о ценах.\n",
"Использовать методы статистического анализа, такие как вычисление стандартного отклонения, или методы машинного обучения для более точной оценки волатильности.\n",
"\n",
"#3 Проверим датасет на пропуски и удалим при необходимости строки с недостающими данными"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Обработка пропусков \n",
"Пропуски в данных могут негативно влиять на обучение моделей. Сначала оцениваем количество пропусков по столбцам. Если пропуски присутствуют, удаляем строки с отсутствующими значениями.\n"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Date 0\n",
"Open 0\n",
"High 0\n",
"Low 0\n",
"Close 0\n",
"Adj Close 0\n",
"Volume 0\n",
"dtype: int64\n",
"Данные после очистки: (5251, 7)\n"
]
}
],
"source": [
"# 3. Проверим датасет на наличие пропусков и удалим строки с недостающими данными\n",
"print(data.isnull().sum()) # Суммируем пропуски по каждому столбцу\n",
"data.dropna(inplace=True) # Удаляем строки с пропусками\n",
"print(\"Данные после очистки:\", data.shape)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Добавление признаков \n",
"Для выполнения задач добавляем два новых признака: \n",
"Daily_Change: разница между ценой закрытия и открытия торгов. \n",
"Volatility: относительная волатильность, рассчитываемая как отношение разницы между максимальной и минимальной ценой к цене открытия."
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Date 0\n",
"Open 0\n",
"High 0\n",
"Low 0\n",
"Close 0\n",
"Adj Close 0\n",
"Volume 0\n",
"dtype: int64\n",
"Количество строк после удаления пропусков: 5251\n"
]
2024-11-15 23:40:48 +04:00
}
],
"source": [
"print(data.isnull().sum()) # Вывод количества пропусков\n",
"data.dropna(inplace=True) # Удаление строк с пропущенными значениями\n",
"print(f\"Количество строк после удаления пропусков: {data.shape[0]}\")\n"
2024-11-15 23:40:48 +04:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Создание новых признаков "
2024-11-15 23:40:48 +04:00
]
},
{
"cell_type": "code",
"execution_count": 49,
2024-11-15 23:40:48 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" Daily_Change Volatility\n",
"0 0.0 0.0\n",
"1 0.0 0.0\n",
"2 0.0 0.0\n",
"3 0.0 0.0\n",
"4 0.0 0.0\n"
]
}
],
"source": [
2024-11-15 23:40:48 +04:00
"\n",
"data['Daily_Change'] = data['Close'] - data['Open']\n",
"data['Volatility'] = (data['High'] - data['Low']) / data['Open']\n",
"print(data[['Daily_Change', 'Volatility']].head())"
]
},
2024-11-15 23:40:48 +04:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Проведем масштабированние данных"
2024-11-15 23:40:48 +04:00
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [],
2024-11-15 23:40:48 +04:00
"source": [
"from sklearn.preprocessing import StandardScaler\n",
"\n",
"scaler = StandardScaler()\n",
"scaled_columns = ['Open', 'High', 'Low', 'Close', 'Volume']\n",
"data[scaled_columns] = scaler.fit_transform(data[scaled_columns])\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Разбиение данных на выборки \n",
"Для предотвращения просачивания данных используем разбиение на три части: \n",
"Обучающая выборка (60%): для тренировки модели. \n",
"Валидационная выборка (20%): для подбора гиперпараметров модели и проверки ее производительности на новых данных. \n",
"Тестовая выборка (20%): для оценки финальной производительности модели. "
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Размер обучающей выборки: (3150, 5)\n",
"Размер валидационной выборки: (1050, 5)\n",
"Размер тестовой выборки: (1051, 5)\n"
]
}
],
"source": [
"from sklearn.model_selection import train_test_split\n",
2024-11-15 23:40:48 +04:00
"\n",
"X = data[scaled_columns]\n",
"y = data['Close'] # Заменить на целевую переменную, если другая\n",
"X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.4, random_state=42)\n",
"X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)\n",
2024-11-15 23:40:48 +04:00
"\n",
"print(f\"Размер обучающей выборки: {X_train.shape}\")\n",
"print(f\"Размер валидационной выборки: {X_val.shape}\")\n",
"print(f\"Размер тестовой выборки: {X_test.shape}\")\n",
2024-11-15 23:40:48 +04:00
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Оценка и балансировка классов \n",
"Проверяем распределение классов в целевой переменной для каждого набора данных. Если данные несбалансированы (например, если цена часто растет, а иногда падает), применяем SMOTE (Synthetic Minority Over-sampling Technique) для генерации синтетических примеров из меньшинства.\n"
2024-11-15 23:40:48 +04:00
]
},
{
"cell_type": "code",
"execution_count": 52,
2024-11-15 23:40:48 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Проверка на пропуски после масштабирования:\n",
" Date 0\n",
"Open 0\n",
"High 0\n",
"Low 0\n",
"Close 0\n",
"Adj Close 0\n",
"Volume 0\n",
"Daily_Change 0\n",
"Volatility 0\n",
"dtype: int64\n"
2024-11-15 23:40:48 +04:00
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA1MAAAHWCAYAAACSWtPeAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABmH0lEQVR4nO3dfVwVdfr/8fcBDyDgQVFupLwh7zXLslSqTU2EzNpMt/ImMzNtDdvMVos2y5vK1Vy1G8tutTtr0+42MxXNbFM0My3vMmsRLeVGCVAROBzm90dfzq8jqIfxjAf09Xw8eOTMfOaaz1zMmbjOzHzGZhiGIQAAAABAtQT4uwMAAAAAUBtRTAEAAACACRRTAAAAAGACxRQAAAAAmEAxBQAAAAAmUEwBAAAAgAkUUwAAAABgAsUUAAAAAJhAMQUAAAAAJlBMAQBwGp588kmVl5dLksrLyzVt2jQ/9wjVsW3bNn300Ufu6S1btujTTz89I9ueNGmSbDbbGdkWAGtQTAHwsGDBAtlsNvdPSEiIWrdurTFjxig7O9vf3QNqnNdff10zZ87UL7/8on/96196/fXX/d0lVMPhw4d19913a/369dq9e7fuu+8+bd261at177jjDvXo0aPS/OLiYs2ePVtdu3ZVRESEx3n0xx9/9PEenL4ePXrojjvu8Hc3gFqpjr87AKBmmjJliuLj41VcXKyvvvpKL7zwgpYuXapt27YpNDTU390DaowpU6bo9ttv14MPPqjg4GC99dZb/u4SqiEhIcH9I0mtW7fWyJEjTcc7ePCgrr32Wm3atEnXX3+9Bg8erPDwcO3atUvvvvuuXnrpJZWWlvqq+wD8jGIKQJX69Omjyy67TJJ01113qWHDhpo1a5Y+/vhjDRo0yM+9A2qOW2+9VT179tRPP/2kVq1aKSoqyt9dQjV99NFH2rFjh44dO6aOHTsqKCjIdKw77rhDmzdv1uLFizVgwACPZVOnTtU//vGP0+0ugBqE2/wAeOWaa66RJGVkZEiS8vLy9Pe//10dO3ZUeHi4HA6H+vTpo++++67SusXFxZo0aZJat26tkJAQNW7cWP3799fPP/8sSdqzZ4/HrYXH//zxNpovvvhCNptN//73v/Xwww8rNjZWYWFh+vOf/6x9+/ZV2vaGDRt07bXXKiIiQqGhoerevbvWrl1b5T726NGjyu1PmjSpUtu33npLnTt3Vt26dRUZGamBAwdWuf2T7dsflZeXa86cOerQoYNCQkIUExOju+++W7/99ptHu+bNm+v666+vtJ0xY8ZUillV35966qlKOZWkkpISPfbYY2rZsqWCg4PVpEkTTZgwQSUlJVXm6o969OihCy+8sNL8mTNnymazac+ePR7z8/PzNXbsWDVp0kTBwcFq2bKlpk+f7n7u6I8qnik5/uf4W5J+/fVX3XnnnYqJiVFwcLA6dOig1157zaNNxbFT8RMcHKzWrVtr2rRpMgzDo+3mzZvVp08fORwOhYeHq1evXlq/fr1Hm4pbYvfs2aPo6GhdccUVatiwoS666CLZbDYtWLDgpHk7/pbaUx131dlHX34+Kn4H0dHRcjqdHsveeecdd38PHjzoseyzzz7Tn/70J4WFhalevXrq27evtm/f7tHmjjvuUHh4eKV+LV68WDabTV988YV7XnWPs+eff14dOnRQcHCw4uLilJKSovz8fI82PXr0cH8W2rdvr86dO+u7776r8jPqjQ0bNujTTz/ViBEjKhVSkhQcHKyZM2eeNEZZWZmmTp2qFi1aKDg4WM2bN9fDDz9c6bP4zTffKDk5WY0aNVLdunUVHx+vO++806ONt+cVAOZxZQqAVyoKn4YNG0qS/ve//+mjjz7SzTffrPj4eGVnZ+vFF19U9+7dtWPHDsXFxUmSXC6Xrr/+eq1atUoDBw7Ufffdp8OHDystLU3btm1TixYt3NsYNGiQrrvuOo/tpqamVtmfJ554QjabTQ8++KBycnI0Z84cJSYmasuWLapbt64k6fPPP1efPn3UuXNnPfbYYwoICND8+fN1zTXX6L///a+6dOlSKe7555/vHkDgyJEjGj16dJXbnjhxom655Rbdddddys3N1bPPPqurr75amzdvVv369SutM2rUKP3pT3+SJH3wwQf68MMPPZbffffdWrBggYYPH66//e1vysjI0HPPPafNmzdr7dq1stvtVeahOvLz86scHKG8vFx//vOf9dVXX2nUqFFq166dtm7dqtmzZ+vHH3/0eDj/dBUVFal79+769ddfdffdd6tp06Zat26dUlNTdeDAAc2ZM6fK9d588033v++//36PZdnZ2erWrZtsNpvGjBmjqKgoffbZZxoxYoQKCws1duxYj/YPP/yw2rVrp2PHjrmLjujoaI0YMUKStH37dv3pT3+Sw+HQhAkTZLfb9eKLL6pHjx5as2aNunbtesL9e/PNN71+3qZCxS21Fao67qq7j1Z8Pg4fPqwlS5bopptucs+bP3++QkJCVFxcXCkPw4YNU3JysqZPn66ioiK98MILuuqqq7R582Y1b968WjmqrkmTJmny5MlKTEzU6NGjtWvXLr3wwgvauHHjKT9PDz74oOnt/uc//5EkDR061HSMu+66S6+//rr+8pe/6IEHHtCGDRs0bdo07dy5033eyMnJUVJSkqKiovTQQw+pfv362rNnjz744AOPWGfivAKc8wwA+IP58+cbkoyVK1caubm5xr59+4x3333XaNiwoVG3bl3jl19+MQzDMIqLiw2Xy+WxbkZGhhEcHGxMmTLFPe+1114zJBmzZs2qtK3y8nL3epKMp556qlKbDh06GN27d3dPr1692pBknHfeeUZhYaF7/nvvvWdIMp5++ml37FatWhnJycnu7RiGYRQVFRnx8fFG7969K23riiuuMC688EL3dG5uriHJeOyxx9zz9uzZYwQGBhpPPPGEx7pbt2416tSpU2n+7t27DUnG66+/7p732GOPGX88/f73v/81JBlvv/22x7rLli2rNL9Zs2ZG3759K/U9JSXFOP6UfnzfJ0yYYERHRxudO3f2yOmbb75pBAQEGP/973891p83b54hyVi7dm2l7f1R9+7djQ4dOlSa/9RTTxmSjIyMDPe8qVOnGmFhYcaPP/7o0fahhx4yAgMDjb1793rM/8c//mHYbDaPec2aNTOGDRvmnh4xYoTRuHFj4+DBgx7tBg4caERERBhFRUWGYfz/Y2f16tXuNsXFxUZAQIBxzz33uOf169fPCAoKMn7++Wf3vP379xv16tUzrr76ave8is9Kxf4VFxcbTZs2Nfr06WNIMubPn185WX9Qsf7GjRs95ld13FV3H335+ag4XgcNGmRcf/317vmZmZlGQECAMWjQIEOSkZubaxiGYRw+fNioX7++MXLkSI++ZmVlGRERER7zhw0bZoSFhVXKzaJFiyr9rrw9znJycoygoCAjKSnJ4xz13HPPGZKM1157zSPmHz8LS5cuNSQZ1157baXPkzduuukmQ5Lx22+/edX++HPBli1bDEnGXXfd5dHu73//uyHJ+Pzzzw3DMIwPP/ywymPnj6pzXgFgHrf5AahSYmKioqKi1KRJEw0cOFDh4eH68MMPdd5550n6/XaVgIDfTyEul0uHDh1SeHi42rRpo2+//dYd5/3331ejRo107733VtrG6QwJfPvtt6tevXru6b/85S9q3Lixli5dKun34Y13796twYMH69ChQzp48KAOHjyoo0ePqlevXvryyy8r3VZWXFyskJCQk273gw8+UHl5uW655RZ3zIMHDyo2NlatWrXS6tWrPdpXPGgeHBx8wpiLFi1SRESEevfu7RGzc+fOCg8PrxTT6XR6tDt48GClKwPH+/XXX/Xss89q4sSJlW6rWrRokdq1a6e2bdt6xKy4tfP47Z+ORYsW6U9/+pMaNGjgsa3ExES5XC59+eWXHu1LS0tPmjvDMPT+++/rhhtukGEYHjGTk5NVUFDgcTxKUkFBgQ4ePKi9e/dqxowZKi8vd++ry+XSihUr1K9fP11wwQXudRo3bqzBgwfrq6++UmFhYZV9mTt3rg4dOqT
2024-11-15 23:40:48 +04:00
"text/plain": [
"<Figure size 1000x500 with 1 Axes>"
2024-11-15 23:40:48 +04:00
]
},
"metadata": {},
"output_type": "display_data"
2024-11-15 23:40:48 +04:00
}
],
"source": [
"from collections import Counter\n",
"from imblearn.over_sampling import SMOTE\n",
"\n",
"# Проверка на наличие пропусков после масштабирования\n",
"print(\"Проверка на пропуски после масштабирования:\\n\", data.isnull().sum())\n",
"\n",
"# Проверка распределения целевой переменной\n",
"import matplotlib.pyplot as plt\n",
"\n",
"plt.figure(figsize=(10, 5))\n",
"plt.hist(data['Close'], bins=30, edgecolor='k', alpha=0.7)\n",
"plt.title(\"Распределение целевой переменной 'Close'\")\n",
"plt.xlabel(\"Цена закрытия\")\n",
"plt.ylabel(\"Частота\")\n",
"plt.grid(True)\n",
"plt.show()"
2024-11-15 23:40:48 +04:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Создадим модель для прогназирования "
]
},
2024-11-15 23:40:48 +04:00
{
"cell_type": "code",
"execution_count": 53,
2024-11-15 23:40:48 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
2024-11-15 23:40:48 +04:00
"output_type": "stream",
"text": [
"\n",
"--- Прогнозирование цены акции ---\n"
2024-11-15 23:40:48 +04:00
]
}
],
"source": [
"from sklearn.linear_model import LinearRegression\n",
"from sklearn.metrics import mean_squared_error, r2_score\n",
2024-11-15 23:40:48 +04:00
"\n",
"# Модель для прогнозирования цены акции\n",
"print(\"\\n--- Прогнозирование цены акции ---\")\n",
"price_model = LinearRegression()\n",
"price_model.fit(X_train, y_train)\n",
2024-11-15 23:40:48 +04:00
"\n",
"# Предсказание на тестовой выборке\n",
"y_pred_price = price_model.predict(X_test)\n"
2024-11-15 23:40:48 +04:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Оценка модели"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Mean Squared Error (MSE): 0.0000\n",
"R^2 Score: 1.0000\n"
2024-11-15 23:40:48 +04:00
]
}
],
"source": [
"# Оценка модели\n",
"mse_price = mean_squared_error(y_test, y_pred_price)\n",
"r2_price = r2_score(y_test, y_pred_price)\n",
"print(f\"Mean Squared Error (MSE): {mse_price:.4f}\")\n",
"print(f\"R^2 Score: {r2_price:.4f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"MSE = 0.0000 и R² = 1.0000, это говорит о том, что ваша модель предсказывает данные абсолютно точно. (йоу)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Визуализируем полученный результат "
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {},
"outputs": [
2024-11-15 23:40:48 +04:00
{
2024-11-15 23:59:43 +04:00
"data": {
"image/png": "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
2024-11-15 23:59:43 +04:00
"text/plain": [
"<Figure size 1000x500 with 1 Axes>"
2024-11-15 23:59:43 +04:00
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Визуализация результатов прогноза\n",
"plt.figure(figsize=(10, 5))\n",
"plt.plot(y_test.values, label='Истинные значения', color='blue')\n",
"plt.plot(y_pred_price, label='Предсказанные значения', color='red')\n",
"plt.title(\"Прогнозирование цены акции\")\n",
"plt.xlabel(\"Наблюдения\")\n",
"plt.ylabel(\"Цена закрытия\")\n",
"plt.legend()\n",
"plt.grid(True)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"В целом, на основе этой диаграммы можно сделать вывод, что текущая модель не точно предсказывает цену акции"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Теперь сделаем все то же самое для волотильности "
]
},
{
"cell_type": "code",
"execution_count": 56,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"--- Оценка волатильности ---\n",
"Mean Squared Error (MSE) для волатильности: 0.0003\n",
"R^2 Score для волатильности: 0.6214\n"
]
}
],
"source": [
"# Модель для оценки волатильности\n",
"print(\"\\n--- Оценка волатильности ---\")\n",
"X_volatility = data[['High', 'Low', 'Open']] # Переменные для оценки волатильности\n",
"y_volatility = data['Volatility']\n",
"\n",
"# Разделение на выборки для модели волатильности\n",
"X_train_vol, X_test_vol, y_train_vol, y_test_vol = train_test_split(X_volatility, y_volatility, test_size=0.2, random_state=42)\n",
"\n",
"volatility_model = LinearRegression()\n",
"volatility_model.fit(X_train_vol, y_train_vol)\n",
2024-11-15 23:40:48 +04:00
"\n",
"# Предсказание на тестовой выборке\n",
"y_pred_volatility = volatility_model.predict(X_test_vol)\n",
2024-11-15 23:40:48 +04:00
"\n",
"# Оценка модели волатильности\n",
"mse_volatility = mean_squared_error(y_test_vol, y_pred_volatility)\n",
"r2_volatility = r2_score(y_test_vol, y_pred_volatility)\n",
"print(f\"Mean Squared Error (MSE) для волатильности: {mse_volatility:.4f}\")\n",
"print(f\"R^2 Score для волатильности: {r2_volatility:.4f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"MSE = 0.0003 и R² = 0.6214 говорят о том, что модель делает предсказания с малой ошибкой, но есть еще пространство для улучшения, поскольку она объясняет менее 70% вариации в данных."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Визуализируем "
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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atXwyCOPYMOGDcjJyfF7vZmZmbL/c3NzZe9v3boV58+fx5AhQxAbG+ucfuedd6Jx48b47bffZPObzWZkZmbi0KFDmDBhAvR6PW655RbFdUuShJEjR+Lee+/1aBUqzu1y+fJlZGZm4vDhw/jggw8QERGBjh07Ot+Pi4tzvjYYDMjMzMRNN90EANi+fbtHGS9duiTbhtnZ2YrfRTRy5Ei0bNkS999/v2z6ihUrkJWVhYcffli2zIiICNx4441Ys2aNz2X7+o5nzpxBRkYGBgwYIGuBvP7669GlSxcsWbLEY3kmkwkxMTFe1ylut9zcXGRmZqJ9+/bIz8/H/v37NZVbzalTp/DRRx/hjTfeUO1qp6WMDo7tqtTi5+A4lsX/3ed3bKvhw4fLpr/44osA4Px9rFixArm5uXjllVdkvyMARW7B1LJtiKjsYlc9Iip3rr76ao9pjRo1Qn5+Pi5cuAAAyM/PxzXXXOMxX5MmTWCz2XDixAk0bdpU8zrz8vJQpUoVr/McO3YMABTX27hxY2zYsEE2bdWqVejRowcAIDk5GT/88IMz6HD39ddfY8+ePfj++++d4zzcFcd2admypfN1TEwMPv74Y1lXwkuXLmHs2LH47rvvcP78edkylYIipXV7s2HDBvzyyy9YtWoVjh8/Lnvv4MGDAIDbb79d8bPJycma1uHtO3rbp02aNMHvv/+OvLw8JCQkOKdnZ2f7rJTv2bMHr7/+OlavXu0RrGoJJr0ZPXo0qlevjieffBI//PCD4jxZWVmaAgf3475WrVp48cUX8dxzz8nmW758uabfh16vR8OGDWXT09LSkJKS4tzWhw4dAoBieRSBlm1DRGUXAyciohIQGxuLX375RTZt/fr1ePPNNwNeZps2bbBixQpcvnwZ8+bNw8CBA1GrVi2PDIMmkwlvvPEGBg0ahEaNGgW8vkDMmzcPVatWhcFgwOrVqzF06FDExsZiwIABAIAHHngAf/75J/73v/+hRYsWSExMhM1mQ/fu3WGz2TyW9+OPP8oCmn///RdDhw5VXf+IESPQrVs33H777bIEEgCcy587dy7S0tI8PhsZqe0S6es7+uPSpUswmUyK5XHIyspCx44dkZycjDfffBMNGjRAbGwstm/fjhEjRihuN6327duH2bNnY968eYiKilKd7+zZs6hTp47P5YnHfW5uLr788ks8//zzqFatGh544AHnfDfeeCPefvtt2Wc//vhjLF682GOZwRr35i+t24aIyi4GTkRU7jhaGkT//vsv4uPjnXe94+PjceDAAY/59u/fD71ej1q1avm1zoiICGeyAIesrCzZ346K6IEDBzxaQQ4cOOBRUb3qqqucy7z33ntxzTXXYNKkSZg/f75svk8//RTnz5/3yAzmrji2yy233OJMfnDXXXdhz549GD9+PAYMGIDLly9j1apVGDt2LEaNGuW1HA4dOnRA5cqVnX87kmUoWbRoETZt2qTY5Q8AGjRoAABITU312Df+8PYdxX3qbv/+/ahcubKstWnv3r0A7K1RatauXYuLFy/ip59+QocOHZzTjxw5EvB3cBg5ciRatGiBBx98UHUes9mM//77D927d/e5PPfj/s4770SlSpWwbNkyWeBUuXJlj33gniWyTp06sNlsOHjwoGz7nDt3DllZWc5t7div//zzj0f
"text/plain": [
"<Figure size 1000x500 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Визуализация результатов прогноза волатильности\n",
"plt.figure(figsize=(10, 5))\n",
"plt.plot(y_test_vol.values, label='Истинные значения волатильности', color='green')\n",
"plt.plot(y_pred_volatility, label='Предсказанные значения волатильности', color='orange')\n",
"plt.title(\"Прогнозирование волатильности\")\n",
"plt.xlabel(\"Наблюдения\")\n",
"plt.ylabel(\"Волатильность\")\n",
"plt.legend()\n",
"plt.grid(True)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"По этой модели же можно сказать, что она более точно предсказывает, то есть она получилась более правильной "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Теперь воспользуемся фреймворком Featuretools"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Generated feature columns: Index(['open', 'high', 'low', 'close', 'Adj Close', 'volume', 'DAY(datetime)',\n",
" 'MONTH(datetime)', 'YEAR(datetime)'],\n",
" dtype='object')\n",
"Размер обучающей выборки: (3150, 5)\n",
"Размер валидационной выборки: (1050, 5)\n",
"Размер тестовой выборки: (1051, 5)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"c:\\Users\\alexk\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\featuretools\\synthesis\\deep_feature_synthesis.py:169: UserWarning: Only one dataframe in entityset, changing max_depth to 1 since deeper features cannot be created\n",
" warnings.warn(\n",
"c:\\Users\\alexk\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\featuretools\\synthesis\\dfs.py:321: UnusedPrimitiveWarning: Some specified primitives were not used during DFS:\n",
" agg_primitives: ['mean', 'sum']\n",
"This may be caused by a using a value of max_depth that is too small, not setting interesting values, or it may indicate no compatible columns for the primitive were found in the data. If the DFS call contained multiple instances of a primitive in the list above, none of them were used.\n",
" warnings.warn(warning_msg, UnusedPrimitiveWarning)\n"
]
}
],
"source": [
"# Импорт библиотек для работы с Featuretools\n",
"import featuretools as ft\n",
"import pandas as pd\n",
"from sklearn.preprocessing import StandardScaler\n",
"from sklearn.model_selection import train_test_split\n",
"import woodwork as ww\n",
"\n",
"\n",
"# Проверим и удалим дублирующиеся столбцы\n",
"if not data.columns.is_unique:\n",
" print(\"Обнаружены дублирующиеся столбцы. Переименуем их.\")\n",
" data = data.loc[:, ~data.columns.duplicated()] \n",
"\n",
"# Переименование столбцов для совместимости с Featuretools\n",
"data = data.rename(columns={'Date': 'datetime', 'Open': 'open', 'High': 'high', \n",
" 'Low': 'low', 'Close': 'close', 'Volume': 'volume'})\n",
"\n",
"# Создание EntitySet\n",
"es = ft.EntitySet(id=\"stocks\")\n",
"\n",
"# Добавление данных в EntitySet с правильными логическими типами\n",
"es = es.add_dataframe(\n",
" dataframe_name=\"stock_data\",\n",
" dataframe=data,\n",
" index=\"datetime\", \n",
" # Убираем time_index, так как datetime уже используется как индекс\n",
" logical_types={\n",
" \"open\": ww.logical_types.Double, \n",
" \"high\": ww.logical_types.Double,\n",
" \"low\": ww.logical_types.Double,\n",
" \"close\": ww.logical_types.Double,\n",
" \"volume\": ww.logical_types.Double,\n",
" },\n",
")\n",
"\n",
"# Автоматическое создание признаков с использованием Featuretools\n",
"feature_matrix, feature_defs = ft.dfs(\n",
" entityset=es,\n",
" target_dataframe_name=\"stock_data\",\n",
" agg_primitives=[\"mean\", \"sum\"], \n",
" trans_primitives=[\"day\", \"month\", \"year\"] \n",
")\n",
"\n",
"# Выводим имена столбцов в feature_matrix, чтобы убедиться, какие признаки были сгенерированы\n",
"print(\"Generated feature columns:\", feature_matrix.columns)\n",
"\n",
"# Объединяем новые признаки с исходными данными, добавив суффиксы для дублирующихся столбцов\n",
"data_featuretools = data.join(feature_matrix, lsuffix='_orig', rsuffix='_feature')\n",
"\n",
"# Масштабирование данных\n",
"scaler = StandardScaler()\n",
"\n",
"# Используем правильные имена столбцов для масштабирования\n",
"scaled_columns = ['open_orig', 'high_orig', 'low_orig', 'close_orig', 'volume_orig']\n",
"\n",
"data_featuretools[scaled_columns] = scaler.fit_transform(data_featuretools[scaled_columns])\n",
"\n",
"# Разделение данных на выборки\n",
"\n",
"feature_columns = [col for col in feature_matrix.columns if 'feature' in col]\n",
"X = data_featuretools[scaled_columns + feature_columns]\n",
"y = data_featuretools['close_orig'] # Целевая переменная\n",
"\n",
"X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.4, random_state=42)\n",
"X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)\n",
2024-11-15 23:59:43 +04:00
"\n",
"print(f\"Размер обучающей выборки: {X_train.shape}\")\n",
"print(f\"Размер валидационной выборки: {X_val.shape}\")\n",
"print(f\"Размер тестовой выборки: {X_test.shape}\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}