{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# FPProphet. Практика\nВ этом ноутбуке мы попытаемся прогнозировать данные по транзакциям с использованием библиотеки пророк\n\nЗагрузим библиотеки и данные (будем использовать для удобства оригинальный датасет с соревнования  Corporación Favorita Grocery Sales Forecastingg). Для этого придется эти данные разархивировать в рабочую директорию","metadata":{}},{"cell_type":"code","source":"\nimport os\n!pip install pyunpack\n!pip install patool\nos.system('apt-get install p7zip')\n\n\nfrom pyunpack import Archive\nimport shutil","metadata":{"execution":{"iopub.status.busy":"2021-12-19T23:01:55.012247Z","iopub.execute_input":"2021-12-19T23:01:55.012795Z","iopub.status.idle":"2021-12-19T23:02:19.667585Z","shell.execute_reply.started":"2021-12-19T23:01:55.012668Z","shell.execute_reply":"2021-12-19T23:02:19.666693Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        Archive(os.path.join(dirname, filename)).extractall('/kaggle/working/')\n        print(os.path.join(dirname, filename))","metadata":{"execution":{"iopub.status.busy":"2021-12-19T23:02:19.671128Z","iopub.execute_input":"2021-12-19T23:02:19.671415Z","iopub.status.idle":"2021-12-19T23:03:37.756975Z","shell.execute_reply.started":"2021-12-19T23:02:19.671380Z","shell.execute_reply":"2021-12-19T23:03:37.755708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Приведите данные train.csv к виду временного ряда, сгруппированного по дате, с агрегирующей функцией sum() для столбца unit_sales. \n# У вас должен получиться временной ряд с двумя столбцами: дата и sum_unit_sales. Отобразите на графике. \n# Видно ли влияние сезонности и других факторов на количество покупок?","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np \nimport pandas as pd \n# optimize memory loading by specifying the data types...\ndtypes = {'id':'uint32', 'item_nbr':'int32', 'store_nbr':'int8', 'onpromotion':str}\ntrain_df = pd.read_csv('./train.csv', dtype=dtypes, parse_dates=['date'])\n# Если мы посмотрим на данные транзакций, транзакции сгруппированы по номерам магазинов. \n# Сейчас мы упростим это и сгруппируем их по дате. \ndf = train_df.groupby(\"date\")['unit_sales'].sum()\ndf.to_csv('./all_transactions.csv')","metadata":{"execution":{"iopub.status.busy":"2021-12-19T17:58:07.379645Z","iopub.execute_input":"2021-12-19T17:58:07.380493Z","iopub.status.idle":"2021-12-19T17:59:53.015163Z","shell.execute_reply.started":"2021-12-19T17:58:07.380438Z","shell.execute_reply":"2021-12-19T17:59:53.014019Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load libraries\nimport numpy as np\nRANDOM_SEED = 42\nnp.random.seed(RANDOM_SEED)\nimport pandas as pd\npd.set_option('display.max_rows', 10)\npd.set_option('display.max_columns', 70)\nimport plotly.offline as py\nimport plotly.graph_objs as go\npy.init_notebook_mode()\n\nfrom fbprophet import Prophet\n\n%time df_transactions = pd.read_csv('./all_transactions.csv')\n%time df_holidays_events = pd.read_csv('./holidays_events.csv')\n\nprint('Data and libraries are loaded.')\ndf_transactions.head()","metadata":{"_cell_guid":"8622f914-bf69-49bb-9cc2-4d2fa4d26a32","_uuid":"00e60bd44272ef95cb68aab3fac252880a8a4d28","execution":{"iopub.status.busy":"2021-12-19T18:32:17.880683Z","iopub.execute_input":"2021-12-19T18:32:17.881035Z","iopub.status.idle":"2021-12-19T18:32:17.967479Z","shell.execute_reply.started":"2021-12-19T18:32:17.880997Z","shell.execute_reply":"2021-12-19T18:32:17.966645Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_transactions = df_transactions.set_index(pd.DatetimeIndex(df_transactions['date'])).drop(columns=['date'])\ndf_transactions.head()","metadata":{"execution":{"iopub.status.busy":"2021-12-19T18:32:19.698389Z","iopub.execute_input":"2021-12-19T18:32:19.699405Z","iopub.status.idle":"2021-12-19T18:32:19.711824Z","shell.execute_reply.started":"2021-12-19T18:32:19.699358Z","shell.execute_reply":"2021-12-19T18:32:19.711254Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transactions = df_transactions['unit_sales']\npy.iplot([go.Scatter(\n    x=transactions.index,\n    y=transactions\n)])","metadata":{"execution":{"iopub.status.busy":"2021-12-19T18:34:16.755998Z","iopub.execute_input":"2021-12-19T18:34:16.756935Z","iopub.status.idle":"2021-12-19T18:34:16.879602Z","shell.execute_reply.started":"2021-12-19T18:34:16.756887Z","shell.execute_reply":"2021-12-19T18:34:16.878392Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Хорошо заметно влияние сезонности и праздников на общий объем транзакций.","metadata":{}},{"cell_type":"markdown","source":"Теперь давайте попробуем библиотеку пророк и посмотрим, насколько хорошо она предсказывает. Но перед этим мы должны подготовить данные. Согласно документации:\n\n> Prophet следует API модели sklearn. Мы создаем экземпляр класса Prophet, а затем вызываем его методы соответствия и прогнозирования.\n> Входными данными для Prophet всегда является фрейм данных с двумя столбцами: ** ds ** и ** y **. Столбец ds (отметка даты) должен содержать дату или дату и время (это нормально). Столбец ** y ** должен быть числовым и представлять измерение, которое мы хотим спрогнозировать.","metadata":{}},{"cell_type":"code","source":"transactions = pd.DataFrame(transactions).reset_index()\ntransactions.columns = ['ds', 'y']\ntransactions","metadata":{"execution":{"iopub.status.busy":"2021-12-19T18:34:33.215289Z","iopub.execute_input":"2021-12-19T18:34:33.215560Z","iopub.status.idle":"2021-12-19T18:34:33.232986Z","shell.execute_reply.started":"2021-12-19T18:34:33.215532Z","shell.execute_reply":"2021-12-19T18:34:33.232073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Попробуйте выполнить предсказание пророком (prophet) на год вперёд (periods=365). Отобразите на графике. Посчитайте RSME.","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"m = Prophet()\nm.fit(transactions)\nfuture = m.make_future_dataframe(periods=365)\nforecast = m.predict(future)\nforecast","metadata":{"execution":{"iopub.status.busy":"2021-12-19T18:34:41.087596Z","iopub.execute_input":"2021-12-19T18:34:41.088220Z","iopub.status.idle":"2021-12-19T18:34:48.006339Z","shell.execute_reply.started":"2021-12-19T18:34:41.088166Z","shell.execute_reply":"2021-12-19T18:34:48.005741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"py.iplot([\n    go.Scatter(x=transactions['ds'], y=transactions['y'], name='y'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat'], name='yhat'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat_upper'], fill='tonexty', mode='none', name='upper'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat_lower'], fill='tonexty', mode='none', name='lower'),\n    go.Scatter(x=forecast['ds'], y=forecast['trend'], name='Trend')\n])","metadata":{"execution":{"iopub.status.busy":"2021-12-19T18:35:07.026923Z","iopub.execute_input":"2021-12-19T18:35:07.027632Z","iopub.status.idle":"2021-12-19T18:35:07.564951Z","shell.execute_reply.started":"2021-12-19T18:35:07.027595Z","shell.execute_reply":"2021-12-19T18:35:07.564267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Вычислим среднеквадратичную ошибку.\nprint('RMSE: %f' % np.sqrt(np.mean((forecast.loc[:1682, 'yhat']-transactions['y'])**2)) )","metadata":{"execution":{"iopub.status.busy":"2021-12-19T18:35:14.745628Z","iopub.execute_input":"2021-12-19T18:35:14.746703Z","iopub.status.idle":"2021-12-19T18:35:14.758770Z","shell.execute_reply.started":"2021-12-19T18:35:14.746626Z","shell.execute_reply":"2021-12-19T18:35:14.757556Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Как видно на графике выше, прогноз довольно хороший и согласуется с взлетами и падениями данных. Вы можете увеличить график, выбрав область масштабирования с помощью мыши.\n\nНо тенденция довольно жесткая, она не учитывает под-тренды середины года. В первой половине года тенденция нарастает, а затем немного замедляется. Сделаем тренд немного гибким. Если тренд является переобученным (слишком большая гибкость) или недостаточными (недостаточная гибкость), вы можете отрегулировать силу разреженности перед использованием входного аргумента ** changepoint_prior_scale **. По умолчанию этот параметр установлен на 0,05. Его увеличение сделает тренд более гибким. (https://facebook.github.io/prophet/docs/trend_changepoints.html)","metadata":{}},{"cell_type":"code","source":"# Поэкспериментируйте с коэффициентом changepoint_prior_scale (переберите 3-5 значений, больше/меньше 0,5) и посмотрите, как изменится тренд. \n# В какую сторону необходимо двигать коэффициент? Тренд переобучен или недообучен?","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"m = Prophet(changepoint_prior_scale=0.1)\nm.fit(transactions)\nfuture = m.make_future_dataframe(periods=365)\nforecast = m.predict(future)\n# Вычислим среднеквадратичную ошибку.\nprint('RMSE: %f' % np.sqrt(np.mean((forecast.loc[:1682, 'yhat']-transactions['y'])**2)) )\npy.iplot([\n    go.Scatter(x=transactions['ds'], y=transactions['y'], name='y'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat'], name='yhat'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat_upper'], fill='tonexty', mode='none', name='upper'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat_lower'], fill='tonexty', mode='none', name='lower'),\n    go.Scatter(x=forecast['ds'], y=forecast['trend'], name='Trend')\n])","metadata":{"execution":{"iopub.status.busy":"2021-12-19T18:43:14.959069Z","iopub.execute_input":"2021-12-19T18:43:14.959601Z","iopub.status.idle":"2021-12-19T18:43:20.803357Z","shell.execute_reply.started":"2021-12-19T18:43:14.959566Z","shell.execute_reply":"2021-12-19T18:43:20.802130Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"m = Prophet(changepoint_prior_scale=0.25)\nm.fit(transactions)\nfuture = m.make_future_dataframe(periods=365)\nforecast = m.predict(future)\n# Вычислим среднеквадратичную ошибку.\nprint('RMSE: %f' % np.sqrt(np.mean((forecast.loc[:1682, 'yhat']-transactions['y'])**2)) )\npy.iplot([\n    go.Scatter(x=transactions['ds'], y=transactions['y'], name='y'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat'], name='yhat'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat_upper'], fill='tonexty', mode='none', name='upper'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat_lower'], fill='tonexty', mode='none', name='lower'),\n    go.Scatter(x=forecast['ds'], y=forecast['trend'], name='Trend')\n])","metadata":{"execution":{"iopub.status.busy":"2021-12-19T18:45:13.801625Z","iopub.execute_input":"2021-12-19T18:45:13.802217Z","iopub.status.idle":"2021-12-19T18:45:19.749758Z","shell.execute_reply.started":"2021-12-19T18:45:13.802152Z","shell.execute_reply":"2021-12-19T18:45:19.748851Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"m = Prophet(changepoint_prior_scale=0.5)\nm.fit(transactions)\nfuture = m.make_future_dataframe(periods=365)\nforecast = m.predict(future)\n# Вычислим среднеквадратичную ошибку.\nprint('RMSE: %f' % np.sqrt(np.mean((forecast.loc[:1682, 'yhat']-transactions['y'])**2)) )\npy.iplot([\n    go.Scatter(x=transactions['ds'], y=transactions['y'], name='y'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat'], name='yhat'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat_upper'], fill='tonexty', mode='none', name='upper'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat_lower'], fill='tonexty', mode='none', name='lower'),\n    go.Scatter(x=forecast['ds'], y=forecast['trend'], name='Trend')\n])","metadata":{"execution":{"iopub.status.busy":"2021-12-19T18:45:34.637362Z","iopub.execute_input":"2021-12-19T18:45:34.637646Z","iopub.status.idle":"2021-12-19T18:45:41.514212Z","shell.execute_reply.started":"2021-12-19T18:45:34.637613Z","shell.execute_reply":"2021-12-19T18:45:41.513279Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"m = Prophet(changepoint_prior_scale=1)\nm.fit(transactions)\nfuture = m.make_future_dataframe(periods=365)\nforecast = m.predict(future)\n# Вычислим среднеквадратичную ошибку.\nprint('RMSE: %f' % np.sqrt(np.mean((forecast.loc[:1682, 'yhat']-transactions['y'])**2)) )\npy.iplot([\n    go.Scatter(x=transactions['ds'], y=transactions['y'], name='y'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat'], name='yhat'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat_upper'], fill='tonexty', mode='none', name='upper'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat_lower'], fill='tonexty', mode='none', name='lower'),\n    go.Scatter(x=forecast['ds'], y=forecast['trend'], name='Trend')\n])","metadata":{"execution":{"iopub.status.busy":"2021-12-19T18:45:56.449503Z","iopub.execute_input":"2021-12-19T18:45:56.449771Z","iopub.status.idle":"2021-12-19T18:46:03.771320Z","shell.execute_reply.started":"2021-12-19T18:45:56.449743Z","shell.execute_reply":"2021-12-19T18:46:03.770442Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"m = Prophet(changepoint_prior_scale=1.5)\nm.fit(transactions)\nfuture = m.make_future_dataframe(periods=365)\nforecast = m.predict(future)\n# Вычислим среднеквадратичную ошибку.\nprint('RMSE: %f' % np.sqrt(np.mean((forecast.loc[:1682, 'yhat']-transactions['y'])**2)) )\npy.iplot([\n    go.Scatter(x=transactions['ds'], y=transactions['y'], name='y'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat'], name='yhat'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat_upper'], fill='tonexty', mode='none', name='upper'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat_lower'], fill='tonexty', mode='none', name='lower'),\n    go.Scatter(x=forecast['ds'], y=forecast['trend'], name='Trend')\n])","metadata":{"execution":{"iopub.status.busy":"2021-12-19T18:46:14.664648Z","iopub.execute_input":"2021-12-19T18:46:14.664936Z","iopub.status.idle":"2021-12-19T18:46:22.145131Z","shell.execute_reply.started":"2021-12-19T18:46:14.664901Z","shell.execute_reply":"2021-12-19T18:46:22.143881Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Отобразите результаты с подобранным коэффициентом на графике. Как изменилась ошибка?","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"m = Prophet(changepoint_prior_scale=2.5)\nm.fit(transactions)\nfuture = m.make_future_dataframe(periods=365)\nforecast = m.predict(future)","metadata":{"execution":{"iopub.status.busy":"2021-12-19T18:50:33.300377Z","iopub.execute_input":"2021-12-19T18:50:33.300718Z","iopub.status.idle":"2021-12-19T18:50:40.348667Z","shell.execute_reply.started":"2021-12-19T18:50:33.300681Z","shell.execute_reply":"2021-12-19T18:50:40.347609Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Вычислим среднеквадратичную ошибку.\nprint('RMSE: %f' % np.sqrt(np.mean((forecast.loc[:1682, 'yhat']-transactions['y'])**2)) )\npy.iplot([\n    go.Scatter(x=transactions['ds'], y=transactions['y'], name='y'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat'], name='yhat'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat_upper'], fill='tonexty', mode='none', name='upper'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat_lower'], fill='tonexty', mode='none', name='lower'),\n    go.Scatter(x=forecast['ds'], y=forecast['trend'], name='Trend')\n])","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-12-19T18:50:40.350294Z","iopub.execute_input":"2021-12-19T18:50:40.350539Z","iopub.status.idle":"2021-12-19T18:50:40.880356Z","shell.execute_reply.started":"2021-12-19T18:50:40.350509Z","shell.execute_reply":"2021-12-19T18:50:40.879469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Проэкспериментировав с значением 'changepoint_prior_scale' in [0.1, 0.25, 0.5, 1, 1.5, 2.5]  можно отметить как с ростом значения 'changepoint_prior_scale' улучшалась \"гибкость\" тренда и уменьшалась недообученность модели. Ошибка RMSE уменьшилась с ростом значения 'changepoint_prior_scale'.","metadata":{}},{"cell_type":"code","source":"# Добавьте в модель месячную сезонность (name='monthly', period=30.5, fourier_order=5). \n# Как изменилась ошибка? Улучшилась ли модель? Отобразите на графике. Посчитайте ошибку.","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Теперь добавим в модель больше сезонности. Как мы видим, Пророк рассчитывает еженедельную и годовую сезонность. Нам не нужна ежедневная сезонность, потому что у нас нет внутридневных данных для этого случая. Достаточно просто добавить ежемесячную сезонность.","metadata":{}},{"cell_type":"code","source":"m = Prophet(changepoint_prior_scale=2.5)\nm.add_seasonality(name='monthly', period=30.5, fourier_order=5)\nm.fit(transactions)\nfuture = m.make_future_dataframe(periods=365)\nforecast = m.predict(future)","metadata":{"execution":{"iopub.status.busy":"2021-12-19T18:49:17.550348Z","iopub.execute_input":"2021-12-19T18:49:17.550686Z","iopub.status.idle":"2021-12-19T18:49:24.566053Z","shell.execute_reply.started":"2021-12-19T18:49:17.550655Z","shell.execute_reply":"2021-12-19T18:49:24.565399Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Вычислим среднеквадратичную ошибку.\nprint('RMSE: %f' % np.sqrt(np.mean((forecast.loc[:1682, 'yhat']-transactions['y'])**2)) )\npy.iplot([\n    go.Scatter(x=transactions['ds'], y=transactions['y'], name='y'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat'], name='yhat'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat_upper'], fill='tonexty', mode='none', name='upper'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat_lower'], fill='tonexty', mode='none', name='lower'),\n    go.Scatter(x=forecast['ds'], y=forecast['trend'], name='Trend')\n])","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-12-19T18:49:25.489318Z","iopub.execute_input":"2021-12-19T18:49:25.489603Z","iopub.status.idle":"2021-12-19T18:49:26.043512Z","shell.execute_reply.started":"2021-12-19T18:49:25.489567Z","shell.execute_reply":"2021-12-19T18:49:26.042851Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Добавление сезонности в модель улучшило модель и существенно сократило ошибку!","metadata":{}},{"cell_type":"code","source":"# Улучшите модель добавлением данных о праздниках. Отобразите результат, сделайте письменный вывод.","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Пришло время добавить в нашу модель влияние праздников. Сначала нам нужно настроить формат данных. Пророку нужны два столбца (праздник и ds) и строка для каждого наступления праздника. Так же можно включить столбцы lower_window и upper_window, которые продлевают праздничные дни до дней «[lower_window, upper_window]» вокруг даты. ","metadata":{}},{"cell_type":"code","source":"df_holidays_events","metadata":{"execution":{"iopub.status.busy":"2021-12-19T18:37:01.018587Z","iopub.execute_input":"2021-12-19T18:37:01.019621Z","iopub.status.idle":"2021-12-19T18:37:01.042162Z","shell.execute_reply.started":"2021-12-19T18:37:01.019570Z","shell.execute_reply":"2021-12-19T18:37:01.040728Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"holidays = df_holidays_events[df_holidays_events['transferred'] == False][['description', 'date']]\nholidays.columns = ['holiday', 'ds']\n#holidays['lower_window'] = 0\n#holidays['upper_window'] = 0\nholidays","metadata":{"execution":{"iopub.status.busy":"2021-12-19T18:37:12.786537Z","iopub.execute_input":"2021-12-19T18:37:12.786958Z","iopub.status.idle":"2021-12-19T18:37:12.801130Z","shell.execute_reply.started":"2021-12-19T18:37:12.786929Z","shell.execute_reply":"2021-12-19T18:37:12.800161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"m = Prophet(changepoint_prior_scale=2.5, holidays=holidays)\nm.add_seasonality(name='monthly', period=30.5, fourier_order=5)\nm.fit(transactions)\nfuture = m.make_future_dataframe(periods=365)\nforecast = m.predict(future)","metadata":{"execution":{"iopub.status.busy":"2021-12-19T18:37:20.067635Z","iopub.execute_input":"2021-12-19T18:37:20.067893Z","iopub.status.idle":"2021-12-19T18:37:33.000493Z","shell.execute_reply.started":"2021-12-19T18:37:20.067865Z","shell.execute_reply":"2021-12-19T18:37:32.999316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Вычислим среднеквадратичную ошибку.\nprint('RMSE: %f' % np.sqrt(np.mean((forecast.loc[:1682, 'yhat']-transactions['y'])**2)) )\npy.iplot([\n    go.Scatter(x=transactions['ds'], y=transactions['y'], name='y'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat'], name='yhat'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat_upper'], fill='tonexty', mode='none', name='upper'),\n    go.Scatter(x=forecast['ds'], y=forecast['yhat_lower'], fill='tonexty', mode='none', name='lower'),\n    go.Scatter(x=forecast['ds'], y=forecast['trend'], name='Trend')\n])","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-12-19T18:37:33.002595Z","iopub.execute_input":"2021-12-19T18:37:33.002959Z","iopub.status.idle":"2021-12-19T18:37:33.544004Z","shell.execute_reply.started":"2021-12-19T18:37:33.002908Z","shell.execute_reply":"2021-12-19T18:37:33.542812Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Нам удалось спрогнозировать всплески на новогодний период. Модель не смогла уловить резкий скачок вниз на 4 января 2016 года, поэтому она не смогла успешно спрогнозировать 1 января 2017 года. \nЭто объясняется тем, что 4 января 2016 года не было выходных. Но модель хорошо предсказывает продажи на 24 декабря. А также прогнозируемый период после 15 августа 2017 года выглядит неплохо.\n### Добавление праздников в модель еще сильнее улучшило модель и сократило ошибку.","metadata":{}}]}