{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Линейная регрессия" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Набор данных содержит информацию о затратах на рекламу (в тыс $) для разных типов медиа: __TV__, __Radio__, __Newspaper__. \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", "# создадим фигуру для графика\n", "fig, ax = plt.subplots(figsize=(8,6))\n", "# построим точечные графики\n", "ax.scatter(x=advertising['TV'], y=advertising['Sales'])\n", "ax.scatter(x=advertising['Radio'], y=advertising['Sales'], color='gold')\n", "# заголовок\n", "ax.set_title('Peклaмa TB Радио')\n", "# названия осей\n", "ax.set_xlabel('затраты')\n", "ax.set_ylabel('продажи')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# отрисуем точечные графики с помощью seaborn\n", "import seaborn as sns\n", "sns.set(style=\"ticks\", color_codes=True)\n", "\n", "# https://seaborn.pydata.org/generated/seaborn.pairplot.html\n", "sns.pairplot(advertising, x_vars=['TV','Radio','Newspaper'], y_vars='Sales', height=6, aspect=1., kind='reg')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "здесь использована опция `kind='reg'` этого графика [`sns.pairplot()`](https://seaborn.pydata.org/generated/seaborn.pairplot.html) для визуализации регрессии датасета. " ] }, { "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$ значения называются **коэффициенты модели**. Эти значения вычисляются по критерию наименьших квадратов ошибки. После подбора коэффициентов можно пробовать сделать прогноз по тренду. \n", "Для вычисления коэффициентов можно подключить \n", "- библиотеку numpy\n", "- библиотеку фреймворка [`sklearn.linear_model.LinearRegression()`](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html#sklearn.linear_model.LinearRegression).\n", "\n", "Например можно получить такое уравнение: $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", "ax.tick_params(direction='in', top=True, right=True)\n", "ax.plot(xtv, y, 'o')\n", "# рассчитаем линейную регрессию\n", "p1, p0 = np.polyfit(xtv, y, deg=1) # наклон, смещение\n", "ax.axline(xy1=(0, p0), slope=p1, color='r', lw=2)\n", "\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$ = {round(p1,3)}*x+{round(p0,3)}' )\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", "# повернем текст для наглядности\n", "plt.setp(ax.get_xticklabels(), rotation=45, ha=\"right\", rotation_mode=\"anchor\")\n", "pass" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Тестовые данные Анскомба\n", "Можно получить готовые данные датасета Анскомба из фреймворка seaborn. \n", "\n", "Датасет содержит 44 ряда и 3 колонки пар значений `x`,`y` и поле `dataset` с индексом (`I/II/III/IV`). " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#import pandas as pd\n", "#import seaborn as sns\n", "\n", "pd.set_option(\"max_rows\", 8) # покажем только 8 рядов\n", "anscome_df = sns.load_dataset(\"anscombe\") # загрим данные из готового датасета anscombe\n", "anscome_df['x'] = anscome_df['x'].astype(float)\n", "anscome_df['y'] = anscome_df['y'].astype(float)\n", "anscome_df # покажем данные" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Графики по данным Анскомба\n", "\n", "Построим каждую группу точек (облако точек) дискретным графиком scatter из [matplotlib](https://matplotlib.org/3.2.1/api/_as_gen/matplotlib.pyplot.scatter.html) и используем сетку подграфиков из [seaborn](https://seaborn.pydata.org/tutorial/axis_grids.html). " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#import matplotlib.pyplot as plt # import pyplot to create scatter plots\n", "sns.set(style=\"ticks\")\n", "\n", "g = sns.FacetGrid(anscome_df, col=\"dataset\", hue=\"dataset\") # зададим сетку для графиков\n", "g.map(plt.scatter, \"x\", \"y\", alpha=.7) # отобразим графики в сетку" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "anscome_dataset_labels = anscome_df['dataset'].unique() # labels for each dataset\n", "\n", "# First, compute mean\n", "anscome_mean_of_xy = {q: anscome_df[anscome_df['dataset'] == q].mean() for q in anscome_dataset_labels}\n", "\n", "# Second, compute variances \n", "anscome_var_of_xy = {q: anscome_df[anscome_df['dataset'] == q].var() for q in anscome_dataset_labels}\n", "\n", "# Third, compute correlation between x and y\n", "anscome_corr_of_xy = {q: anscome_df[anscome_df['dataset'] == q]['x'].corr(anscome_df[anscome_df['dataset'] == q]['y']) for q in anscome_dataset_labels}\n", "\n", "# Show statistics\n", "print(\"Anscombe's quartet statistics\")\n", "pd.concat([pd.DataFrame.from_dict(anscome_mean_of_xy).rename({\"x\": \"среднее x\", \"y\": \"среднее y\"}),\n", " pd.DataFrame.from_dict(anscome_var_of_xy).rename({\"x\": \"дисперсия x\", \"y\": \"дисперсия y\"}),\n", " pd.DataFrame({k: [v] for k, v in anscome_corr_of_xy.items()}).rename({0: \"корреляция x и y\"})])" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3.7.6 64-bit", "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.7.6" }, "vscode": { "interpreter": { "hash": "aaea06cd2337f3f1a8255382ee5a8ce2e63ade4be3aa94187189b8da1d3aff1f" } } }, "nbformat": 4, "nbformat_minor": 2 }