{"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":"Predict demand by removing seasonality. This provides better accuracy than the naive prediction.","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport os\n\nPATH_CSV = '/kaggle/input/applications-of-deep-learning-wustlfall-2022/beach_demand_forecast/'\n\ndf_sales_train = pd.read_csv(os.path.join(PATH_CSV,\"sales_train.csv\"))\ndf_items = pd.read_csv(os.path.join(PATH_CSV,\"items.csv\"))\ndf_resturant = pd.read_csv(os.path.join(PATH_CSV,\"resturants.csv\"))\ndf_sales_test = pd.read_csv(os.path.join(PATH_CSV,\"sales_test.csv\"))\n\ndf_sales_train.date = pd.to_datetime(df_sales_train.date, errors='coerce') \ndf_sales_test.date = pd.to_datetime(df_sales_test.date, errors='coerce') ","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-10-29T23:07:07.645676Z","iopub.execute_input":"2022-10-29T23:07:07.646022Z","iopub.status.idle":"2022-10-29T23:07:07.826065Z","shell.execute_reply.started":"2022-10-29T23:07:07.645946Z","shell.execute_reply":"2022-10-29T23:07:07.824822Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Begin by producing a line graph of all sales over the provided 3-year timespan.","metadata":{}},{"cell_type":"code","source":"import plotly.express as px\n\ndf_plot = df_sales_train[['date','item_count']].groupby(['date']).mean().reset_index()\nfig = px.line(df_plot, x=\"date\", y=\"item_count\", title='RAW Sales by Date')\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:07.827353Z","iopub.execute_input":"2022-10-29T23:07:07.827671Z","iopub.status.idle":"2022-10-29T23:07:08.932834Z","shell.execute_reply.started":"2022-10-29T23:07:07.827640Z","shell.execute_reply":"2022-10-29T23:07:08.931811Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Detrending\n\nCan you see an overall trend in this data? Beyond just the seasonality?","metadata":{}},{"cell_type":"code","source":"from scipy import signal\n\ndf_plot.item_count = signal.detrend(df_plot.item_count)\n\nfig = px.line(df_plot, x=\"date\", y=\"item_count\", title='RAW Sales by Date')\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:08.934075Z","iopub.execute_input":"2022-10-29T23:07:08.934409Z","iopub.status.idle":"2022-10-29T23:07:09.385032Z","shell.execute_reply.started":"2022-10-29T23:07:08.934378Z","shell.execute_reply":"2022-10-29T23:07:09.383959Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from scipy import signal\n\ndf_plot.item_count = signal.detrend(df_plot.item_count)\n\nfig = px.line(df_plot, x=\"date\", y=\"item_count\", title='RAW Sales by Date')\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:09.388061Z","iopub.execute_input":"2022-10-29T23:07:09.388406Z","iopub.status.idle":"2022-10-29T23:07:09.470367Z","shell.execute_reply.started":"2022-10-29T23:07:09.388374Z","shell.execute_reply":"2022-10-29T23:07:09.469272Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## De-Seasoning\n\nLets remove the seasonality.","metadata":{}},{"cell_type":"code","source":"from statsmodels.tsa.seasonal import seasonal_decompose\nfrom matplotlib import pyplot\n\ndf_plot = df_sales_train[['date','item_count']].groupby(['date']).mean()\n\n# extrapolate_trend='freq',\nadjustment = seasonal_decompose(df_plot.item_count, model='multiplicative') # , model='additive', period=7\n\n# multiplicative\n# additive\n\nadjustment.plot()\npyplot.show()","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:09.472040Z","iopub.execute_input":"2022-10-29T23:07:09.472706Z","iopub.status.idle":"2022-10-29T23:07:10.245851Z","shell.execute_reply.started":"2022-10-29T23:07:09.472664Z","shell.execute_reply":"2022-10-29T23:07:10.244717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Notice how the yearly seasonality was detected as the trend? The weekly seasonality was detected as seasonal. Without zooming you cannot see the ups and downs of the individual days of the week.","metadata":{}},{"cell_type":"code","source":"adjustment.trend","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:10.247427Z","iopub.execute_input":"2022-10-29T23:07:10.247895Z","iopub.status.idle":"2022-10-29T23:07:10.259068Z","shell.execute_reply.started":"2022-10-29T23:07:10.247852Z","shell.execute_reply":"2022-10-29T23:07:10.257759Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"adjustment.seasonal","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:10.260689Z","iopub.execute_input":"2022-10-29T23:07:10.261441Z","iopub.status.idle":"2022-10-29T23:07:10.273831Z","shell.execute_reply.started":"2022-10-29T23:07:10.261393Z","shell.execute_reply":"2022-10-29T23:07:10.272273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Resulting Dataset\nLets see the dataset \"flattened\".","metadata":{}},{"cell_type":"code","source":"df_plot2 = df_plot.copy()\n\ndf_plot2.item_count = df_plot2.item_count / adjustment.seasonal / adjustment.trend\n\nfig = px.line(df_plot2.reset_index(), x=\"date\", y=\"item_count\", title='RAW Sales by Date')\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:10.275316Z","iopub.execute_input":"2022-10-29T23:07:10.275712Z","iopub.status.idle":"2022-10-29T23:07:10.356244Z","shell.execute_reply.started":"2022-10-29T23:07:10.275680Z","shell.execute_reply":"2022-10-29T23:07:10.355271Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_adjustment = pd.DataFrame(adjustment.seasonal)\ndf_adjustment['trend'] = adjustment.trend\n\ndf_adjustment","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:10.357917Z","iopub.execute_input":"2022-10-29T23:07:10.358896Z","iopub.status.idle":"2022-10-29T23:07:10.378894Z","shell.execute_reply.started":"2022-10-29T23:07:10.358855Z","shell.execute_reply":"2022-10-29T23:07:10.377903Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We will save the adjustment table to a binary pickle form, so we can later reload it exactly as it is. We will make use of this table during day 2.","metadata":{}},{"cell_type":"code","source":"df_adjustment.to_pickle(\"adjustment.pkl\")","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:10.379967Z","iopub.execute_input":"2022-10-29T23:07:10.380292Z","iopub.status.idle":"2022-10-29T23:07:10.385632Z","shell.execute_reply.started":"2022-10-29T23:07:10.380264Z","shell.execute_reply":"2022-10-29T23:07:10.384782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Convert All Items\nNow that we've estimated seasonality and trend for the average of all items, we must apply this to the individual items.","metadata":{}},{"cell_type":"code","source":"df_sales_adj = df_sales_train.merge(df_adjustment,right_index=True,left_on=\"date\")\ndf_sales_adj.dropna(inplace=True)\ndf_sales_adj['adjust'] = df_sales_adj.item_count / df_sales_adj.seasonal / df_sales_adj.trend","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:10.386567Z","iopub.execute_input":"2022-10-29T23:07:10.387080Z","iopub.status.idle":"2022-10-29T23:07:10.429956Z","shell.execute_reply.started":"2022-10-29T23:07:10.387047Z","shell.execute_reply":"2022-10-29T23:07:10.428756Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Compare the individual item plot to the previous example with seasonality still embeded.","metadata":{}},{"cell_type":"code","source":"SINGLE_YEAR = 2020\n\ndf_sales_single_year = df_sales_adj[df_sales_train['date'].dt.year == SINGLE_YEAR]\ndf_plot = df_sales_single_year[['date','item_id','adjust']].groupby(['date','item_id']).mean().reset_index()\ndf_plot = df_plot.merge(df_items,left_on=\"item_id\",right_on=\"id\")[['date','adjust','name']]\nfig = px.bar(df_plot, x='date', y='adjust',color=\"name\", title=f'Item Sales by Date - {SINGLE_YEAR}')\nfig.update_layout(bargap=0.0,bargroupgap=0.0)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:10.431436Z","iopub.execute_input":"2022-10-29T23:07:10.432619Z","iopub.status.idle":"2022-10-29T23:07:11.781156Z","shell.execute_reply.started":"2022-10-29T23:07:10.432583Z","shell.execute_reply":"2022-10-29T23:07:11.780046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model with Adjusted Data\nNow lets model, with this mostly cleaned up data.\n\nUtility function to create sequences.","metadata":{}},{"cell_type":"code","source":"def series_to_supervised(data, window=1, lag=1, dropnan=True):\n    cols, names = list(), list()\n    # Input sequence (t-n, ... t-1)\n    for i in range(window, 0, -1):\n        cols.append(data.shift(i))\n        names += [('%s(t-%d)' % (col, i)) for col in data.columns]\n    # Current timestep (t=0)\n    cols.append(data)\n    names += [('%s(t)' % (col)) for col in data.columns]\n    # Target timestep (t=lag)\n    cols.append(data.shift(-lag))\n    names += [('%s(t+%d)' % (col, lag)) for col in data.columns]\n    # Put it all together\n    agg = pd.concat(cols, axis=1)\n    agg.columns = names\n    # Drop rows with NaN values\n    if dropnan:\n        agg.dropna(inplace=True)\n    return agg","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:11.785746Z","iopub.execute_input":"2022-10-29T23:07:11.786601Z","iopub.status.idle":"2022-10-29T23:07:11.798037Z","shell.execute_reply.started":"2022-10-29T23:07:11.786552Z","shell.execute_reply":"2022-10-29T23:07:11.797117Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We will link the season and trend adjustments.","metadata":{}},{"cell_type":"code","source":"df_items2 = df_items[['id','store_id']]\ndf_train = df_sales_adj.merge(df_items2,left_on='item_id',right_on='id')\ndf_train[['date','item_id','adjust','store_id','item_count','seasonal','trend']]\n\ndf_train = df_train.sort_values('date').groupby(['item_id', 'store_id', 'date'], as_index=False)\ndf_train = df_train.agg({'adjust':['mean'],'item_count':['mean'],'seasonal':['mean'],'trend':['mean']})\ndf_train.columns = ['item', 'store', 'date', 'adjust', 'item_count', 'seasonal', 'trend']\ndf_train.head()","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:11.799479Z","iopub.execute_input":"2022-10-29T23:07:11.800030Z","iopub.status.idle":"2022-10-29T23:07:11.948773Z","shell.execute_reply.started":"2022-10-29T23:07:11.799998Z","shell.execute_reply":"2022-10-29T23:07:11.947726Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Lets also engineer two features. This gives the neural network some information about what day of the week and day of the year we are in. Ideally, these are not needed with seasonality generally removed; however, if some seasonality and trend remain, maybe these two features help the neural network to overcome.","metadata":{}},{"cell_type":"code","source":"df_train['dow'] = df_train['date'].dt.dayofweek\ndf_train['doy'] = df_train['date'].dt.dayofyear\ndf_train","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:11.950438Z","iopub.execute_input":"2022-10-29T23:07:11.950761Z","iopub.status.idle":"2022-10-29T23:07:11.993154Z","shell.execute_reply.started":"2022-10-29T23:07:11.950730Z","shell.execute_reply":"2022-10-29T23:07:11.992098Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Build the sequence data.","metadata":{}},{"cell_type":"code","source":"window = 29\nfuture_span = 30\nseries = series_to_supervised(df_train.drop('date', axis=1), window=window, lag=future_span)\nseries.head()","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:11.994397Z","iopub.execute_input":"2022-10-29T23:07:11.994785Z","iopub.status.idle":"2022-10-29T23:07:12.679410Z","shell.execute_reply.started":"2022-10-29T23:07:11.994756Z","shell.execute_reply":"2022-10-29T23:07:12.678315Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Remove sequences that did not have enough data.","metadata":{}},{"cell_type":"code","source":"# Remove edge cases, where there were not enough values to complete a series\nlast_item = 'item(t-%d)' % window\nlast_store = 'store(t-%d)' % window\nlast_dow = 'dow(t-%d)' % window\nlast_doy = 'doy(t-%d)' % window\nseries = series[(series['store(t)'] == series[last_store])]\nseries = series[(series['item(t)'] == series[last_item])]","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:12.680897Z","iopub.execute_input":"2022-10-29T23:07:12.681259Z","iopub.status.idle":"2022-10-29T23:07:12.888374Z","shell.execute_reply.started":"2022-10-29T23:07:12.681227Z","shell.execute_reply":"2022-10-29T23:07:12.887478Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We will predict with adjusted sales, and our engineered features.","metadata":{}},{"cell_type":"code","source":"import numpy as np\nfrom keras.utils.np_utils import to_categorical   \n\ndef drop_column(df, col):\n  columns_to_drop = [('%s(t+%d)' % (col, future_span))]\n  for i in range(window, 0, -1):\n      columns_to_drop += [('%s(t-%d)' % (col, i))]\n  df.drop(columns_to_drop, axis=1, inplace=True, errors='ignore')\n  df.drop([f\"{col}(t)\"], axis=1, inplace=True, errors='ignore')\n\ndef cat_seq(df, col):\n  return to_categorical(df[col].values)\n\n# Label\nlabels_col = 'adjust(t+%d)' % future_span\nlabels = series[labels_col]\nseries.drop(labels_col, axis=1, inplace=True)\nseries.drop('item(t+%d)' % future_span, axis=1, inplace=True)\nseries.drop('store(t+%d)' % future_span, axis=1, inplace=True)\nseries.drop('dow(t+%d)' % future_span, axis=1, inplace=True)\nseries.drop('doy(t+%d)' % future_span, axis=1, inplace=True)\n\n# Adjustment columns\nunadjust_sales_col = 'item_count(t+%d)' % future_span\nseasonal_col = 'seasonal(t+%d)' % future_span\ntrend_col = 'trend(t+%d)' % future_span\n\nhold_sales = series[unadjust_sales_col]\nhold_seasonal = series[seasonal_col]\nhold_trend = series[trend_col]\n\nseries.drop(unadjust_sales_col, axis=1, inplace=True)\nseries.drop(seasonal_col, axis=1, inplace=True)\nseries.drop(trend_col, axis=1, inplace=True)\n\n\n# Get sales sequences\nseries2 = series.copy()\ndrop_column(series2, \"item\")\ndrop_column(series2, \"store\")\ndrop_column(series2, \"dow\")\ndrop_column(series2, \"doy\")\nsales_series = series2.values\n\n# Day of week as a categorical\nseries2 = series.copy()\ndrop_column(series2, \"item\")\ndrop_column(series2, \"store\")\ndrop_column(series2, \"doy\")\ndrop_column(series2, \"adjust\")\ndow_series = series2.values\n\n# Get item sequences\nseries2 = series.copy()\ndrop_column(series2, \"item\")\ndrop_column(series2, \"store\")\ndrop_column(series2, \"dow\")\ndrop_column(series2, \"adjust\")\ndoy_series = series2.values\n\n# Day of year\nt1 = sales_series.reshape(sales_series.shape + (1,))\nt2 = dow_series.reshape(dow_series.shape + (1,)) \nt3 = doy_series.reshape(doy_series.shape + (1,))\nx = np.concatenate([t1,t2,t3],axis=2)","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:12.889691Z","iopub.execute_input":"2022-10-29T23:07:12.890571Z","iopub.status.idle":"2022-10-29T23:07:16.303920Z","shell.execute_reply.started":"2022-10-29T23:07:12.890536Z","shell.execute_reply":"2022-10-29T23:07:16.302890Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Double check that all input data is of the same shape.","metadata":{}},{"cell_type":"code","source":"print(t1.shape)\nprint(t2.shape)\nprint(t3.shape)","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:16.305563Z","iopub.execute_input":"2022-10-29T23:07:16.309165Z","iopub.status.idle":"2022-10-29T23:07:16.315870Z","shell.execute_reply.started":"2022-10-29T23:07:16.309110Z","shell.execute_reply":"2022-10-29T23:07:16.314683Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Extract the predictors (x sequences) and the label (future prediction)","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\n# Split the training data into training and validation\ndata = np.arange(len(x))\ny = labels.values\nnp.random.shuffle(data)\nsplit_pt = int(len(data) * 0.2)\nx_valid = x[data[:split_pt]]\nx_train = x[data[split_pt:]]\ny_valid = y[data[:split_pt]]\ny_train = y[data[split_pt:]]\n\n# Also split the seasonality/trend data\ny_train_actual = hold_sales.iloc[data[split_pt:]]\ny_valid_actual = hold_sales.iloc[data[:split_pt]]\n\ny_train_seasonal = hold_seasonal.iloc[data[split_pt:]]\ny_valid_seasonal = hold_seasonal.iloc[data[:split_pt]]\n\ny_train_trend = hold_trend.iloc[data[split_pt:]]\ny_valid_trend = hold_trend.iloc[data[:split_pt]]\n\n# Display results\nprint('Train set shape', x_train.shape)\nprint('Validation set shape', x_valid.shape)","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:16.317140Z","iopub.execute_input":"2022-10-29T23:07:16.318043Z","iopub.status.idle":"2022-10-29T23:07:17.190724Z","shell.execute_reply.started":"2022-10-29T23:07:16.318008Z","shell.execute_reply":"2022-10-29T23:07:17.189748Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Final preparation for the x and y.","metadata":{}},{"cell_type":"code","source":"print('Train set shape', x_train.shape)\nprint('Validation set shape', y_valid.shape)","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:17.192129Z","iopub.execute_input":"2022-10-29T23:07:17.192448Z","iopub.status.idle":"2022-10-29T23:07:17.198506Z","shell.execute_reply.started":"2022-10-29T23:07:17.192421Z","shell.execute_reply":"2022-10-29T23:07:17.197267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Construct the neural network.","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf \nfrom keras.models import Sequential, Model\nfrom keras.layers.convolutional import Conv1D, MaxPooling1D\nfrom keras.layers import Dense, LSTM, RepeatVector, TimeDistributed, Flatten, Dropout\nimport keras\n\nepochs = 500\nbatch = 256\nlr = 0.0003\nadam = tf.keras.optimizers.Adam(lr)\n\nmodel = Sequential()\nmodel.add(Conv1D(filters=64, kernel_size=8, activation='relu', input_shape=(x_train.shape[1], x_train.shape[2])))\nmodel.add(MaxPooling1D(pool_size=2))\nmodel.add(Flatten())\nmodel.add(Dense(50, activation='relu'))\nmodel.add(Dropout(0.2))\nmodel.add(Dense(1))\nmodel.compile(loss='mse', optimizer=adam)\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:17.200596Z","iopub.execute_input":"2022-10-29T23:07:17.202119Z","iopub.status.idle":"2022-10-29T23:07:17.334911Z","shell.execute_reply.started":"2022-10-29T23:07:17.202078Z","shell.execute_reply":"2022-10-29T23:07:17.333839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Fit the neural network.","metadata":{}},{"cell_type":"code","source":"from keras.callbacks import EarlyStopping\n\nmonitor = EarlyStopping(monitor='val_loss', min_delta=1e-3, patience=5, \n        verbose=1, mode='auto', restore_best_weights=True)\n\ncnn_history = model.fit(x_train, y_train, callbacks=[monitor],\n    validation_data=(x_valid, y_valid), epochs=epochs, verbose=2)","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:07:17.336088Z","iopub.execute_input":"2022-10-29T23:07:17.336407Z","iopub.status.idle":"2022-10-29T23:09:55.697976Z","shell.execute_reply.started":"2022-10-29T23:07:17.336379Z","shell.execute_reply":"2022-10-29T23:09:55.696910Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nfig = plt.figure()\nplt.plot(cnn_history.history['loss'], label='Train loss')\nplt.plot(cnn_history.history['val_loss'], label='Validation loss')\nfig.legend()\nfig.suptitle('CNN')\nplt.xlabel(\"Epochs\")\nplt.ylabel(\"MSE\")\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:09:55.699649Z","iopub.execute_input":"2022-10-29T23:09:55.700084Z","iopub.status.idle":"2022-10-29T23:09:55.928314Z","shell.execute_reply.started":"2022-10-29T23:09:55.700051Z","shell.execute_reply":"2022-10-29T23:09:55.927168Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import mean_squared_error \nimport numpy as np\n\ncnn_train_pred = model.predict(x_train) \ncnn_valid_pred = model.predict(x_valid) \nprint('Train rmse:', np.sqrt(mean_squared_error(y_train, cnn_train_pred))) \nprint('Validation rmse:', np.sqrt(mean_squared_error(y_valid, cnn_valid_pred)))","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:20:26.253975Z","iopub.execute_input":"2022-10-29T23:20:26.254426Z","iopub.status.idle":"2022-10-29T23:20:31.289827Z","shell.execute_reply.started":"2022-10-29T23:20:26.254377Z","shell.execute_reply":"2022-10-29T23:20:31.288991Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cnn_train_pred2 = cnn_train_pred.flatten() * y_train_seasonal * y_train_trend\ncnn_valid_pred2 = cnn_valid_pred.flatten() * y_valid_seasonal * y_valid_trend\n\nprint('Train rmse:', np.sqrt(mean_squared_error(y_train_actual, cnn_train_pred2)))\nprint('Validation rmse:', np.sqrt(mean_squared_error(y_valid_actual, cnn_valid_pred2)))","metadata":{"execution":{"iopub.status.busy":"2022-10-29T23:21:10.992774Z","iopub.execute_input":"2022-10-29T23:21:10.993803Z","iopub.status.idle":"2022-10-29T23:21:11.005563Z","shell.execute_reply.started":"2022-10-29T23:21:10.993757Z","shell.execute_reply":"2022-10-29T23:21:11.004275Z"},"trusted":true},"execution_count":null,"outputs":[]}]}