{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":84493,"databundleVersionId":9871156,"sourceType":"competition"},{"sourceId":9935211,"sourceType":"datasetVersion","datasetId":6107762},{"sourceId":9939150,"sourceType":"datasetVersion","datasetId":6110654}],"dockerImageVersionId":30786,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport polars as pl\nimport numpy as np\nimport os, gc\nfrom tqdm.auto import tqdm\nimport pickle\nfrom sklearn.metrics import r2_score\nimport kaggle_evaluation.jane_street_inference_server","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2024-11-18T08:49:49.391848Z","iopub.execute_input":"2024-11-18T08:49:49.392312Z","iopub.status.idle":"2024-11-18T08:49:50.000378Z","shell.execute_reply.started":"2024-11-18T08:49:49.392270Z","shell.execute_reply":"2024-11-18T08:49:49.999176Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from xgboost import XGBRegressor","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-18T08:49:50.002555Z","iopub.execute_input":"2024-11-18T08:49:50.003154Z","iopub.status.idle":"2024-11-18T08:49:50.008736Z","shell.execute_reply.started":"2024-11-18T08:49:50.003103Z","shell.execute_reply":"2024-11-18T08:49:50.007392Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\nfrom lightgbm import Booster as LGBBooster\nfrom catboost import CatBoostRegressor\nimport joblib","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-18T08:49:50.010203Z","iopub.execute_input":"2024-11-18T08:49:50.010646Z","iopub.status.idle":"2024-11-18T08:49:50.024801Z","shell.execute_reply.started":"2024-11-18T08:49:50.010604Z","shell.execute_reply":"2024-11-18T08:49:50.023626Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Configuration\nclass CONFIG:\n    seed = 42\n    target_col = \"responder_6\"\n    feature_cols = [\"symbol_id\", \"time_id\"] + [f\"feature_{idx:02d}\" for idx in range(79)] + [f\"responder_{idx}_lag_1\" for idx in range(9)]\n    model_path = '/kaggle/input/ensemblev2-1'\n\nxgb_model = XGBRegressor()\nxgb_model.load_model(f\"{CONFIG.model_path}/xgb_model.json\")\n\nlgb_model = LGBBooster(model_file=f\"{CONFIG.model_path}/lgb_model.txt\")\n\ncat_model = CatBoostRegressor()\ncat_model.load_model(f\"{CONFIG.model_path}/cat_model.cbm\")\n\n\n\nwith open(f\"{CONFIG.model_path}/ensemble_metadata.pkl\", \"rb\") as f:\n    ensemble_metadata = pickle.load(f)\n\nprint(\"Loaded models successfully.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-18T08:49:54.404847Z","iopub.execute_input":"2024-11-18T08:49:54.405299Z","iopub.status.idle":"2024-11-18T08:49:54.514857Z","shell.execute_reply.started":"2024-11-18T08:49:54.405255Z","shell.execute_reply":"2024-11-18T08:49:54.513575Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ensemble_weights = ensemble_metadata[\"weights\"]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-18T08:49:57.101413Z","iopub.execute_input":"2024-11-18T08:49:57.101874Z","iopub.status.idle":"2024-11-18T08:49:57.107511Z","shell.execute_reply.started":"2024-11-18T08:49:57.101828Z","shell.execute_reply":"2024-11-18T08:49:57.106256Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Print loaded models for verification\nprint(\"Loaded Models:\")\nprint(\"XGBoost:\", xgb_model)\nprint(\"LightGBM:\", lgb_model)\nprint(\"CatBoost:\", cat_model)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-18T08:49:57.406416Z","iopub.execute_input":"2024-11-18T08:49:57.406872Z","iopub.status.idle":"2024-11-18T08:49:57.417888Z","shell.execute_reply.started":"2024-11-18T08:49:57.406827Z","shell.execute_reply":"2024-11-18T08:49:57.416691Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Validate on the provided validation data (optional sanity check)\nvalid = pl.scan_parquet(\n    f\"/kaggle/input/js-data-v2/validation.parquet\"\n).collect().to_pandas()\n\nX_valid = valid[CONFIG.feature_cols]\ny_valid = valid[CONFIG.target_col]\nw_valid = valid[\"weight\"]\n\n# Check R² score on validation\ndef evaluate_model(model, X, y, w):\n    preds = model.predict(X)\n    return r2_score(y, preds, sample_weight=w)\n\nxgb_score = evaluate_model(xgb_model, X_valid, y_valid, w_valid)\nlgb_score = evaluate_model(lgb_model, X_valid, y_valid, w_valid)\ncat_score = evaluate_model(cat_model, X_valid, y_valid, w_valid)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-18T08:50:49.694274Z","iopub.execute_input":"2024-11-18T08:50:49.694729Z","iopub.status.idle":"2024-11-18T08:51:16.088031Z","shell.execute_reply.started":"2024-11-18T08:50:49.694687Z","shell.execute_reply":"2024-11-18T08:51:16.086728Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Weighted Ensemble Validation\nensemble_preds = (\n    ensemble_weights[0] * xgb_model.predict(X_valid) +\n    ensemble_weights[1] * lgb_model.predict(X_valid) +\n    ensemble_weights[2] * cat_model.predict(X_valid)\n)\n\nensemble_score = r2_score(y_valid, ensemble_preds, sample_weight=w_valid)\n\nprint(f\"Validation Scores:\")\nprint(f\"XGBoost R²: {xgb_score:.5f}\")\nprint(f\"LightGBM R²: {lgb_score:.5f}\")\nprint(f\"CatBoost R²: {cat_score:.5f}\")\nprint(f\"Weighted Ensemble R²: {ensemble_score:.5f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-18T08:51:16.089892Z","iopub.execute_input":"2024-11-18T08:51:16.090427Z","iopub.status.idle":"2024-11-18T08:51:35.820545Z","shell.execute_reply.started":"2024-11-18T08:51:16.090380Z","shell.execute_reply":"2024-11-18T08:51:35.819305Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"del valid, X_valid, y_valid, w_valid\ngc.collect()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Predict Function for Inference\nlags_: pl.DataFrame | None = None\n\ndef predict(test: pl.DataFrame, lags: pl.DataFrame | None) -> pl.DataFrame | pd.DataFrame:\n    global lags_\n\n    if lags is not None:\n        lags_ = lags\n\n    # Add lagged features\n    if lags_ is not None:\n        lags_ = lags_.group_by([\"date_id\", \"symbol_id\"], maintain_order=True).last()\n        test = test.join(lags_, on=[\"date_id\", \"symbol_id\"], how=\"left\")\n    else:\n        test = test.with_columns(\n            (pl.lit(0.0).alias(f'responder_{idx}_lag_1') for idx in range(9))\n        )\n\n    # Base Model Predictions\n    xgb_preds = xgb_model.predict(test[CONFIG.feature_cols].to_pandas())\n    lgb_preds = lgb_model.predict(test[CONFIG.feature_cols].to_pandas())\n    cat_preds = cat_model.predict(test[CONFIG.feature_cols].to_pandas())\n\n    # Weighted Ensemble Predictions\n    ensemble_preds = (\n        ensemble_weights[0] * xgb_preds +\n        ensemble_weights[1] * lgb_preds +\n        ensemble_weights[2] * cat_preds\n    )\n\n\n    # Final Predictions (Choose Stacking or Weighted Ensemble)\n    final_preds = np.clip(ensemble_preds, a_min=-5, a_max=5)\n\n    # Prepare Output\n    predictions = test.select('row_id').with_columns(\n        pl.Series(\n            name=\"responder_6\",\n            values=final_preds,\n            dtype=pl.Float64\n        )\n    )\n\n    # Ensure submission format\n    assert isinstance(predictions, pl.DataFrame | pd.DataFrame)\n    assert list(predictions.columns) == ['row_id', 'responder_6']\n    assert len(predictions) == len(test)\n\n    return predictions\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Initialize Inference Server\ninference_server = kaggle_evaluation.jane_street_inference_server.JSInferenceServer(predict)\n\nif os.getenv('KAGGLE_IS_COMPETITION_RERUN'):\n    inference_server.serve()\nelse:\n    inference_server.run_local_gateway(\n        (\n            '/kaggle/input/jane-street-real-time-market-data-forecasting/test.parquet',\n            '/kaggle/input/jane-street-real-time-market-data-forecasting/lags.parquet',\n        )\n    )\n","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}