{"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":"# Crypto Forecasting - Basic LGBM\n\nBasic lgbm, using standard Feature Engineering from here: ","metadata":{}},{"cell_type":"code","source":"import gresearch_crypto\n\nimport pandas as pd\nimport numpy as np\nimport os\nimport gc\nimport pickle\n\nimport time\nfrom datetime import datetime\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nimport lightgbm as lgb\n\nimport warnings\n\nbase_seed = 0\n\nDEBUG = False\n\nif ~DEBUG:\n    warnings.filterwarnings(\"ignore\")","metadata":{"execution":{"iopub.status.busy":"2022-01-02T15:21:06.06505Z","iopub.execute_input":"2022-01-02T15:21:06.065753Z","iopub.status.idle":"2022-01-02T15:21:08.491762Z","shell.execute_reply.started":"2022-01-02T15:21:06.065653Z","shell.execute_reply":"2022-01-02T15:21:08.4907Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# https://stackoverflow.com/questions/38641691/weighted-correlation-coefficient-with-pandas\ndef wmean(x, w):\n    return np.sum(x * w) / np.sum(w)\n\ndef wcov(x, y, w):\n    return np.sum(w * (x - wmean(x, w)) * (y - wmean(y, w))) / np.sum(w)\n\ndef wcorr(x, y, w):\n    return wcov(x, y, w) / np.sqrt(wcov(x, x, w) * wcov(y, y, w))\n\ndef eval_wcorr(preds, train_data):\n    w = train_data.add_w.values.flatten()\n    y_true = train_data.get_label()\n    return 'eval_wcorr', wcorr(preds, y_true, w), True\n\nasset_details = pd.read_csv('../input/g-research-crypto-forecasting/asset_details.csv')\n\n#create dictionnary of weights\ndict_weights = {}\nfor i in range(asset_details.shape[0]):\n    dict_weights[asset_details.iloc[i,0]] = asset_details.iloc[i,1]\n","metadata":{"execution":{"iopub.status.busy":"2022-01-02T15:21:08.493538Z","iopub.execute_input":"2022-01-02T15:21:08.493786Z","iopub.status.idle":"2022-01-02T15:21:08.522653Z","shell.execute_reply.started":"2022-01-02T15:21:08.493756Z","shell.execute_reply":"2022-01-02T15:21:08.521849Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"n_fold = 2 if DEBUG else 5\nn_seed = 2 if DEBUG else 5\n\nimportances = []\nmodels = {}\nES_it = {}\ndf_scores = []\n\n#start early stopping after this number of rows\nlow = 100\n\nSAMPLE = False\n\nfor fold in range(n_fold):\n    \n    train = pd.read_parquet('../input/on-line-feature-engineering/train_fold_'+str(fold)+'.parquet')\n    test = pd.read_parquet('../input/on-line-feature-engineering/test_fold_'+str(fold)+'.parquet')\n\n    if DEBUG or SAMPLE:\n        timestamp_sample_train = train.timestamp.unique()[:np.int(len(train.timestamp.unique())*0.1)]\n        timestamp_sample_test = test.timestamp.unique()[:np.int(len(test.timestamp.unique())*0.1)]\n        train = train[train.timestamp.isin(timestamp_sample_train)]\n        test = test[test.timestamp.isin(timestamp_sample_test)]\n\n\n    train['weights'] = train.Asset_ID.map(dict_weights).astype('float32')\n    test['weights'] = test.Asset_ID.map(dict_weights).astype('float32')    \n\n    y_train = train['Target']\n    y_test = test['Target']\n\n    features = [col for col in train.columns if col not in {'timestamp', 'Target', 'Target_M','weights','Asset_ID'}]\n\n    weights_train = train[['weights']]\n    weights_test = test[['weights']]\n\n    train = train[features]\n    test = test[features]\n\n    for seed in range(n_seed):    \n        print('Fold: '+str(fold)+ ' - seed: '+str(seed))\n\n        train_dataset = lgb.Dataset(train, y_train, feature_name = features)#, categorical_feature= ['Asset_ID'])\n        val_dataset = lgb.Dataset(test, y_test, feature_name = features)#, categorical_feature= ['Asset_ID'])\n\n        train_dataset.add_w = weights_train\n        val_dataset.add_w = weights_test\n\n        val_data = test\n        val_y = y_test\n        \n        evals_result = {}\n\n        # parameters\n        # objective_params = [0.0001,0.001,0.01,0.1,1,10]\n\n        params = {'n_estimators': 2500,\n                'objective': 'regression',  #objectives = ['regression','regression_l1', 'huber', 'fair','quantile', 'mape', 'gamma','tweedie']\n                #'fair_c': 100,\n                'metric': 'None',\n                'boosting_type': 'gbdt',\n                'max_depth': -1,\n                'learning_rate': 0.005,\n                'subsample': 0.4,\n                'subsample_freq': 4,\n                'feature_fraction': 0.4,\n                'lambda_l1': 1,\n                'lambda_l2': 1,\n                'seed': base_seed+seed,\n                'verbose': -1,\n                'min_data_in_leaf':100\n                }\n\n        model = lgb.train(params = params,\n                          train_set = train_dataset, \n                          valid_sets = [val_dataset],\n                          #early_stopping_rounds=1000,\n                          verbose_eval = 100,\n                          feval= eval_wcorr,\n                          evals_result = evals_result \n                         )\n        \n        key = str(fold)+'-'+str(seed) \n        \n        early_stopping_it = low + np.argmax(np.array(evals_result['valid_0']['eval_wcorr'])[low:])\n        \n        models[key] = model\n        ES_it[key] = early_stopping_it\n        \n        df_scores.append((fold, seed, np.max(np.array(evals_result['valid_0']['eval_wcorr'])[low:])))\n\n        importances.append(model.feature_importance(importance_type='gain'))\n\n        plt.plot(np.array(evals_result['valid_0']['eval_wcorr']), label= 'fold '+str(fold)+' seed '+str(seed))\n        \n    plt.legend(loc=\"upper left\", bbox_to_anchor=(1, 0.5))\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-02T15:22:01.681611Z","iopub.execute_input":"2022-01-02T15:22:01.681875Z","iopub.status.idle":"2022-01-02T15:22:04.424857Z","shell.execute_reply.started":"2022-01-02T15:22:01.681848Z","shell.execute_reply":"2022-01-02T15:22:04.422955Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_results = pd.DataFrame(df_scores,columns=['fold','seed','score']).pivot(index='fold',columns='seed',values='score')\n\ndf_results.loc['seed_mean']= df_results.mean(numeric_only=True, axis=0)\ndf_results.loc[:,'fold_mean'] = df_results.mean(numeric_only=True, axis=1)\ndf_results","metadata":{"execution":{"iopub.status.busy":"2022-01-02T19:14:05.779548Z","iopub.execute_input":"2022-01-02T19:14:05.780106Z","iopub.status.idle":"2022-01-02T19:14:05.856796Z","shell.execute_reply.started":"2022-01-02T19:14:05.780015Z","shell.execute_reply":"2022-01-02T19:14:05.855595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"from nyanp's Optiver solution.","metadata":{}},{"cell_type":"code","source":"def plot_importance(importances, features_names = features, PLOT_TOP_N = 20, figsize=(10, 10)):\n    importance_df = pd.DataFrame(data=importances, columns=features)\n    sorted_indices = importance_df.median(axis=0).sort_values(ascending=False).index\n    sorted_importance_df = importance_df.loc[:, sorted_indices]\n    plot_cols = sorted_importance_df.columns[:PLOT_TOP_N]\n    _, ax = plt.subplots(figsize=figsize)\n    ax.grid()\n    ax.set_xscale('log')\n    ax.set_ylabel('Feature')\n    ax.set_xlabel('Importance')\n    sns.boxplot(data=sorted_importance_df[plot_cols],\n                orient='h',\n                ax=ax)\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-02T15:21:59.461156Z","iopub.status.idle":"2022-01-02T15:21:59.461539Z","shell.execute_reply.started":"2022-01-02T15:21:59.461352Z","shell.execute_reply":"2022-01-02T15:21:59.461375Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_importance(np.array(importances),features, PLOT_TOP_N = 20, figsize=(10, 20))","metadata":{"execution":{"iopub.status.busy":"2022-01-02T15:21:59.462793Z","iopub.status.idle":"2022-01-02T15:21:59.463136Z","shell.execute_reply.started":"2022-01-02T15:21:59.462958Z","shell.execute_reply":"2022-01-02T15:21:59.46298Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pickle.dump(models, open('lgbm_models.pkl', 'wb'))\npickle.dump(df_scores, open('scores.pkl', 'wb'))\npickle.dump(ES_it, open('ES_it.pkl', 'wb'))\npickle.dump(importances, open('importances.pkl', 'wb'))\npickle.dump(features, open('features.pkl', 'wb'))","metadata":{"execution":{"iopub.status.busy":"2022-01-02T15:21:59.464849Z","iopub.status.idle":"2022-01-02T15:21:59.465231Z","shell.execute_reply.started":"2022-01-02T15:21:59.465041Z","shell.execute_reply":"2022-01-02T15:21:59.465059Z"},"trusted":true},"execution_count":null,"outputs":[]}]}