{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","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":218960,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":178227,"modelId":199794}],"dockerImageVersionId":30822,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport polars as pl\nimport polars.selectors as cs\n\nimport optuna\nimport lightgbm as lgb\n\nimport gc\nimport os\nimport joblib\n\nfrom pathlib import Path\nfrom tqdm.auto import tqdm\n\nimport kaggle_evaluation.jane_street_inference_server","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-04T16:25:50.187274Z","iopub.execute_input":"2025-01-04T16:25:50.187544Z","iopub.status.idle":"2025-01-04T16:25:55.108049Z","shell.execute_reply.started":"2025-01-04T16:25:50.187519Z","shell.execute_reply":"2025-01-04T16:25:55.107008Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class CFG:\n    data_dir = Path(\"/kaggle/input/jane-street-real-time-market-data-forecasting\")\n    target = \"responder_6\"\n    symbol = \"symbol_id\"\n    date = \"date_id\"\n    time = \"time_id\"\n    weight = \"weight\"\n    n_splits = 5\n    lag_ndays = 4\n    features = [f\"feature_{i:02d}\" for i in range(79)]\n    cat_features = [\"feature_09\", \"feature_10\", \"feature_11\"]\n    responders = [f\"responder_{i}\" for i in range(9)]\n    symbol_categories = list(range(39))\n    # for create lags\n    lag_1_features = [f\"responder_{i}_lag_1\" for i in range(9)]\n    lag_feature_regex = r\"^responder_\\d+_lag_\\d+$\"\n    lag_features = [\n        f\"responder_6_lag_{i+1}\" for i in range(lag_ndays)\n    ]\n    # for model\n    model_features = [symbol] + features + lag_features\n    mappings = [\n        {2: 0, 4: 1, 9: 2, 11: 3, 12: 4, 14: 5, 15: 6, 25: 7, 26: 8, 30: 9, 34: 10, 42: 11, 44: 12, 46: 13, 49: 14, 50: 15, 57: 16, 64: 17, 68: 18, 70: 19, 81: 20, 82: 21},\n        {1: 0, 2: 1, 3: 2, 4: 3, 5: 4, 6: 5, 7: 6, 10: 7, 12: 8},\n        {9: 0, 11: 1, 13: 2, 16: 3, 24: 4, 25: 5, 34: 6, 40: 7, 48: 8, 50: 9, 59: 10, 62: 11, 63: 12, 66: 13, 76: 14, 150: 15, 158: 16, 171: 17, 195: 18, 214: 19, 230: 20, 261: 21, 297: 22, 336: 23, 376: 24, 388: 25, 410: 26, 522: 27, 534: 28, 539: 29}\n    ]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-04T16:25:55.108962Z","iopub.execute_input":"2025-01-04T16:25:55.109504Z","iopub.status.idle":"2025-01-04T16:25:55.119610Z","shell.execute_reply.started":"2025-01-04T16:25:55.109476Z","shell.execute_reply":"2025-01-04T16:25:55.117692Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def remap_categories(df: pl.DataFrame, colname: str, mapping: dict) -> pl.DataFrame:\n    return df.with_columns(\n        pl.col(colname).replace_strict(mapping, default=-1, return_dtype=pl.Int32).alias(colname)\n    )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-04T16:25:55.120675Z","iopub.execute_input":"2025-01-04T16:25:55.120950Z","iopub.status.idle":"2025-01-04T16:25:55.139721Z","shell.execute_reply.started":"2025-01-04T16:25:55.120927Z","shell.execute_reply":"2025-01-04T16:25:55.138675Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = joblib.load(\"/kaggle/input/js24-lgb/other/v2/18/lgb_v19.pkl\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-04T16:25:55.142119Z","iopub.execute_input":"2025-01-04T16:25:55.142465Z","iopub.status.idle":"2025-01-04T16:25:55.184313Z","shell.execute_reply.started":"2025-01-04T16:25:55.142374Z","shell.execute_reply":"2025-01-04T16:25:55.183511Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"lags_ : pl.DataFrame | None = None\n\n\n# Replace this function with your inference code.\n# You can return either a Pandas or Polars dataframe, though Polars is recommended.\n# Each batch of predictions (except the very first) must be returned within 1 minute of the batch features being provided.\ndef predict(test: pl.DataFrame, lags: pl.DataFrame | None) -> pl.DataFrame | pd.DataFrame:\n    \"\"\"Make a prediction.\"\"\"\n    # All the responders from the previous day are passed in at time_id == 0. We save them in a global variable for access at every time_id.\n    # Use them as extra features, if you like.\n    global lags_, model\n    if lags is not None:\n        lags_ = lags\n\n    # Replace this section with your own predictions\n    predictions = test.select(\n        \"row_id\",\n        pl.lit(0.0).alias(\"responder_6\"),\n    )\n\n    if not lags is None:\n        lags = (\n            lags.group_by([CFG.date, CFG.symbol], maintain_order=True)\n            .last()\n            .select(cs.by_name(CFG.date, CFG.symbol, CFG.lag_1_features))\n            .group_by(CFG.symbol, maintain_order=True)\n            .map_groups(\n                lambda group_df: group_df.with_columns(\n                    cs.by_name(CFG.lag_1_features).shift(1).name.map(lambda colname: colname[:-1] + \"2\"),\n                    cs.by_name(CFG.lag_1_features).shift(2).name.map(lambda colname: colname[:-1] + \"3\"),\n                    cs.by_name(CFG.lag_1_features).shift(3).name.map(lambda colname: colname[:-1] + \"4\")\n                )\n            )\n            .select(cs.by_name(CFG.date, CFG.symbol), cs.matches(CFG.lag_feature_regex))\n        )\n        test = test.join(lags, on=[CFG.date, CFG.symbol], how=\"left\")\n    else:\n        test = test.with_columns([pl.lit(0.0).alias(colname) for colname in CFG.lag_features])\n\n    for i, col in enumerate(CFG.cat_features):\n        test = remap_categories(test, col, CFG.mappings[i])\n        \n    X_test = test.select(cs.by_name(CFG.model_features)).to_numpy()\n    y_hat = model.predict(X_test)\n    predictions = predictions.with_columns(pl.Series(name=\"responder_6\", values=y_hat))\n\n    if isinstance(predictions, pl.DataFrame):\n        assert predictions.columns == [\"row_id\", \"responder_6\"]\n    elif isinstance(predictions, pd.DataFrame):\n        assert (predictions.columns == [\"row_id\", \"responder_6\"]).all()\n    else:\n        raise TypeError(\"The predict function must return a DataFrame\")\n    # Confirm has as many rows as the test data.\n    assert len(predictions) == len(test)\n\n    return predictions","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-04T16:25:55.185112Z","iopub.execute_input":"2025-01-04T16:25:55.185348Z","iopub.status.idle":"2025-01-04T16:25:55.196344Z","shell.execute_reply.started":"2025-01-04T16:25:55.185326Z","shell.execute_reply":"2025-01-04T16:25:55.195643Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"inference_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    )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-04T16:25:55.197214Z","iopub.execute_input":"2025-01-04T16:25:55.197961Z","iopub.status.idle":"2025-01-04T16:25:55.656588Z","shell.execute_reply.started":"2025-01-04T16:25:55.197932Z","shell.execute_reply":"2025-01-04T16:25:55.655294Z"}},"outputs":[],"execution_count":null}]}