{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":96164,"databundleVersionId":11418275,"sourceType":"competition"}],"dockerImageVersionId":31041,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"### Hey there! 😊 If you found this notebook helpful, dropping an upvote would really make my day.","metadata":{}},{"cell_type":"markdown","source":"## 📌 1. Import Libraries","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport shap\n\nimport numpy as np\nimport pandas as pd\nfrom sklearn.model_selection import KFold\nfrom xgboost import XGBRegressor\nfrom scipy.stats import pearsonr","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-16T16:50:35.558833Z","iopub.execute_input":"2025-06-16T16:50:35.559032Z","iopub.status.idle":"2025-06-16T16:50:45.093789Z","shell.execute_reply.started":"2025-06-16T16:50:35.559015Z","shell.execute_reply":"2025-06-16T16:50:45.093004Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 📂 2. Load Dataset","metadata":{}},{"cell_type":"markdown","source":"The following technique/code is adapted from Kaggle Master Mahdi Ravaghi’s work.\nYou can find more details in his original [notebook](https://www.kaggle.com/code/ravaghi/drw-crypto-market-prediction-ensemble).","metadata":{}},{"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\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-16T16:50:45.094580Z","iopub.execute_input":"2025-06-16T16:50:45.094980Z","iopub.status.idle":"2025-06-16T16:50:45.098789Z","shell.execute_reply.started":"2025-06-16T16:50:45.094961Z","shell.execute_reply":"2025-06-16T16:50:45.098123Z"}},"outputs":[],"execution_count":null},{"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.int16)\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.float16)\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,"execution":{"iopub.status.busy":"2025-06-16T16:50:45.100141Z","iopub.execute_input":"2025-06-16T16:50:45.100332Z","iopub.status.idle":"2025-06-16T16:50:45.116797Z","shell.execute_reply.started":"2025-06-16T16:50:45.100317Z","shell.execute_reply":"2025-06-16T16:50:45.116279Z"}},"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)\nsample=pd.read_csv(\"/kaggle/input/drw-crypto-market-prediction/sample_submission.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-16T16:50:45.117568Z","iopub.execute_input":"2025-06-16T16:50:45.117833Z","iopub.status.idle":"2025-06-16T16:51:35.805284Z","shell.execute_reply.started":"2025-06-16T16:50:45.117811Z","shell.execute_reply":"2025-06-16T16:51:35.804506Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 📊 3. Selected Features Based on SHAP Values","metadata":{}},{"cell_type":"code","source":"selected_features = [\n    \"X863\", \"X856\", \"X344\", \"X598\", \"X862\", \"X385\", \"X852\", \"X603\", \"X860\", \"X674\",\n    \"X415\", \"X345\", \"X137\", \"X855\", \"X174\", \"X302\", \"X178\", \"X532\", \"X168\", \"X612\",\n    \"X888\",\"X421\",\"X333\",\n    \"bid_qty\", \"ask_qty\", \"buy_qty\", \"sell_qty\", \"volume\"\n]\n\n\ntrain= train[selected_features + [\"label\"]]\ntest= test[selected_features]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-16T16:51:35.809072Z","iopub.execute_input":"2025-06-16T16:51:35.809453Z","iopub.status.idle":"2025-06-16T16:51:36.037002Z","shell.execute_reply.started":"2025-06-16T16:51:35.809435Z","shell.execute_reply":"2025-06-16T16:51:36.036411Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train = reduce_mem_usage(train, \"train\")\ntest = reduce_mem_usage(test, \"test\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-16T16:51:36.037648Z","iopub.execute_input":"2025-06-16T16:51:36.037861Z","iopub.status.idle":"2025-06-16T16:51:36.335112Z","shell.execute_reply.started":"2025-06-16T16:51:36.037845Z","shell.execute_reply":"2025-06-16T16:51:36.334317Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Train=\",train.shape)\nprint(\"Test=\",test.shape)\nprint(\"Sample=\",sample.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-16T16:51:53.142088Z","iopub.execute_input":"2025-06-16T16:51:53.142838Z","iopub.status.idle":"2025-06-16T16:51:53.146908Z","shell.execute_reply.started":"2025-06-16T16:51:53.142811Z","shell.execute_reply":"2025-06-16T16:51:53.146238Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"RMV = [\"label\"]\nFEATURES = [c for c in train.columns if not c in RMV]\nprint(f\"There are {len(FEATURES)} FEATURES: {FEATURES}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-16T16:51:54.125970Z","iopub.execute_input":"2025-06-16T16:51:54.126666Z","iopub.status.idle":"2025-06-16T16:51:54.130993Z","shell.execute_reply.started":"2025-06-16T16:51:54.126641Z","shell.execute_reply":"2025-06-16T16:51:54.130205Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 🚀 4. Train XGBoost with KFold Cross-Validation","metadata":{}},{"cell_type":"markdown","source":"In earlier versions of this notebook, the training data was explicitly shuffled prior to cross-validation.\nIn the current setup, however, the KFold strategy is used without shuffling","metadata":{}},{"cell_type":"code","source":"FOLDS = 5\nkf = KFold(n_splits=FOLDS)\n\noof_preds = np.zeros(len(train))\ntest_preds = np.zeros(len(test))\n\nxgb_params = {\n    \"tree_method\": \"gpu_hist\",\n    \"colsample_bylevel\": 0.4778015829774066,\n    \"colsample_bynode\": 0.362764358742407,\n    \"colsample_bytree\": 0.7107423488010493,\n    \"gamma\": 1.7094857725240398,\n    \"learning_rate\": 0.02213323588455387,\n    \"max_depth\": 20,\n    \"max_leaves\": 12,\n    \"min_child_weight\": 16,\n    \"n_estimators\": 1667,\n    \"n_jobs\": -1,\n    \"random_state\": 42,\n    \"reg_alpha\": 39.352415706891264,\n    \"reg_lambda\": 75.44843704068275,\n    \"subsample\": 0.06566669853471274,\n    \"verbosity\": 0\n}\n\nfor i, (train_idx, valid_idx) in enumerate(kf.split(train)):\n    print(\"#\" * 25)\n    print(f\"### Fold {i + 1}\")\n    print(\"#\" * 25)\n\n    X_train = train.iloc[train_idx][FEATURES]\n    y_train = train.iloc[train_idx][\"label\"]\n    X_valid = train.iloc[valid_idx][FEATURES]\n    y_valid = train.iloc[valid_idx][\"label\"]\n    X_test = test[FEATURES]\n\n    model = XGBRegressor(**xgb_params)\n\n    model.fit(\n        X_train, y_train,\n        eval_set=[(X_valid, y_valid)],\n        verbose=200\n    )\n\n    oof_preds[valid_idx] = model.predict(X_valid)\n    test_preds += model.predict(X_test)\n\npearson_score = pearsonr(train[\"label\"], oof_preds)[0]\nprint(\"Final Pearson Correlation = \", pearson_score)\n\ntest_preds /= FOLDS","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-16T16:57:03.106261Z","iopub.execute_input":"2025-06-16T16:57:03.106775Z","iopub.status.idle":"2025-06-16T16:57:56.857475Z","shell.execute_reply.started":"2025-06-16T16:57:03.106740Z","shell.execute_reply":"2025-06-16T16:57:56.856655Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 📌 5. SHAP Explainability","metadata":{}},{"cell_type":"code","source":"explainer = shap.TreeExplainer(model, feature_perturbation=\"tree_path_dependent\", model_output=\"raw\")\nshap_values = explainer.shap_values(X_test)\nshap.summary_plot(shap_values, X_test)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T17:23:29.347601Z","iopub.execute_input":"2025-05-28T17:23:29.348081Z","iopub.status.idle":"2025-05-28T17:24:40.012084Z","shell.execute_reply.started":"2025-05-28T17:23:29.348058Z","shell.execute_reply":"2025-05-28T17:24:40.011417Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 📤 6. Create Submission File","metadata":{}},{"cell_type":"code","source":"sample[\"prediction\"] = test_preds\nsample.to_csv(\"submission.csv\", index=False)\nsample.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-16T16:58:16.437451Z","iopub.execute_input":"2025-06-16T16:58:16.437994Z","iopub.status.idle":"2025-06-16T16:58:17.479680Z","shell.execute_reply.started":"2025-06-16T16:58:16.437970Z","shell.execute_reply":"2025-06-16T16:58:17.479114Z"}},"outputs":[],"execution_count":null}]}