{"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\n# Necessary imports\n\n# File/data manipulation\nimport os\nimport gc\nimport json\nimport glob\nimport time\nimport joblib\nimport pathlib\nimport datetime\nimport warnings\nimport numpy as np\nimport pandas as pd\nfrom scipy import stats\nfrom tqdm.auto import tqdm\nfrom multiprocessing import Pool, cpu_count\n\n# Models\n#from xgboost import XGBRegressor\nfrom lightgbm import LGBMRegressor\n\n# Visualization\nimport seaborn as sns\nimport plotly.express as px\nimport matplotlib.pyplot as plt\nimport matplotlib.style as style\nimport plotly.graph_objects as go\nfrom matplotlib import pyplot\nfrom matplotlib_venn import venn2, venn3\nfrom matplotlib.ticker import ScalarFormatter","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-12-19T03:14:27.365091Z","iopub.execute_input":"2021-12-19T03:14:27.365741Z","iopub.status.idle":"2021-12-19T03:14:30.689347Z","shell.execute_reply.started":"2021-12-19T03:14:27.365648Z","shell.execute_reply":"2021-12-19T03:14:30.688608Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Inits/configs\n\nsns.set_context(\"talk\")\nstyle.use('seaborn-colorblind')\nwarnings.simplefilter('ignore')\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\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\n\n# Filepaths\nclass CFG:\n    INPUT_DIR = '/kaggle/input/g-research-crypto-forecasting/'\n    OUTPUT_DIR = './'\n    SEED = 20211103","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:14:30.692961Z","iopub.execute_input":"2021-12-19T03:14:30.693160Z","iopub.status.idle":"2021-12-19T03:14:30.711779Z","shell.execute_reply.started":"2021-12-19T03:14:30.693136Z","shell.execute_reply":"2021-12-19T03:14:30.711038Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Function to reduce memory usage.\n# Thanks fellow Kaggle User.\n\ndef 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":"2021-12-19T03:14:30.712824Z","iopub.execute_input":"2021-12-19T03:14:30.713130Z","iopub.status.idle":"2021-12-19T03:14:30.727266Z","shell.execute_reply.started":"2021-12-19T03:14:30.713095Z","shell.execute_reply":"2021-12-19T03:14:30.726498Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Get training (and testing) data.\n\n#train = pd.read_csv(os.path.join(CFG.INPUT_DIR, 'train.csv'))\ntrain = pd.read_csv(os.path.join(CFG.INPUT_DIR, 'train.csv')).pipe(reduce_mem_usage)\nprint(train.shape)\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:14:30.729442Z","iopub.execute_input":"2021-12-19T03:14:30.729843Z","iopub.status.idle":"2021-12-19T03:15:28.766097Z","shell.execute_reply.started":"2021-12-19T03:14:30.729803Z","shell.execute_reply":"2021-12-19T03:15:28.765423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Get cryptoasset details, i.e. real name and weight assigned per market share.\n\nasset_details = pd.read_csv(os.path.join(CFG.INPUT_DIR, 'asset_details.csv'))\nasset_details['Asset_ID'] = asset_details['Asset_ID'].astype(np.int8)\nprint(asset_details.shape)\nasset_details","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:15:28.767342Z","iopub.execute_input":"2021-12-19T03:15:28.768519Z","iopub.status.idle":"2021-12-19T03:15:28.793744Z","shell.execute_reply.started":"2021-12-19T03:15:28.768481Z","shell.execute_reply":"2021-12-19T03:15:28.793030Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Examine G-Research's example_sample_submission.\n\nexample_sample_submission = pd.read_csv(os.path.join(CFG.INPUT_DIR, 'example_sample_submission.csv'))\nprint(example_sample_submission.shape)\nexample_sample_submission.head()","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:15:28.794980Z","iopub.execute_input":"2021-12-19T03:15:28.795313Z","iopub.status.idle":"2021-12-19T03:15:28.813168Z","shell.execute_reply.started":"2021-12-19T03:15:28.795275Z","shell.execute_reply":"2021-12-19T03:15:28.812276Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Get \"test\" data. Note: Already included at end of training data.\n# This just a standalone set provided as an example of the data that G-Research's API uses to test model.\n\n#test_df = pd.read_csv(os.path.join(CFG.INPUT_DIR, 'example_test.csv'))\ntest_df = pd.read_csv(os.path.join(CFG.INPUT_DIR, 'example_test.csv')).pipe(reduce_mem_usage)\nprint(test_df.shape)\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:15:28.814449Z","iopub.execute_input":"2021-12-19T03:15:28.814876Z","iopub.status.idle":"2021-12-19T03:15:28.847616Z","shell.execute_reply.started":"2021-12-19T03:15:28.814835Z","shell.execute_reply":"2021-12-19T03:15:28.846915Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Dataframe info.\ntrain.info()","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:15:28.848848Z","iopub.execute_input":"2021-12-19T03:15:28.849277Z","iopub.status.idle":"2021-12-19T03:15:28.865898Z","shell.execute_reply.started":"2021-12-19T03:15:28.849241Z","shell.execute_reply":"2021-12-19T03:15:28.865009Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"example_sample_submission.info()","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:15:28.867760Z","iopub.execute_input":"2021-12-19T03:15:28.868612Z","iopub.status.idle":"2021-12-19T03:15:28.880928Z","shell.execute_reply.started":"2021-12-19T03:15:28.868569Z","shell.execute_reply":"2021-12-19T03:15:28.880018Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check for missing/null values.\ntrain.isna().sum()","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:15:28.885636Z","iopub.execute_input":"2021-12-19T03:15:28.886293Z","iopub.status.idle":"2021-12-19T03:15:29.408656Z","shell.execute_reply.started":"2021-12-19T03:15:28.886261Z","shell.execute_reply":"2021-12-19T03:15:29.407829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Total Null Target Rows = \" ,train[\"Target\"].isnull().sum())\nprint(\"Percentage Null Rows in Data = {:.2f}%\".format(train[\"Target\"].isnull().sum()*100 / train.shape[0] ))","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:15:29.409984Z","iopub.execute_input":"2021-12-19T03:15:29.410397Z","iopub.status.idle":"2021-12-19T03:15:29.561489Z","shell.execute_reply.started":"2021-12-19T03:15:29.410348Z","shell.execute_reply":"2021-12-19T03:15:29.560688Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(3, 5, figsize=(20, 12), sharex=True)\nax = ax.flatten()\nfor i, asset in enumerate(train['Asset_ID'].unique()):\n    train.query('Asset_ID == @asset')['Target'].hist(bins=30, color='k', alpha=0.7, ax=ax[i])\n    asset_name = asset_details.query('Asset_ID == @asset')['Asset_Name'].values[0]\n    weight = asset_details.query('Asset_ID == @asset')['Weight'].values[0]\n    ax[i].set_title(f'{asset_name}\\n(weight={weight})')\n    \nax[-1].axis('off')\nplt.tight_layout()","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:15:29.562753Z","iopub.execute_input":"2021-12-19T03:15:29.563639Z","iopub.status.idle":"2021-12-19T03:15:38.633166Z","shell.execute_reply.started":"2021-12-19T03:15:29.563593Z","shell.execute_reply":"2021-12-19T03:15:38.632493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Split train and validation data manually by date. 6/13/21 current best guess for where test data begins.\n\n# Auxiliary function, from datetime to timestamp\ntotimestamp = lambda s: np.int32(time.mktime(datetime.datetime.strptime(s, \"%m/%d/%Y\").timetuple()))\n\ntrain_window = [totimestamp(\"01/01/2018\"), totimestamp(\"06/12/2021\")]\nvalid_window = [totimestamp(\"06/13/2021\"), totimestamp(\"09/21/2021\")]\n#train_window = [totimestamp(\"01/01/2018\"), totimestamp(\"09/21/2020\")]\n#valid_window = [totimestamp(\"09/22/2020\"), totimestamp(\"09/21/2021\")]","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:15:38.634126Z","iopub.execute_input":"2021-12-19T03:15:38.634382Z","iopub.status.idle":"2021-12-19T03:15:38.642014Z","shell.execute_reply.started":"2021-12-19T03:15:38.634332Z","shell.execute_reply":"2021-12-19T03:15:38.641032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Examine distribution of data.\n\nasset_count= []\n\nfor i in range(14):\n    count = (train[\"Asset_ID\"]==i).sum()\n    asset_count.append(count)\n    \nfig = px.bar(x = asset_details.sort_values(\"Asset_ID\")[\"Asset_Name\"],\n             y = asset_count, \n             color = asset_count,\n             color_continuous_scale=\"Emrld\")\n\nfig.update_xaxes(title = \"Assets\")\nfig.update_yaxes(title = \"Number of Rows\")\n\nfig.update_layout(showlegend = True,\n                  title = {'text':'Data Distribution ',\n                           'y':0.95,\n                           'x':0.5,\n                           'xanchor':'center',\n                           'yanchor': 'top'})\n\nfig.show()\nplt.savefig(\"data_dist.png\")","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:15:38.643767Z","iopub.execute_input":"2021-12-19T03:15:38.644477Z","iopub.status.idle":"2021-12-19T03:15:39.981425Z","shell.execute_reply.started":"2021-12-19T03:15:38.644438Z","shell.execute_reply":"2021-12-19T03:15:39.980629Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = train.set_index(\"timestamp\")\nbeg_ = train.index[0].astype('datetime64[s]')\nend_ = train.index[-1].astype('datetime64[s]')\nprint('>> data goes from ', beg_, 'to ', end_, 'shape=', train.shape)","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:15:39.982827Z","iopub.execute_input":"2021-12-19T03:15:39.983084Z","iopub.status.idle":"2021-12-19T03:15:40.337134Z","shell.execute_reply.started":"2021-12-19T03:15:39.983050Z","shell.execute_reply":"2021-12-19T03:15:40.336409Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Drop rows with missing/null targets.\ntrain.dropna(subset=['Target'], inplace=True)\n\n# Add train flag. 0 = validation data, 1 = training data.\ntrain['train_flg'] = 1\ntrain.loc[valid_window[0]:valid_window[1], 'train_flg'] = 0\n\n# Merge asset_details.\ntrain = train.merge(asset_details,how='left',on='Asset_ID')","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:15:40.338269Z","iopub.execute_input":"2021-12-19T03:15:40.338898Z","iopub.status.idle":"2021-12-19T03:15:47.086680Z","shell.execute_reply.started":"2021-12-19T03:15:40.338859Z","shell.execute_reply":"2021-12-19T03:15:47.085927Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define useful features. Upper/lower shadow suggested by competition tutorial.\n\ndef get_row_feats(df):\n    df['upper_shadow'] = df['High'] / df[['Close', 'Open']].max(axis=1)\n    df['lower_shadow'] = df[['Close', 'Open']].min(axis=1) / df['Low']\n    df['open2close'] = df['Close'] / df['Open']\n    df['high2low'] = df['High'] / df['Low']\n    mean_price = df[['Open', 'High', 'Low', 'Close']].mean(axis=1)\n    median_price = df[['Open', 'High', 'Low', 'Close']].median(axis=1)\n    df['high2mean'] = df['High'] / mean_price\n    df['low2mean'] = df['Low'] / mean_price\n    df['high2median'] = df['High'] / median_price\n    df['low2median'] = df['Low'] / median_price\n    df['volume2count'] = df['Volume'] / (df['Count'] + 1)\n    df[\"opensubclose\"] = df[\"Open\"] - df[\"Close\"]\n    return df","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:15:47.088117Z","iopub.execute_input":"2021-12-19T03:15:47.088392Z","iopub.status.idle":"2021-12-19T03:15:47.097266Z","shell.execute_reply.started":"2021-12-19T03:15:47.088344Z","shell.execute_reply":"2021-12-19T03:15:47.096609Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n\nfeature_df = get_row_feats(train)\nprint(feature_df.shape)\nfeature_df.tail()","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:15:47.098576Z","iopub.execute_input":"2021-12-19T03:15:47.098969Z","iopub.status.idle":"2021-12-19T03:16:08.919445Z","shell.execute_reply.started":"2021-12-19T03:15:47.098933Z","shell.execute_reply":"2021-12-19T03:16:08.918661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"target = 'Target'\ndrops = ['timestamp','Asset_Name','Weight','train_flg','Open','High','Low','Close','Volume','VWAP']\nfeatures = [f for f in train.columns if f not in drops + [target]]\ncategoricals = ['Asset_ID']\n\nprint('{:,} features: {}'.format(len(features), features))","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:16:08.920717Z","iopub.execute_input":"2021-12-19T03:16:08.921576Z","iopub.status.idle":"2021-12-19T03:16:08.928445Z","shell.execute_reply.started":"2021-12-19T03:16:08.921535Z","shell.execute_reply":"2021-12-19T03:16:08.927694Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Build Light Gradient Boosted Model.\n\nmodel = LGBMRegressor(#n_estimators=101,\n                      n_estimators=1001,\n                      #n_estimators=10001,\n                      objective='regression',\n                      metric='rmse',\n                      boosting_type='gbdt',\n                      max_depth=-1,\n                      learning_rate=0.01,\n                      feature_fraction=0.72,\n                      bagging_fraction=0.4,\n                      bagging_freq = 4,\n                      lambda_l1=1,\n                      lambda_l2=1,\n                      #subsample=0.72,\n                      #subsample_freq=4,\n                      #feature_fraction: 0.994\n                      #bagging_fraction: 0.632\n                      #bagging_freq: 5\n                      #lambda_l1: 9.4618\n                      #lambda_l2: 0.0003\n                      #num_leaves: 174\n                      #min_child_samples: 99\n                      seed=46)\n","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:16:08.929942Z","iopub.execute_input":"2021-12-19T03:16:08.930998Z","iopub.status.idle":"2021-12-19T03:16:08.939622Z","shell.execute_reply.started":"2021-12-19T03:16:08.930956Z","shell.execute_reply":"2021-12-19T03:16:08.938708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train the LGBM model.\n\nmodel.fit(feature_df.query('train_flg == 1')[features],\n          feature_df.query('train_flg == 1')[target].values,\n          eval_set=[(feature_df.query('train_flg == 0')[features],\n                     feature_df.query('train_flg == 0')[target].values)],\n          verbose=-1,\n          early_stopping_rounds=100,\n          categorical_feature=categoricals)\n\n# Save trained model.\njoblib.dump(model, os.path.join(CFG.OUTPUT_DIR, 'lgb_model_val.pkl'))\nprint('model saved')","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:16:08.941487Z","iopub.execute_input":"2021-12-19T03:16:08.942147Z","iopub.status.idle":"2021-12-19T03:19:26.302740Z","shell.execute_reply.started":"2021-12-19T03:16:08.942102Z","shell.execute_reply":"2021-12-19T03:19:26.302177Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Feature importance.\n\nfi_df = pd.DataFrame()\nfi_df['features'] = features\nfi_df['importance'] = model.booster_.feature_importance(importance_type=\"gain\")\n\nfig, ax = plt.subplots(1,1, figsize = (6,12))\nsns.barplot(x ='importance', y ='features', data=fi_df.sort_values(by=['importance'], ascending=False), ax=ax)\nplt.savefig('feat_importance.png')","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:19:26.305925Z","iopub.execute_input":"2021-12-19T03:19:26.307354Z","iopub.status.idle":"2021-12-19T03:19:26.611928Z","shell.execute_reply.started":"2021-12-19T03:19:26.307316Z","shell.execute_reply":"2021-12-19T03:19:26.611248Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Based on weighted version of Pearson Correlation Coefficient.\n# Evaluation metric, provided by competition hosts after some time.\n# See: https://www.kaggle.com/c/g-research-crypto-forecasting/discussion/291845\n\ndef weighted_correlation(a, b, weights):\n\n    w = np.ravel(weights)\n    a = np.ravel(a)\n    b = np.ravel(b)\n\n    sum_w = np.sum(w)\n    mean_a = np.sum(a * w) / sum_w\n    mean_b = np.sum(b * w) / sum_w\n    var_a = np.sum(w * np.square(a - mean_a)) / sum_w\n    var_b = np.sum(w * np.square(b - mean_b)) / sum_w\n\n    cov = np.sum((a * b * w)) / np.sum(w) - mean_a * mean_b\n    corr = cov / np.sqrt(var_a * var_b)\n\n    return corr","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:19:26.612997Z","iopub.execute_input":"2021-12-19T03:19:26.613813Z","iopub.status.idle":"2021-12-19T03:19:26.621090Z","shell.execute_reply.started":"2021-12-19T03:19:26.613775Z","shell.execute_reply":"2021-12-19T03:19:26.620124Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Compute weighted correlations to evaluate model.\n\nmodel = joblib.load(os.path.join(CFG.OUTPUT_DIR, 'lgb_model_val.pkl'))\nval_df = train.query('train_flg == 0').copy()\nval_df['Prediction'] = model.predict(val_df[features])\n\nval_scores = []\n\nfor asset in val_df['Asset_ID'].unique():\n    \n    tmp = val_df.query('Asset_ID == @asset')\n    coin = tmp['Asset_Name'].values[0]\n    corr = weighted_correlation(tmp['Prediction'], tmp['Target'], tmp['Weight'])\n    val_scores.append(\" - {}: Validation Score (weighted correlation) = {:.4f}\".format(coin,corr))\n\n    try: plt.close()\n    except: pass\n    \n    fig = plt.figure(figsize = (12, 6))\n    ax_left = fig.add_subplot(111)\n    ax_left.set_facecolor('azure')   \n    ax_right = ax_left.twinx()\n    ax_left.plot(tmp['Target'][-15:], color = 'crimson', label =\"Target\")\n    ax_right.plot(tmp['Prediction'][-15:], color = 'darkgrey', label =\"Prediction\")\n    #plt.legend()\n    plt.grid()\n    plt.xlabel('Time')\n    plt.title('{}: Target (red) vs. Prediction (grey) [WCC = {:.4f}]'.format(coin,corr))\n    plt.show()\n    plt.savefig(\"{}.png\".format(asset))\n    \ncorr = weighted_correlation(val_df['Prediction'], val_df['Target'], val_df['Weight'])\nval_scores.append(\"=> Overall Validation Score (weighted correlation) = {:.4f}\".format(corr))\n\ntry: plt.close()\nexcept: pass\n\nfig = plt.figure(figsize = (12, 6))\nax_left = fig.add_subplot(111)\nax_left.set_facecolor('azure') \nax_right = ax_left.twinx()\nax_left.plot(val_df['Target'][-30:], color = 'crimson', label = \"Target\")\nax_right.plot(val_df['Prediction'][-30:], color = 'darkgrey', label = \"Prediction\")\n#plt.legend(\"Target\",\"Prediction\")\nplt.grid()\nplt.title('Overall: Target (red) vs. Prediction (grey) [WCC = {:.4f}]'.format(corr))\nplt.xlabel('Time')\nplt.show()\nplt.savefig('overall.png')\n","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:34:51.951142Z","iopub.execute_input":"2021-12-19T03:34:51.951424Z","iopub.status.idle":"2021-12-19T03:35:00.074787Z","shell.execute_reply.started":"2021-12-19T03:34:51.951392Z","shell.execute_reply":"2021-12-19T03:35:00.073825Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in val_scores:\n    print(i)","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:19:34.519284Z","iopub.execute_input":"2021-12-19T03:19:34.519556Z","iopub.status.idle":"2021-12-19T03:19:34.527117Z","shell.execute_reply.started":"2021-12-19T03:19:34.519522Z","shell.execute_reply":"2021-12-19T03:19:34.526298Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Rebuild Light Gradient Boosted Model with fewer trees.\n\nmodel = LGBMRegressor(n_estimators=101,\n                      #n_estimators=10001,\n                      objective='regression',\n                      metric='rmse',\n                      boosting_type='gbdt',\n                      max_depth=-1,\n                      learning_rate=0.01,\n                      feature_fraction=0.72,\n                      bagging_fraction=0.4,\n                      bagging_freq = 4,\n                      lambda_l1=1,\n                      lambda_l2=1,\n                      #subsample=0.72,\n                      #subsample_freq=4,\n                      #feature_fraction: 0.994\n                      #bagging_fraction: 0.632\n                      #bagging_freq: 5\n                      #lambda_l1: 9.4618\n                      #lambda_l2: 0.0003\n                      #num_leaves: 174\n                      #min_child_samples: 99\n                      seed=46)","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:19:34.528580Z","iopub.execute_input":"2021-12-19T03:19:34.528900Z","iopub.status.idle":"2021-12-19T03:19:34.536783Z","shell.execute_reply.started":"2021-12-19T03:19:34.528862Z","shell.execute_reply":"2021-12-19T03:19:34.535944Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train model on all data as, when submitted, G-Research will evaluate on completely unknown validation data.\n\nmodel.fit(\n    feature_df[features],\n    feature_df[target].values, \n    verbose=-1,\n    categorical_feature=categoricals,\n)\n\n# Save final model.\njoblib.dump(model, 'lgb_model.pkl')\nprint('final model saved')","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:19:34.538244Z","iopub.execute_input":"2021-12-19T03:19:34.538936Z","iopub.status.idle":"2021-12-19T03:21:58.658074Z","shell.execute_reply.started":"2021-12-19T03:19:34.538888Z","shell.execute_reply":"2021-12-19T03:21:58.657413Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import gresearch_crypto\n\nenv = gresearch_crypto.make_env()   # Initialize G-Research submission environment.\niter_test = env.iter_test()         # Iterator which loops over test set and sample submission.\n\nfor (test_df, sample_prediction_df) in iter_test:\n    \n    test_df = get_row_feats(test_df)                                   # Feature engineering.\n    sample_prediction_df['Target'] = model.predict(test_df[features])  # Make predictions (inference).\n    env.predict(sample_prediction_df)                                  # Register/submit predictions.","metadata":{"execution":{"iopub.status.busy":"2021-12-19T03:21:58.661404Z","iopub.execute_input":"2021-12-19T03:21:58.663101Z","iopub.status.idle":"2021-12-19T03:21:58.754577Z","shell.execute_reply.started":"2021-12-19T03:21:58.663067Z","shell.execute_reply":"2021-12-19T03:21:58.753997Z"},"trusted":true},"execution_count":null,"outputs":[]}]}