{"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":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport pandas as pd\nimport numpy as np\nimport time\nimport gc\n\n# from sklearn.linear_model import RidgeCV, Ridge\n# from sklearn.metrics import mean_squared_error\nfrom sklearn.preprocessing import StandardScaler\n# from sklearn.model_selection import train_test_split\n\nfrom lightgbm import LGBMRegressor\n# from xgboost import XGBRegressor\nfrom sklearn.model_selection import TimeSeriesSplit\nfrom scipy.stats.stats import pearsonr\nfrom tqdm import tqdm\n\nimport gresearch_crypto\n\n# Warningの無効化\nimport warnings\nwarnings.simplefilter(\"ignore\")\n\n# データフレームcolumの全表示\npd.set_option(\"display.max_columns\", None)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-05-20T19:16:54.995613Z","iopub.execute_input":"2022-05-20T19:16:54.995908Z","iopub.status.idle":"2022-05-20T19:16:55.009121Z","shell.execute_reply.started":"2022-05-20T19:16:54.995879Z","shell.execute_reply":"2022-05-20T19:16:55.008295Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Load Data","metadata":{}},{"cell_type":"code","source":"def reduce_mem_usage(df):\n    \"\"\" iterate through all the columns of a dataframe and modify the data type\n        to reduce memory usage.        \n    \"\"\"\n    start_mem = df.memory_usage().sum() / 1024**2\n    print(\"Memory usage of dataframe is {:.2f} MB\".format(start_mem))\n    \n    for col in df.columns:\n        col_type = df[col].dtype\n        \n        if col_type != object:\n            c_min = df[col].min()\n            c_max = df[col].max()\n            if str(col_type)[:3] == \"int\":\n                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:\n                    df[col] = df[col].astype(np.int8)\n                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:\n                    df[col] = df[col].astype(np.int16)\n                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:\n                    df[col] = df[col].astype(np.int32)\n                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:\n                    df[col] = df[col].astype(np.int64)  \n            else:\n                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:\n                    df[col] = df[col].astype(np.float16)\n                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:\n                    df[col] = df[col].astype(np.float32)\n                else:\n                    df[col] = df[col].astype(np.float64)\n        # else:\n            # df[col] = df[col].astype('category')\n\n    end_mem = df.memory_usage().sum() / 1024**2\n    print(\"Memory usage after optimization is: {:.2f} MB\".format(end_mem))\n    print(\"Decreased by {:.1f}%\".format(100 * (start_mem - end_mem) / start_mem))\n    \n    return df","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:16:55.010594Z","iopub.execute_input":"2022-05-20T19:16:55.010921Z","iopub.status.idle":"2022-05-20T19:16:55.026354Z","shell.execute_reply.started":"2022-05-20T19:16:55.010890Z","shell.execute_reply":"2022-05-20T19:16:55.025482Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_asset_details = pd.read_csv(r\"/kaggle/input/g-research-crypto-forecasting/asset_details.csv\").sort_values(\"Asset_ID\")\ndf_asset_details","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:16:55.031597Z","iopub.execute_input":"2022-05-20T19:16:55.031871Z","iopub.status.idle":"2022-05-20T19:16:55.054997Z","shell.execute_reply.started":"2022-05-20T19:16:55.031841Z","shell.execute_reply":"2022-05-20T19:16:55.054083Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# val = df_asset_details.loc[ df_asset_details[\"Asset_ID\"] == 3, \"Asset_Name\"]\n# val.values[0]","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:16:55.056865Z","iopub.execute_input":"2022-05-20T19:16:55.057178Z","iopub.status.idle":"2022-05-20T19:16:55.061592Z","shell.execute_reply.started":"2022-05-20T19:16:55.057144Z","shell.execute_reply":"2022-05-20T19:16:55.060791Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def read_csv_strict(file_name=r\"/kaggle/input/g-research-crypto-forecasting/train.csv\"):\n    df = pd.read_csv(file_name).pipe(reduce_mem_usage)\n    df[\"datetime\"] = pd.to_datetime(df[\"timestamp\"], unit=\"s\")\n#     df = df[df[\"datetime\"] > \"2019-06-13 00:00:00\"]\n    df = df[df[\"datetime\"] >= \"2020-05-13 00:00:00\"]\n    return df","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:16:55.062865Z","iopub.execute_input":"2022-05-20T19:16:55.063350Z","iopub.status.idle":"2022-05-20T19:16:55.073901Z","shell.execute_reply.started":"2022-05-20T19:16:55.063304Z","shell.execute_reply":"2022-05-20T19:16:55.073237Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = read_csv_strict(file_name=r\"/kaggle/input/g-research-crypto-forecasting/supplemental_train.csv\")\ndf_train.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:16:55.075263Z","iopub.execute_input":"2022-05-20T19:16:55.076200Z","iopub.status.idle":"2022-05-20T19:16:59.307559Z","shell.execute_reply.started":"2022-05-20T19:16:55.076165Z","shell.execute_reply":"2022-05-20T19:16:59.306765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_supp_train = read_csv_strict(file_name=r\"/kaggle/input/g-research-crypto-forecasting/supplemental_train.csv\")\ndf_supp_train.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:16:59.309265Z","iopub.execute_input":"2022-05-20T19:16:59.310055Z","iopub.status.idle":"2022-05-20T19:17:03.590887Z","shell.execute_reply.started":"2022-05-20T19:16:59.310005Z","shell.execute_reply":"2022-05-20T19:17:03.590134Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test = read_csv_strict(file_name=r\"/kaggle/input/g-research-crypto-forecasting/example_test.csv\")\ndf_test.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:03.592144Z","iopub.execute_input":"2022-05-20T19:17:03.592378Z","iopub.status.idle":"2022-05-20T19:17:03.622307Z","shell.execute_reply.started":"2022-05-20T19:17:03.592350Z","shell.execute_reply":"2022-05-20T19:17:03.621747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(df_train[\"timestamp\"].min(), df_train[\"timestamp\"].max())","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:03.623817Z","iopub.execute_input":"2022-05-20T19:17:03.624341Z","iopub.status.idle":"2022-05-20T19:17:03.633979Z","shell.execute_reply.started":"2022-05-20T19:17:03.624303Z","shell.execute_reply":"2022-05-20T19:17:03.633046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(df_supp_train[\"timestamp\"].min(), df_supp_train[\"timestamp\"].max())","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:03.635002Z","iopub.execute_input":"2022-05-20T19:17:03.635206Z","iopub.status.idle":"2022-05-20T19:17:03.648310Z","shell.execute_reply.started":"2022-05-20T19:17:03.635181Z","shell.execute_reply":"2022-05-20T19:17:03.647384Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = pd.concat([df_train, df_supp_train, df_test])\ndf_train.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:03.649525Z","iopub.execute_input":"2022-05-20T19:17:03.649940Z","iopub.status.idle":"2022-05-20T19:17:03.797003Z","shell.execute_reply.started":"2022-05-20T19:17:03.649900Z","shell.execute_reply":"2022-05-20T19:17:03.796148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.shape, df_supp_train.shape, df_test.shape","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:03.798107Z","iopub.execute_input":"2022-05-20T19:17:03.798334Z","iopub.status.idle":"2022-05-20T19:17:03.804637Z","shell.execute_reply.started":"2022-05-20T19:17:03.798307Z","shell.execute_reply":"2022-05-20T19:17:03.803634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Outliers","metadata":{}},{"cell_type":"code","source":"## Negative volume implies lack of liquidity in the market\ndf_train[df_train.Volume < 0]","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:03.805943Z","iopub.execute_input":"2022-05-20T19:17:03.806202Z","iopub.status.idle":"2022-05-20T19:17:03.920718Z","shell.execute_reply.started":"2022-05-20T19:17:03.806173Z","shell.execute_reply":"2022-05-20T19:17:03.919836Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Negative volume indicates that the market lacked liquidity for these instances; in other words, the bid and ask price  failed to overlap.","metadata":{}},{"cell_type":"markdown","source":"## Check for NaNs","metadata":{}},{"cell_type":"code","source":"## https://www.kaggle.com/c/g-research-crypto-forecasting/discussion/286778\n## https://www.kaggle.com/cstein06/tutorial-to-the-g-research-crypto-competition?scriptVersionId=84976518&cellId=51\n\n# df_train[(df_train.Target.isna()) & (df_train.Asset_ID==8)]\ndf_train[df_train.Target.isna()].groupby(\"Asset_ID\")[\"timestamp\"].count()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:03.922176Z","iopub.execute_input":"2022-05-20T19:17:03.922410Z","iopub.status.idle":"2022-05-20T19:17:03.955337Z","shell.execute_reply.started":"2022-05-20T19:17:03.922381Z","shell.execute_reply":"2022-05-20T19:17:03.954336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train[(df_train.Target.isna()) & (df_train.Asset_ID==8)].describe(percentiles=[0.25, 0.50, 0.75, 0.90, 0.95, 0.99])","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:03.957889Z","iopub.execute_input":"2022-05-20T19:17:03.958119Z","iopub.status.idle":"2022-05-20T19:17:04.030941Z","shell.execute_reply.started":"2022-05-20T19:17:03.958091Z","shell.execute_reply":"2022-05-20T19:17:04.030082Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Sort by Asset and Timestamp","metadata":{}},{"cell_type":"code","source":"df_train = df_train.sort_values(by=[\"Asset_ID\", \"timestamp\"]\n                               ,ascending=True)\n\ndf_train.head(20)","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:04.032243Z","iopub.execute_input":"2022-05-20T19:17:04.032484Z","iopub.status.idle":"2022-05-20T19:17:05.808084Z","shell.execute_reply.started":"2022-05-20T19:17:04.032454Z","shell.execute_reply":"2022-05-20T19:17:05.807235Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Dealing with missing data","metadata":{}},{"cell_type":"code","source":"df_train.info()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:05.809266Z","iopub.execute_input":"2022-05-20T19:17:05.809513Z","iopub.status.idle":"2022-05-20T19:17:05.823746Z","shell.execute_reply.started":"2022-05-20T19:17:05.809484Z","shell.execute_reply":"2022-05-20T19:17:05.823047Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"total missing: \")\nprint(df_train.isna().sum())\nprint(\"----------------------------\")\nprint(\"percent missing: \")\nprint(df_train.isna().sum() * 100. / df_train.shape[0])","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:05.824876Z","iopub.execute_input":"2022-05-20T19:17:05.825183Z","iopub.status.idle":"2022-05-20T19:17:06.090060Z","shell.execute_reply.started":"2022-05-20T19:17:05.825152Z","shell.execute_reply":"2022-05-20T19:17:06.089194Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:06.091167Z","iopub.execute_input":"2022-05-20T19:17:06.091465Z","iopub.status.idle":"2022-05-20T19:17:06.113362Z","shell.execute_reply.started":"2022-05-20T19:17:06.091424Z","shell.execute_reply":"2022-05-20T19:17:06.112026Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Ffill for each group for Target missing value","metadata":{}},{"cell_type":"code","source":"## https://stackoverflow.com/questions/16345583/fill-in-missing-pandas-data-with-previous-non-missing-value-grouped-by-key\ndf_train[\"Target\"] = df_train.sort_values([\"Asset_ID\", \"timestamp\"]).groupby(\"Asset_ID\")[\"Target\"].ffill()\ndf_train[\"VWAP\"] = df_train.sort_values([\"Asset_ID\", \"timestamp\"]).groupby(\"Asset_ID\")[\"VWAP\"].ffill()\ndf_train.head(20)","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:06.115294Z","iopub.execute_input":"2022-05-20T19:17:06.115868Z","iopub.status.idle":"2022-05-20T19:17:08.699776Z","shell.execute_reply.started":"2022-05-20T19:17:06.115761Z","shell.execute_reply":"2022-05-20T19:17:08.699061Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.isna().sum()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:08.700734Z","iopub.execute_input":"2022-05-20T19:17:08.700931Z","iopub.status.idle":"2022-05-20T19:17:08.833540Z","shell.execute_reply.started":"2022-05-20T19:17:08.700906Z","shell.execute_reply":"2022-05-20T19:17:08.832926Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train[ (df_train[\"Target\"].isna()) & (df_train[\"Asset_ID\"] == 10)]","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:08.834632Z","iopub.execute_input":"2022-05-20T19:17:08.834883Z","iopub.status.idle":"2022-05-20T19:17:08.879522Z","shell.execute_reply.started":"2022-05-20T19:17:08.834855Z","shell.execute_reply":"2022-05-20T19:17:08.878868Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train[\"Target\"] = df_train[\"Target\"].fillna(0)\n# df_train[\"VWAP\"] = df_train[\"VWAP\"].fillna(0)","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:08.880738Z","iopub.execute_input":"2022-05-20T19:17:08.880952Z","iopub.status.idle":"2022-05-20T19:17:08.916598Z","shell.execute_reply.started":"2022-05-20T19:17:08.880925Z","shell.execute_reply":"2022-05-20T19:17:08.915806Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train[ (df_train[\"Target\"].isna()) & (df_train[\"Asset_ID\"] == 10)]","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:08.918188Z","iopub.execute_input":"2022-05-20T19:17:08.918566Z","iopub.status.idle":"2022-05-20T19:17:08.955293Z","shell.execute_reply.started":"2022-05-20T19:17:08.918522Z","shell.execute_reply":"2022-05-20T19:17:08.954408Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train[\"Target\"].isna().sum()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:08.956459Z","iopub.execute_input":"2022-05-20T19:17:08.956768Z","iopub.status.idle":"2022-05-20T19:17:08.986799Z","shell.execute_reply.started":"2022-05-20T19:17:08.956725Z","shell.execute_reply":"2022-05-20T19:17:08.985965Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Utility Functions","metadata":{}},{"cell_type":"code","source":"# Two new features from the competition tutorial\ndef upper_shadow(df):\n    return df[\"High\"] - np.maximum(df[\"Close\"], df[\"Open\"])\n\ndef lower_shadow(df):\n    return np.minimum(df[\"Close\"], df[\"Open\"]) - df[\"Low\"]\n\n## notebook: crypto-prediction-technical-analysis-features\ndef SM_A_M(df, colname, n):\n    mean = df[colname].rolling(window=n).mean()\n    median = df[colname].rolling(window=n).median()\n    \n    return mean, median\n\ndef EMA1(df, colname, n):\n    \"\"\"\n    https://qiita.com/MuAuan/items/b08616a841be25d29817\n    \"\"\"\n    a= 2/(n+1)\n    return df[colname].ewm(alpha=a).mean()\n\ndef MACD(df, colname, span1=12, span2=26, span3=9):\n    \"\"\"\n    Compute MACD\n    # https://www.learnpythonwithrune.org/pandas-calculate-the-moving-average-convergence-divergence-macd-for-a-stock/\n    \"\"\"\n    \n    exp1 = EMA1(df, colname, span1)\n    exp2 = EMA1(df, colname, span2)\n    macd = 100 * (exp1 - exp2) / exp2\n    signal = macd.ewm(alpha=2./(span3+1)).mean() ##EMA1(df, colname, macd, span3)\n\n    return macd, signal\n\ndef BollingerBand(df, colname, window, no_of_std):\n    mean = df[colname].rolling(window=window).mean()\n    std = df[colname].rolling(window=window).std() \n    bb_high = mean + no_of_std * std\n    bb_low = mean - no_of_std * std\n    \n    return bb_high, bb_low, std\n\ndef rsiFunc(df, colname, n=14):\n    prices = df[colname].values\n    \n    deltas = np.diff(prices)\n    seed = deltas[:n+1]\n    up = seed[seed>=0].sum()/n\n    down = -seed[seed<0].sum()/n\n    rs = up/down\n    rsi = np.zeros_like(prices)\n    rsi[:n] = 100. - 100./(1.+rs)\n\n    for i in range(n, len(prices)):\n        delta = deltas[i-1] # cause the diff is 1 shorter\n\n        if delta>0:\n            upval = delta\n            downval = 0.\n        else:\n            upval = 0.\n            downval = -delta\n\n        up = (up*(n-1) + upval)/n\n        down = (down*(n-1) + downval)/n\n\n        rs = up/down\n        rsi[i] = 100. - 100./(1.+rs)\n\n    return rsi\n\n## https://stackoverflow.com/questions/42138357/pandas-rolling-slope-calculation\ndef calc_slope(x):\n    slope = np.polyfit(range(len(x)), x, 1)[0]\n    return slope","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:08.988121Z","iopub.execute_input":"2022-05-20T19:17:08.988334Z","iopub.status.idle":"2022-05-20T19:17:09.006427Z","shell.execute_reply.started":"2022-05-20T19:17:08.988309Z","shell.execute_reply":"2022-05-20T19:17:09.005553Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## set min_periods=2 to allow subsets less than 60.\n## use [4::5] to select the results you need.\n# result = data.rolling(60, min_periods=2).apply(calc_slope)[4::5]","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:09.007619Z","iopub.execute_input":"2022-05-20T19:17:09.008070Z","iopub.status.idle":"2022-05-20T19:17:09.022126Z","shell.execute_reply.started":"2022-05-20T19:17:09.008041Z","shell.execute_reply":"2022-05-20T19:17:09.021264Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Feature Engineering","metadata":{}},{"cell_type":"code","source":"def get_feat(df):\n    df[\"High-Low\"] = df[\"High\"] - df[\"Low\"]\n    df[\"Close-Open\"] = df[\"Close\"] - df[\"Open\"]\n\n    df[\"dayofweek\"] = df[\"datetime\"].dt.dayofweek\n    df[\"weekofyear\"] = df[\"datetime\"].dt.weekofyear\n    # df_train['upper_shadow'] = upper_shadow(df=df_train)\n    # df_train['lower_shadow'] = lower_shadow(df=df_train)\n\n    df[\"dayofweek\"] = df[\"dayofweek\"].astype(np.int8)\n    df[\"weekofyear\"] = df[\"weekofyear\"].astype(np.int8)\n    # df_train['upper_shadow'] = df_train['upper_shadow'].astype(np.float32)\n    # df_train['lower_shadow'] = df_train['lower_shadow'].astype(np.float32)\n\n    df = df.drop([\"datetime\", \"VWAP\", \"Open\", \"High\", \"Low\"], axis=1)\n    gc.collect()\n    # df_train = reduce_mem_usage(df_train)\n    # df_train.describe()\n\n    macd, signal = MACD(df=df, colname=\"Close\")\n    df['MACD_' + \"Close\" + '_macd'] = macd\n    df['MACD_' + \"Close\" + '_signal'] = signal\n\n    df['MACD_' + \"Close\" + '_macd'] = df['MACD_' + \"Close\" + '_macd'].astype(np.float32)\n    df['MACD_' + \"Close\" + '_signal'] = df['MACD_' + \"Close\" + '_signal'].astype(np.float32)\n\n    arr_n = [5, 10, 15]\n    # arr_cols = [\"Close\", \"VWAP\", \"Volume\"]\n    arr_cols = [\"Close\", \"Volume\"]\n    no_of_std = 2.5\n\n    for colname in arr_cols: \n        print(\"colname = \" + colname)\n        for n in arr_n:\n            print(\"n = \"+ str(n))\n            df['Target_lag_' + str(n)] = df['Target'].shift(n)\n            df['Target_lag_' + str(n)].fillna(value=df[\"Target\"], inplace=True)\n            \n#             print(\"Slope\") ## takes too long\n#             slope = df[\"Target\"].rolling(window=n).apply(calc_slope)[4::5]\n#             df['SM_' + \"Target\" + '_slope_' + str(n)] = slope\n#             df['SM_' + \"Target\" + '_slope_' + str(n)].fillna(value=0.1, inplace=True)\n#             df['SM_' + \"Target\" + '_slope_' + str(n)] = df['SM_' + \"Target\" + '_slope_' + str(n)].astype(np.float32)\n\n            print(\"SMA\")\n            mean, median = SM_A_M(df=df, colname=colname, n=n)\n            df['SM_' + colname + '_mean_' + str(n)] = mean\n            df['SM_' + colname + '_median_' + str(n)] = median\n\n            df['SM_' + colname + '_mean_' + str(n)] = df['SM_' + colname + '_mean_' + str(n)].astype(np.float32)\n            df['SM_' + colname + '_median_' + str(n)] = df['SM_' + colname + '_median_' + str(n)].astype(np.float32)\n\n            df['SM_' + colname + '_mean_' + str(n)].fillna(value=df[colname], inplace=True)\n            df['SM_' + colname + '_median_' + str(n)].fillna(value=df[colname], inplace=True)\n            \n\n            print(\"EMA1\")\n            ewmean = EMA1(df=df_train, colname=colname, n=n)\n            df['EWM_' + colname + '_mean_' + str(n)] = ewmean\n            df['EWM_' + colname + '_mean_' + str(n)] = df['EWM_' + colname + '_mean_' + str(n)].astype(np.float32)\n            df['EWM_' + colname + '_mean_' + str(n)].fillna(value=1, inplace=True)\n            \n            if colname in ['VWAP', 'Volume']:\n                continue\n\n            if n==5:\n                continue\n                \n            print(\"RSI\")\n            rsi = rsiFunc(df=df,  colname=colname, n=n)\n            df['RSI_' + str(n)] = rsi\n            df['RSI_' + str(n)] = df['RSI_' + str(n)].astype(np.float32)\n            df['RSI_' + str(n)].fillna(value=1, inplace=True)\n            \n\n            print(\"BollingerBand\")\n            bb_high, bb_low, std = BollingerBand(df=df, colname=colname, window=n, no_of_std=no_of_std)\n            df['SM_' + colname + '_std_' + str(n)] = std\n            df['SM_' + colname + '_BB_High_' + str(n)] = bb_high\n            df['SM_' + colname + '_BB_Low_' + str(n)] = bb_low\n\n            df['SM_' + colname + '_std_' + str(n)] = df['SM_' + colname + '_std_' + str(n)].astype(np.float32)\n            df['SM_' + colname + '_BB_High_' + str(n)] = df['SM_' + colname + '_BB_High_' + str(n)].astype(np.float32)\n            df['SM_' + colname + '_BB_Low_' + str(n)] = df['SM_' + colname + '_BB_Low_' + str(n)].astype(np.float32)\n            df['SM_' + colname + '_std_' + str(n)].fillna(value=0, inplace=True)\n            df['SM_' + colname + '_BB_High_' + str(n)].fillna(value=df[colname], inplace=True) \n            df['SM_' + colname + '_BB_Low_' + str(n)].fillna(value=df[colname], inplace=True) \n            \n            \n            gc.collect()\n\n    df = reduce_mem_usage(df)\n#     df.fillna(value=0, inplace=True)\n    df.head()\n\n    return df","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:09.023742Z","iopub.execute_input":"2022-05-20T19:17:09.024215Z","iopub.status.idle":"2022-05-20T19:17:09.055423Z","shell.execute_reply.started":"2022-05-20T19:17:09.024173Z","shell.execute_reply":"2022-05-20T19:17:09.054551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.describe()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:09.057074Z","iopub.execute_input":"2022-05-20T19:17:09.057368Z","iopub.status.idle":"2022-05-20T19:17:11.388037Z","shell.execute_reply.started":"2022-05-20T19:17:09.057330Z","shell.execute_reply":"2022-05-20T19:17:11.387219Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = get_feat(df=df_train)\ndf_train.memory_usage(deep=True)","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:17:11.389715Z","iopub.execute_input":"2022-05-20T19:17:11.390016Z","iopub.status.idle":"2022-05-20T19:18:37.399062Z","shell.execute_reply.started":"2022-05-20T19:17:11.389976Z","shell.execute_reply":"2022-05-20T19:18:37.398044Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.info(verbose=False, memory_usage='deep')","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:18:37.400462Z","iopub.execute_input":"2022-05-20T19:18:37.400801Z","iopub.status.idle":"2022-05-20T19:18:37.411480Z","shell.execute_reply.started":"2022-05-20T19:18:37.400757Z","shell.execute_reply":"2022-05-20T19:18:37.410595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:18:37.412797Z","iopub.execute_input":"2022-05-20T19:18:37.413329Z","iopub.status.idle":"2022-05-20T19:18:37.549536Z","shell.execute_reply.started":"2022-05-20T19:18:37.413296Z","shell.execute_reply":"2022-05-20T19:18:37.548543Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import memory_profiler\nm1 = memory_profiler.memory_usage()\nm1","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:18:37.555086Z","iopub.execute_input":"2022-05-20T19:18:37.555509Z","iopub.status.idle":"2022-05-20T19:18:37.661500Z","shell.execute_reply.started":"2022-05-20T19:18:37.555475Z","shell.execute_reply":"2022-05-20T19:18:37.660669Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.head(10)","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:18:37.663034Z","iopub.execute_input":"2022-05-20T19:18:37.663324Z","iopub.status.idle":"2022-05-20T19:18:37.715029Z","shell.execute_reply.started":"2022-05-20T19:18:37.663287Z","shell.execute_reply":"2022-05-20T19:18:37.714185Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:18:37.716441Z","iopub.execute_input":"2022-05-20T19:18:37.716907Z","iopub.status.idle":"2022-05-20T19:18:37.843933Z","shell.execute_reply.started":"2022-05-20T19:18:37.716866Z","shell.execute_reply":"2022-05-20T19:18:37.843022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test = df_train[~((df_train[\"group_num\"].isna()) & (df_train[\"row_id\"].isna()))]\nprint(df_test.shape)\n\ngc.collect()\n\ndf_train.drop(  df_train[~((df_train[\"group_num\"].isna()) & (df_train[\"row_id\"].isna()))].index, inplace=True)\nprint(df_train.shape)\n\ndf_test.drop([\"Target\"], axis=1, inplace=True)\ndf_train.drop([\"group_num\", \"row_id\"], axis=1, inplace=True)\n\ndf_train.shape, df_test.shape","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:18:37.845024Z","iopub.execute_input":"2022-05-20T19:18:37.845241Z","iopub.status.idle":"2022-05-20T19:18:41.896403Z","shell.execute_reply.started":"2022-05-20T19:18:37.845214Z","shell.execute_reply":"2022-05-20T19:18:41.895453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:18:41.897602Z","iopub.execute_input":"2022-05-20T19:18:41.897920Z","iopub.status.idle":"2022-05-20T19:18:41.937925Z","shell.execute_reply.started":"2022-05-20T19:18:41.897888Z","shell.execute_reply":"2022-05-20T19:18:41.937047Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.isna().sum()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:18:41.939057Z","iopub.execute_input":"2022-05-20T19:18:41.939265Z","iopub.status.idle":"2022-05-20T19:18:42.500858Z","shell.execute_reply.started":"2022-05-20T19:18:41.939239Z","shell.execute_reply":"2022-05-20T19:18:42.500045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Training with LGBM","metadata":{}},{"cell_type":"code","source":"# 10-fold time series cross validation\ndef timecv_model(model, X, y):\n    tfold = TimeSeriesSplit(n_splits = 5)\n    pcc_list = []\n    for _, (train_index, test_index) in tqdm(enumerate(tfold.split(X), start=1)):\n        X_train, X_test = X.iloc[train_index], X.iloc[test_index]\n        y_train, y_test = y.iloc[train_index], y.iloc[test_index]\n        clf = model.fit(X_train, y_train)\n        pred = clf.predict(X_test)\n        pcc = pearsonr(pred, y_test) \n        pcc_list.append(pcc[0])\n    \n    return pcc_list\n\ndef cv_result(model, X, y):\n    model_name = model.__class__.__name__\n    pcc_ = timecv_model(model, X, y)\n    for i, pcc in enumerate(pcc_):\n        print(f'{i}th fold: {model_name} PCC: {pcc:.4f}')\n    print(f'\\n{model_name} average PCC: {np.mean(pcc_):.4f}')","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:18:42.502167Z","iopub.execute_input":"2022-05-20T19:18:42.502386Z","iopub.status.idle":"2022-05-20T19:18:42.511504Z","shell.execute_reply.started":"2022-05-20T19:18:42.502359Z","shell.execute_reply":"2022-05-20T19:18:42.510600Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_lgb(model, X, y):\n    print(\"model fitting ...\")\n    clf = model.fit(X, y)\n    print(\"predicting ...\")\n    pred = clf.predict(X)\n    pcc = pearsonr(pred, y)[0]\n    \n    print(\"pcc = \", str(pcc))\n    gc.collect()\n    \n    return model","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:18:42.512556Z","iopub.execute_input":"2022-05-20T19:18:42.512774Z","iopub.status.idle":"2022-05-20T19:18:42.523509Z","shell.execute_reply.started":"2022-05-20T19:18:42.512746Z","shell.execute_reply":"2022-05-20T19:18:42.522744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train = df_train[df_train['timestamp'] < 1630432800] ## original train data\n# valid = df_train[df_train['timestamp'] >= 1630432800] ## supplementary data\n\n# train.drop(['timestamp', 'Asset_ID'], axis = 1, inplace = True)\n# valid.drop(['timestamp', 'Asset_ID'], axis = 1, inplace = True)\n\n# X_train = train.drop(['Target'], axis = 1)\n# y_train = train['Target']\n# X_valid = valid.drop(['Target'], axis = 1)\n# y_valid = valid['Target']\n\n# print(X_train.shape)\n# print(X_valid.shape)","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:18:42.524644Z","iopub.execute_input":"2022-05-20T19:18:42.524908Z","iopub.status.idle":"2022-05-20T19:18:42.535470Z","shell.execute_reply.started":"2022-05-20T19:18:42.524881Z","shell.execute_reply":"2022-05-20T19:18:42.534752Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# lgb_model = LGBMRegressor(n_estimators = 420,\n#                           max_depth = 17,\n#                           num_leaves = 36,\n#                           learning_rate = 0.09786397238905313, \n#                           min_child_samples = 49, \n#                           colsample_bytree=0.7,\n#                           subsample = 0.8683175057718733,\n#                           seed = 0)\n\n## 'colsample_bytree': 0.4000480946836777, 'max_depth': 17, 'num_leaves': 35, 'learning_rate': 0.06891972238739223, 'n_estimators': 576, 'min_child_samples': 47, 'subsample': 0.6058272745943716\n\nlgb_model = LGBMRegressor(n_estimators = 576,\n                          max_depth = 17,\n                          num_leaves = 35,\n                          learning_rate = 0.06891972238739223, \n                          min_child_samples = 47, \n                          colsample_bytree=0.4000480946836777,\n                          subsample = 0.6058272745943716,\n                          seed = 42)\n\n# cv_result(lgb_model, X, y)\n# lgb_model.fit(X_train, y_train, eval_set = [(X_train, y_train), (X_valid, y_valid)],\n#              verbose = 0, early_stopping_rounds = 50)\n# pred = model.predict(X_valid)\n# pcc = pearsonr(pred, y_valid)[0]\n# print(pcc)\ny = df_train[\"Target\"]\nX = df_train.drop(['timestamp', \"Target\"], axis=1)\n\ngc.collect()\n\nmodel = train_lgb(lgb_model, X, y)\nmodel","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:18:42.537602Z","iopub.execute_input":"2022-05-20T19:18:42.538237Z","iopub.status.idle":"2022-05-20T19:21:19.105020Z","shell.execute_reply.started":"2022-05-20T19:18:42.538195Z","shell.execute_reply":"2022-05-20T19:21:19.104108Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_prediction(row):\n    y_pred = df_test.loc[((df_test[\"timestamp\"] == row[\"timestamp\"]) & (df_test[\"Asset_ID\"] == row[\"Asset_ID\"])), \"Target\"]\n    print(y_pred.values[0])\n    return y_pred.values[0]","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:21:19.106313Z","iopub.execute_input":"2022-05-20T19:21:19.106906Z","iopub.status.idle":"2022-05-20T19:21:19.112998Z","shell.execute_reply.started":"2022-05-20T19:21:19.106860Z","shell.execute_reply":"2022-05-20T19:21:19.112131Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Hyperparameter Tuning with Optuna","metadata":{}},{"cell_type":"code","source":"# train = df_train[df_train['timestamp'] < '2020-09-20']\n# valid = df_train[df_train['timestamp'] >= '2020-09-20']\n\n# train.drop(['timestamp', 'Asset_ID'], axis = 1, inplace = True)\n# valid.drop(['timestamp', 'Asset_ID'], axis = 1, inplace = True)\n\n# X_train = train.drop(['Target'], axis = 1)\n# y_train = train['Target']\n# X_valid = valid.drop(['Target'], axis = 1)\n# y_valid = valid['Target']\n\n# print(X_train.shape)\n# print(X_valid.shape)","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:21:19.114167Z","iopub.execute_input":"2022-05-20T19:21:19.114461Z","iopub.status.idle":"2022-05-20T19:21:19.125534Z","shell.execute_reply.started":"2022-05-20T19:21:19.114431Z","shell.execute_reply":"2022-05-20T19:21:19.124780Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from optuna.samplers import TPESampler\n# import optuna\n\n# sampler = TPESampler(seed = 0)\n\n# def objective(trial):\n#     params = {\n#         'objective': 'regression',\n#         'verbose': -1,\n#         'max_depth': trial.suggest_int('max_depth',5, 20),\n#         'num_leaves': trial.suggest_int('num_leaves', 10, 40),\n#         'learning_rate': trial.suggest_float(\"learning_rate\", 1e-5, 0.1),\n#         'n_estimators': trial.suggest_int('n_estimators', 500, 2500),\n#         'min_child_samples': trial.suggest_int('min_child_samples', 5, 100),\n#         'subsample': trial.suggest_float('subsample', 0.4, 1)}\n    \n#     model = LGBMRegressor(**params)\n#     model.fit(X_train, y_train, eval_set = [(X_train, y_train), (X_valid, y_valid)],\n#              verbose = 0, early_stopping_rounds = 50)\n#     pred = model.predict(X_valid)\n#     pcc = pearsonr(pred, y_valid)[0]\n#     return pcc\n\n# study_model = optuna.create_study(direction = 'maximize', sampler = sampler)\n# study_model.optimize(objective, n_trials = 20) ","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:21:19.126772Z","iopub.execute_input":"2022-05-20T19:21:19.127505Z","iopub.status.idle":"2022-05-20T19:21:19.142189Z","shell.execute_reply.started":"2022-05-20T19:21:19.127471Z","shell.execute_reply":"2022-05-20T19:21:19.141393Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # select best trial and parameter\n# trial = study_model.best_trial\n# best_params = trial.params\n\n# print('Best params from optuna: \\n', best_params)","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:21:19.143548Z","iopub.execute_input":"2022-05-20T19:21:19.143816Z","iopub.status.idle":"2022-05-20T19:21:19.155111Z","shell.execute_reply.started":"2022-05-20T19:21:19.143786Z","shell.execute_reply":"2022-05-20T19:21:19.154497Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# optuna.visualization.plot_optimization_history(study_model)","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:21:19.156547Z","iopub.execute_input":"2022-05-20T19:21:19.157210Z","iopub.status.idle":"2022-05-20T19:21:19.166475Z","shell.execute_reply.started":"2022-05-20T19:21:19.157160Z","shell.execute_reply":"2022-05-20T19:21:19.165558Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# optuna.visualization.plot_slice(study_model)","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:21:19.167805Z","iopub.execute_input":"2022-05-20T19:21:19.168636Z","iopub.status.idle":"2022-05-20T19:21:19.178757Z","shell.execute_reply.started":"2022-05-20T19:21:19.168589Z","shell.execute_reply":"2022-05-20T19:21:19.177978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# optuna.visualization.plot_param_importances(study_model)","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:21:19.180075Z","iopub.execute_input":"2022-05-20T19:21:19.180546Z","iopub.status.idle":"2022-05-20T19:21:19.189769Z","shell.execute_reply.started":"2022-05-20T19:21:19.180500Z","shell.execute_reply":"2022-05-20T19:21:19.189161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# opt_model = LGBMRegressor(**best_params)\n\n# cv_result(opt_model, X, y)","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:21:19.190846Z","iopub.execute_input":"2022-05-20T19:21:19.191833Z","iopub.status.idle":"2022-05-20T19:21:19.201452Z","shell.execute_reply.started":"2022-05-20T19:21:19.191780Z","shell.execute_reply":"2022-05-20T19:21:19.200871Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Predict and Submit","metadata":{}},{"cell_type":"code","source":"df_pred = pd.read_csv(r\"/kaggle/input/g-research-crypto-forecasting/example_test.csv\")\ndf_pred.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:21:19.202527Z","iopub.execute_input":"2022-05-20T19:21:19.202764Z","iopub.status.idle":"2022-05-20T19:21:19.230334Z","shell.execute_reply.started":"2022-05-20T19:21:19.202735Z","shell.execute_reply":"2022-05-20T19:21:19.229347Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_sample_sub = pd.read_csv(r\"/kaggle/input/g-research-crypto-forecasting/example_test.csv\")\ndf_sample_sub.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:21:19.231719Z","iopub.execute_input":"2022-05-20T19:21:19.232886Z","iopub.status.idle":"2022-05-20T19:21:19.251519Z","shell.execute_reply.started":"2022-05-20T19:21:19.232837Z","shell.execute_reply":"2022-05-20T19:21:19.250763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test.columns","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:21:19.253132Z","iopub.execute_input":"2022-05-20T19:21:19.253682Z","iopub.status.idle":"2022-05-20T19:21:19.260420Z","shell.execute_reply.started":"2022-05-20T19:21:19.253638Z","shell.execute_reply":"2022-05-20T19:21:19.259543Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_test = df_test.drop([\"group_num\", \"row_id\", \"timestamp\"], axis=1)\ndf_test[\"Target\"] = model.predict(X_test)\ndf_test.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:21:19.261772Z","iopub.execute_input":"2022-05-20T19:21:19.262146Z","iopub.status.idle":"2022-05-20T19:21:19.317951Z","shell.execute_reply.started":"2022-05-20T19:21:19.262102Z","shell.execute_reply":"2022-05-20T19:21:19.317367Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:21:19.318937Z","iopub.execute_input":"2022-05-20T19:21:19.319237Z","iopub.status.idle":"2022-05-20T19:21:19.359867Z","shell.execute_reply.started":"2022-05-20T19:21:19.319210Z","shell.execute_reply":"2022-05-20T19:21:19.359270Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_pred[\"Target\"] = 0.0\n\nfor j, row in df_test.iterrows():\n    print(row[\"Target\"])\n    df_pred.loc[((df_pred[\"group_num\"] == int(row[\"group_num\"])) & (df_pred[\"row_id\"] == int(row[\"row_id\"]))), \"Target\"] = row[\"Target\"]\n    print(\"pred \" + str(row[\"row_id\"])  + \" \" + str(df_pred.loc[df_pred[\"row_id\"] == row[\"row_id\"], \"Target\"]))","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:21:19.360997Z","iopub.execute_input":"2022-05-20T19:21:19.361358Z","iopub.status.idle":"2022-05-20T19:21:19.495221Z","shell.execute_reply.started":"2022-05-20T19:21:19.361328Z","shell.execute_reply":"2022-05-20T19:21:19.494287Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_pred","metadata":{"execution":{"iopub.status.busy":"2022-05-20T19:21:19.496387Z","iopub.execute_input":"2022-05-20T19:21:19.496618Z","iopub.status.idle":"2022-05-20T19:21:19.536856Z","shell.execute_reply.started":"2022-05-20T19:21:19.496589Z","shell.execute_reply":"2022-05-20T19:21:19.536239Z"},"trusted":true},"execution_count":null,"outputs":[]}]}