{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.11.11"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":96164,"databundleVersionId":11418275,"sourceType":"competition"}],"dockerImageVersionId":31040,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false},"papermill":{"default_parameters":{},"duration":40783.654575,"end_time":"2025-05-28T20:50:48.056289","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2025-05-28T09:31:04.401714","version":"2.6.0"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Imports and configs","metadata":{"papermill":{"duration":0.004884,"end_time":"2025-05-28T09:31:09.316484","exception":false,"start_time":"2025-05-28T09:31:09.311600","status":"completed"},"tags":[]}},{"cell_type":"code","source":"!uv pip install -q --system autogluon scikit-learn==1.5.2","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_kg_hide-output":true,"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","papermill":{"duration":14.61724,"end_time":"2025-05-28T09:31:23.937966","exception":false,"start_time":"2025-05-28T09:31:09.320726","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from autogluon.tabular import TabularPredictor\nfrom autogluon.core.metrics import make_scorer\nfrom sklearn.model_selection import KFold\nfrom scipy.stats import pearsonr as pr\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport pandas as pd\nimport numpy as np\nimport warnings\nimport joblib\nimport os\n\nwarnings.filterwarnings(\"ignore\")","metadata":{"papermill":{"duration":5.354043,"end_time":"2025-05-28T09:31:29.296773","exception":false,"start_time":"2025-05-28T09:31:23.942730","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class CFG:\n    train_path = \"/kaggle/input/drw-crypto-market-prediction/train.parquet\"\n    test_path = \"/kaggle/input/drw-crypto-market-prediction/test.parquet\"\n    sample_sub_path = \"/kaggle/input/drw-crypto-market-prediction/sample_submission.csv\"\n    \n    target = \"label\"\n    n_folds = 5\n    seed = 42\n    time_limit = 3600 * 11","metadata":{"papermill":{"duration":0.011871,"end_time":"2025-05-28T09:31:29.313388","exception":false,"start_time":"2025-05-28T09:31:29.301517","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Loading data and predefining folds","metadata":{"papermill":{"duration":0.003982,"end_time":"2025-05-28T09:31:29.321811","exception":false,"start_time":"2025-05-28T09:31:29.317829","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def reduce_mem_usage(dataframe, dataset):    \n    print('Reducing memory usage for:', dataset)\n    initial_mem_usage = dataframe.memory_usage().sum() / 1024**2\n    \n    for col in dataframe.columns:\n        col_type = dataframe[col].dtype\n\n        c_min = dataframe[col].min()\n        c_max = dataframe[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                dataframe[col] = dataframe[col].astype(np.int8)\n            elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:\n                dataframe[col] = dataframe[col].astype(np.int32)\n            elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:\n                dataframe[col] = dataframe[col].astype(np.int32)\n            elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:\n                dataframe[col] = dataframe[col].astype(np.int64)\n        else:\n            if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:\n                dataframe[col] = dataframe[col].astype(np.float32)\n            elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:\n                dataframe[col] = dataframe[col].astype(np.float32)\n            else:\n                dataframe[col] = dataframe[col].astype(np.float64)\n\n    final_mem_usage = dataframe.memory_usage().sum() / 1024**2\n    print('--- Memory usage before: {:.2f} MB'.format(initial_mem_usage))\n    print('--- Memory usage after: {:.2f} MB'.format(final_mem_usage))\n    print('--- Decreased memory usage by {:.1f}%\\n'.format(100 * (initial_mem_usage - final_mem_usage) / initial_mem_usage))\n\n    return dataframe","metadata":{"trusted":true,"_kg_hide-input":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train = pd.read_parquet(CFG.train_path).reset_index(drop=True)\ntest = pd.read_parquet(CFG.test_path).reset_index(drop=True)","metadata":{"papermill":{"duration":74.603156,"end_time":"2025-05-28T09:32:43.984797","exception":false,"start_time":"2025-05-28T09:31:29.381641","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train = reduce_mem_usage(train, \"train\")\ntest = reduce_mem_usage(test, \"test\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"kf = KFold(n_splits=CFG.n_folds, shuffle=False)\nsplit = kf.split(train, train[CFG.target])\nfor i, (_, val_index) in enumerate(split):\n    train.loc[val_index, \"fold\"] = i","metadata":{"papermill":{"duration":0.067061,"end_time":"2025-05-28T09:32:44.056719","exception":false,"start_time":"2025-05-28T09:32:43.989658","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Fitting the predictor","metadata":{"papermill":{"duration":0.004162,"end_time":"2025-05-28T09:32:44.065539","exception":false,"start_time":"2025-05-28T09:32:44.061377","status":"completed"},"tags":[]}},{"cell_type":"code","source":"%%writefile custom_metric.py\n\nfrom autogluon.core.metrics import make_scorer\nfrom scipy.stats import pearsonr as pr\n\ndef pearsonr(y_true, y_pred):\n    return pr(y_true, y_pred)[0]\n\nag_pearsonr = make_scorer(\n    name='pearsonr',\n    score_func=pearsonr,\n    optimum=1,\n    greater_is_better=True\n)","metadata":{"papermill":{"duration":0.011664,"end_time":"2025-05-28T09:32:44.081468","exception":false,"start_time":"2025-05-28T09:32:44.069804","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from custom_metric import ag_pearsonr\n\npredictor = TabularPredictor(\n    path=\"/logs\",\n    problem_type=\"regression\",\n    eval_metric=ag_pearsonr,\n    label=CFG.target,\n    groups=\"fold\",\n    verbosity=2\n)","metadata":{"_kg_hide-output":true,"papermill":{"duration":0.012003,"end_time":"2025-05-28T09:32:44.098822","exception":false,"start_time":"2025-05-28T09:32:44.086819","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predictor.fit(\n    train_data=train,\n    time_limit=CFG.time_limit,\n    presets=\"best_quality\",\n    excluded_model_types=[\"KNN\", \"RF\"],\n    feature_prune_kwargs={'force_prune': True}\n)","metadata":{"_kg_hide-output":true,"papermill":{"duration":39604.014757,"end_time":"2025-05-28T20:32:48.118291","exception":false,"start_time":"2025-05-28T09:32:44.103534","status":"completed"},"scrolled":true,"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predictor.leaderboard(silent=True).style.background_gradient(subset=[\"score_val\"], cmap=\"RdYlGn\")","metadata":{"papermill":{"duration":0.125026,"end_time":"2025-05-28T20:32:48.270542","exception":false,"start_time":"2025-05-28T20:32:48.145516","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Visualizing the ensemble weights","metadata":{"papermill":{"duration":0.016533,"end_time":"2025-05-28T20:32:48.307974","exception":false,"start_time":"2025-05-28T20:32:48.291441","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def get_ensemble_weights(predictor):\n    info = predictor.info()\n    ensemble_weights = {}\n    for model_name, values in info[\"model_info\"].items():\n        if \"Ensemble\" in model_name:\n            children_info = values[\"children_info\"]\n            ensemble_weights[model_name] = values[\"children_info\"][list(children_info.keys())[0]][\"model_weights\"]\n    return ensemble_weights","metadata":{"papermill":{"duration":0.02573,"end_time":"2025-05-28T20:32:48.350367","exception":false,"start_time":"2025-05-28T20:32:48.324637","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ensemble_weights = get_ensemble_weights(predictor)\n\nfor key, value in ensemble_weights.items():\n    plt.figure(figsize=(6, 6))\n    plt.pie(value.values(), labels=value.keys(), autopct=\"%1.1f%%\", colors=sns.color_palette(\"Set2\", len(value)))\n    plt.title(key)\n    plt.tight_layout()\n    plt.show()","metadata":{"papermill":{"duration":17.541316,"end_time":"2025-05-28T20:33:05.913980","exception":false,"start_time":"2025-05-28T20:32:48.372664","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Collecting and saving OOF files","metadata":{"papermill":{"duration":0.016776,"end_time":"2025-05-28T20:33:05.948465","exception":false,"start_time":"2025-05-28T20:33:05.931689","status":"completed"},"tags":[]}},{"cell_type":"code","source":"joblib.dump(predictor.info()[\"features\"], \"features.pkl\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def save_preds(preds, cv_score, name, type, is_ensemble):\n    base_path = \"oof_preds\" if type == \"oof\" else \"test_preds\"\n    base_path = \".\" if is_ensemble else base_path\n    joblib.dump(preds, f\"{base_path}/{name}_{type}_preds_{cv_score:.6f}.pkl\")\n\ndef save_submission(test_preds, score):\n    sub = pd.read_csv(CFG.sample_sub_path)\n    sub[\"prediction\"] = test_preds\n    sub.to_csv(f\"sub_autogluon_{score:.6f}.csv\", index=False)\n    \nos.makedirs(\"oof_preds\", exist_ok=True)\nos.makedirs(\"test_preds\", exist_ok=True)","metadata":{"papermill":{"duration":0.025215,"end_time":"2025-05-28T20:33:05.990563","exception":false,"start_time":"2025-05-28T20:33:05.965348","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"oof_preds = {}\ntest_preds = {}\n\noverall_scores = {}","metadata":{"papermill":{"duration":0.022894,"end_time":"2025-05-28T20:33:06.030555","exception":false,"start_time":"2025-05-28T20:33:06.007661","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def pearsonr(y_true, y_pred):\n    return pr(y_true, y_pred)[0]","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"best_model = predictor.model_best\n_test_preds = predictor.predict_multi(test)\nfor model in predictor.model_names():\n    model_oof_preds = predictor.predict_oof(model).values\n    model_test_preds = _test_preds[model].values\n    \n    cv_score = pr(train[CFG.target], model_oof_preds)[0]\n    if model != best_model:\n        save_preds(model_oof_preds, cv_score, model, \"oof\", False)\n        save_preds(model_test_preds, cv_score, model, \"test\", False)\n    else:\n        save_preds(model_oof_preds, cv_score, model, \"oof\", True)\n        save_preds(model_test_preds, cv_score, model, \"test\", True)\n        save_submission(model_test_preds, cv_score)\n        \n    oof_preds[model] = model_oof_preds\n    test_preds[model] = model_test_preds\n\n    overall_scores[model] = [pr(model_oof_preds, train[CFG.target])[0]]","metadata":{"_kg_hide-output":true,"papermill":{"duration":1057.522857,"end_time":"2025-05-28T20:50:43.570449","exception":false,"start_time":"2025-05-28T20:33:06.047592","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Visualizing the results","metadata":{"papermill":{"duration":0.01787,"end_time":"2025-05-28T20:50:43.618776","exception":false,"start_time":"2025-05-28T20:50:43.600906","status":"completed"},"tags":[]}},{"cell_type":"code","source":"fold_scores = {}\nsplit = KFold(n_splits=CFG.n_folds, shuffle=False).split(train, train[CFG.target])\nfor fold_idx, (train_index, val_index) in enumerate(split):\n    for model in predictor.model_names():\n        fold_score = pr(train.loc[val_index, CFG.target], oof_preds[model][val_index])[0]\n        if model not in fold_scores:\n            fold_scores[model] = []\n        fold_scores[model].append(fold_score)","metadata":{"papermill":{"duration":0.315784,"end_time":"2025-05-28T20:50:43.952027","exception":false,"start_time":"2025-05-28T20:50:43.636243","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fold_scores = pd.DataFrame(fold_scores)\noverall_scores = pd.DataFrame(overall_scores).transpose().sort_values(by=0, ascending=False)\norder = overall_scores.index.tolist()\n\nmin_score = overall_scores.values.flatten().min()\nmax_score = overall_scores.values.flatten().max()\npadding = (max_score - min_score) * 0.5\nlower_limit = min_score - padding\nupper_limit = max_score + padding\n\nfig, axs = plt.subplots(1, 2, figsize=(15, fold_scores.shape[1] * 0.3))\n\nboxplot = sns.boxplot(data=fold_scores, order=order, ax=axs[0], orient=\"h\", palette=\"RdYlGn_r\")\naxs[0].set_title(f\"Fold Score\")\naxs[0].set_xlabel(\"\")\naxs[0].set_ylabel(\"\")\n\nbarplot = sns.barplot(x=overall_scores.values.flatten(), y=overall_scores.index, ax=axs[1], palette=\"RdYlGn_r\")\naxs[1].set_title(f\"Overall Score\")\naxs[1].set_xlabel(\"\")\naxs[1].set_xlim(left=lower_limit, right=upper_limit)\naxs[1].set_ylabel(\"\")\n\nfor i, (score, model) in enumerate(zip(overall_scores.values.flatten(), overall_scores.index)):\n    barplot.text(score, i, round(score, 6), va=\"center\")\n\nplt.tight_layout()\nplt.show()","metadata":{"papermill":{"duration":0.46331,"end_time":"2025-05-28T20:50:44.432943","exception":false,"start_time":"2025-05-28T20:50:43.969633","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null}]}