{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Линейная регрессия" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Набор данных содержит информацию о затратах на рекламу (в тыс $) для разных типов медиа: __TV__, __Radio__, __Newspaper__.\n", " \n", "Результат __Sales__ показывает сколько товаров продано в связи с каждым каналом рекламы (в тыс штук). Собрано 200 наблюдений (рядов). " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# прочитаем данные из файла в датафрейм pandas\n", "import pandas as pd\n", "\n", "example_path = \"./advertising.csv\"\n", "advertising = pd.read_csv(example_path).drop(['Unnamed: 0'], axis=1) # удалим индекс из csv\n", "print(advertising)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Построим точечный график с помощью графика pandas" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\n", "advertising.plot.scatter(x='TV', y='Sales', title='Peклaмa TB')\n", "advertising.plot.scatter(x='Radio', y='Sales', title='Peклaмa Радио')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Построим график с помощью фреймворка matplotlib" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "%matplotlib inline\n", "# словарь цветов {Class:color(HEX coded)}\n", "colors = {'TV':'#8fcfd1', 'Radio':'#df5e88', 'Newspaper':'#f6ab6c'}\n", "\n", "# выберем X\n", "X = advertising[['TV', 'Radio', 'Newspaper']]\n", "# выберем y\n", "y = advertising['Sales']\n", "\n", "# реорганизуем колонки\n", "columns = advertising.columns.drop(['Sales'])\n", "# диапазон x (0 to #rows)\n", "x_data = range(0, advertising.shape[0])\n", "# создадим фигуру 800x600 для графика\n", "fig, ax = plt.subplots(figsize=(8,6))\n", "# построим точечные графики\n", "ax.scatter(x=advertising['TV'], y=advertising['Sales'], color='gold')\n", "ax.scatter(x=advertising['Radio'], y=advertising['Sales'], color='grey')\n", "# заголовок\n", "ax.set_title('Peклaмa- TB / Радио')\n", "# названия осей\n", "ax.set_xlabel('затраты')\n", "ax.set_ylabel('продажи')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Линейная регрессия\n", "\n", "$y = \\beta_0 + \\beta_1x_1 + \\beta_2x_2 + ... + \\beta_nx_n + \\epsilon $\n", "\n", "- $y$ это отклик\n", "- $\\beta_0$ это пересечение (intercept)\n", "- $\\beta_1$ это коэффициент для $x_1$ фактора \n", "- $\\beta_n$ это коэффициент для $x_n$ фактора\n", "- $\\epsilon$ это ошибка модели\n", "\n", "Получаем уравнение:\n", "\n", "$y = \\beta_0 + \\beta_1 \\times TV + \\beta_2 \\times Radio + \\beta_3 \\times Newspaper + \\epsilon$\n", "\n", "здесь $\\beta$ значения называются **коэффициенты модели**. Эти значения вычисляются по критерию наименьших квадратов ошибки (LSE). \n", "\n", "После подбора коэффициентов можно пробовать сделать прогноз по тренду.\n", "\n", "Для вычисления коэффициентов можно подключить \n", "- библиотеку numpy\n", "\n", "// Функция polyfit — функция в библиотеке NumPy, которая подгоняет многочлен заданного порядка к набору точек данных с помощью метода наименьших квадратов.\n", "\n", "//Функция poly1d создаёт полиномиальную функцию, которую можно использовать для оценки значений многочлена в любой позиции x или построения графика.\n", "\n", "- или библиотеку фреймворка [`sklearn.linear_model.LinearRegression()`](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html#sklearn.linear_model.LinearRegression).\n", "\n", "В sklearn можно получить такое уравнение: $y = 2.88 + 0.0466 \\times TV + 0.179 \\times Radio + 0.00345 \\times Newspaper + \\epsilon$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", "xtv=advertising['TV']\n", "y=advertising['Sales']\n", "\n", "fig, ax = plt.subplots(figsize=(8,6))\n", "# установим вид осей графика\n", "ax.tick_params(direction='in', top=True, right=True)\n", "# рассчитаем линейную регрессию\n", "coefficients = np.polyfit(xtv, y, deg=1) # наклон, смещение\n", "# создадим функцию тренда\n", "p = np.poly1d(coefficients)\n", "# построим точечный график исходных данных\n", "ax.scatter(xtv, y, label='данные')\n", "# построим график тренда\n", "ax.plot(xtv, p(xtv), label='линейный тренд', color='red')\n", "# добавим текстовую информацию на график\n", "stats = (f'$\\\\mu$ = {np.mean(y):.2f}\\n'\n", " f'$\\\\sigma$ = {np.std(y):.2f}\\n'\n", " f'$r$ = {np.corrcoef(xtv, y)[0][1]:.2f}\\n'\n", " f'$y$ = {coefficients[1]:.3f}*x+{coefficients[0]:.3f}' )\n", "# оформим легенду графика\n", "bbox = dict(boxstyle='round', fc='blanchedalmond', ec='orange', alpha=0.5)\n", "ax.text(0.95, 0.07, stats, fontsize=9, bbox=bbox,\n", " transform=ax.transAxes, horizontalalignment='right')\n", "pass # заглушка вывода сообщения предыдущего оператора" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "Нарисуем диаграмму матрицы корреляций с помощью библиотеки matplotlib в виде 2D-карты (imshow)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#import numpy as np\n", "# матрица корреляций (Correlation matrix)\n", "corr = advertising.corr()\n", "fig, ax = plt.subplots(figsize=(6,6))\n", "\n", "# тепловая карта (Heatmap)\n", "im = ax.imshow(corr.values, cmap='cividis_r', vmin=0, vmax=1)\n", "\n", "# названия по осям\n", "ax.set_xticks(np.arange(len(corr.columns)))\n", "ax.set_yticks(np.arange(len(corr.columns)))\n", "ax.set_xticklabels(corr.columns)\n", "ax.set_yticklabels(corr.columns)\n", "print(corr.values)\n", "# повернем текст на оси x для наглядности\n", "plt.setp(ax.get_xticklabels(), rotation=45, ha=\"right\", rotation_mode=\"anchor\")\n", "pass" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Рассмотрим и построим нелинейную зависимость, например, кубический тренд." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Perform cubic fit\n", "coefficients = np.polyfit(xtv, y, 3)\n", "print(\"коэффициенты полинома 3й степени:\", coefficients)\n", "print(f'Уравнение тренда = {coefficients[0]:.4f} * X^3 +{coefficients[1]:.4f} * X^2 + {coefficients[2]:.4f} * X + {coefficients[3]:.4f}')\n", "\n", "# создадим функцию тренда\n", "polynomial = np.poly1d(coefficients)\n", "# отрисуем данные\n", "plt.scatter(xtv, y, label='данные', color='pink')\n", "# подготовим список из 100 точек по x\n", "xp = np.linspace(0, 300, 100)\n", "# построим кубический тренд\n", "plt.plot(xp, polynomial(xp), label='кубический тренд', color='lime')\n", "plt.legend()\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Для получения прогноза по известной функции тренда надо подставить новое знчение x в функцию." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x_new = [330]\n", "y_new = polynomial(x_new)\n", "print(y_new)" ] } ], "metadata": { "kernelspec": { "display_name": "env1", "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.7" } }, "nbformat": 4, "nbformat_minor": 2 }