{"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":"My train part is [Here](https://www.kaggle.com/code/takanashihumbert/magic-bingo-train-part-lb-0-687)","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport gc\nimport pickle\nimport polars as pl\nfrom sklearn.model_selection import KFold, GroupKFold\n# from xgboost import XGBoost\nfrom catboost import CatBoostClassifier # Changed to CatBoostClassifier\nfrom sklearn.metrics import f1_score\nfrom tqdm.notebook import tqdm\nfrom collections import defaultdict\nimport warnings\nfrom itertools import combinations\n\nwarnings.filterwarnings('ignore')\npd.set_option(\"display.max_columns\", None)\npd.set_option(\"display.max_rows\", 200) ","metadata":{"execution":{"iopub.status.busy":"2023-03-07T05:04:26.246837Z","iopub.execute_input":"2023-03-07T05:04:26.247654Z","iopub.status.idle":"2023-03-07T05:04:28.226147Z","shell.execute_reply.started":"2023-03-07T05:04:26.247609Z","shell.execute_reply":"2023-03-07T05:04:28.225113Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# CATS = ['event_name', 'name','fqid', 'room_fqid', 'text_fqid']\n# Added `text` and `level`, otherwise, the code would raise errors \n# reminded us that some of its unique features didn't exist.\nCATS = ['event_name', 'name','fqid', 'room_fqid', 'text_fqid','text','level']\n\nevent_name_feature = ['cutscene_click', 'person_click', 'navigate_click',\n       'observation_click', 'notification_click', 'object_click',\n       'object_hover', 'map_hover', 'map_click', 'checkpoint',\n       'notebook_click']\n\nname_feature = ['basic', 'undefined', 'close', 'open', 'prev', 'next']\n\nNUMS = [ \n        'page', \n        'room_coor_x', \n        'room_coor_y', \n        'screen_coor_x', \n        'screen_coor_y', \n        'hover_duration', \n        'elapsed_time_diff'] ","metadata":{"execution":{"iopub.status.busy":"2023-03-07T05:04:28.228696Z","iopub.execute_input":"2023-03-07T05:04:28.230350Z","iopub.status.idle":"2023-03-07T05:04:28.240208Z","shell.execute_reply.started":"2023-03-07T05:04:28.230304Z","shell.execute_reply":"2023-03-07T05:04:28.239257Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def feature_engineer(x, grp, use_extra, feature_suffix):\n        \n    aggs = [\n        pl.col(\"index\").count().alias(f\"session_number_{feature_suffix}\"),\n        *[pl.col(c).drop_nulls().n_unique().alias(f\"{c}_unique_{feature_suffix}\") for c in CATS],\n        *[pl.col(c).mean().alias(f\"{c}_mean_{feature_suffix}\") for c in NUMS],\n        *[pl.col(c).min().alias(f\"{c}_min_{feature_suffix}\") for c in NUMS],\n        *[pl.col(c).max().alias(f\"{c}_max_{feature_suffix}\") for c in NUMS],\n        *[pl.col(\"elapsed_time_diff\").filter(pl.col(\"event_name\")==c).mean().alias(f\"{c}_ET_mean_{feature_suffix}\") for c in event_name_feature],\n        *[pl.col(\"elapsed_time_diff\").filter(pl.col(\"event_name\")==c).max().alias(f\"{c}_ET_max_{feature_suffix}\") for c in event_name_feature],\n        *[pl.col(\"elapsed_time_diff\").filter(pl.col(\"event_name\")==c).min().alias(f\"{c}_ET_min_{feature_suffix}\") for c in event_name_feature],\n        *[pl.col(\"elapsed_time_diff\").filter(pl.col(\"name\")==c).mean().alias(f\"{c}_ET_mean_{feature_suffix}\") for c in name_feature],\n        *[pl.col(\"elapsed_time_diff\").filter(pl.col(\"name\")==c).max().alias(f\"{c}_ET_max_{feature_suffix}\") for c in name_feature],\n        *[pl.col(\"elapsed_time_diff\").filter(pl.col(\"name\")==c).min().alias(f\"{c}_ET_min_{feature_suffix}\") for c in name_feature],\n    ]\n    \n    df = x.groupby([\"session_id\"], maintain_order=True).agg(aggs).sort(\"session_id\")\n    \n    if use_extra:\n        if grp=='5-12':\n            aggs = [\n                pl.col(\"elapsed_time\").filter((pl.col(\"text\")==\"Here's the log book.\")|(pl.col(\"fqid\")=='logbook.page.bingo')).apply(lambda s: s.max()-s.min()).alias(\"logbook_bingo_duration\"),\n                pl.col(\"index\").filter((pl.col(\"text\")==\"Here's the log book.\")|(pl.col(\"fqid\")=='logbook.page.bingo')).apply(lambda s: s.max()-s.min()).alias(\"logbook_bingo_indexCount\"),\n                pl.col(\"elapsed_time\").filter(((pl.col(\"event_name\")=='navigate_click')&(pl.col(\"fqid\")=='reader'))|(pl.col(\"fqid\")==\"reader.paper2.bingo\")).apply(lambda s: s.max()-s.min()).alias(\"reader_bingo_duration\"),\n                pl.col(\"index\").filter(((pl.col(\"event_name\")=='navigate_click')&(pl.col(\"fqid\")=='reader'))|(pl.col(\"fqid\")==\"reader.paper2.bingo\")).apply(lambda s: s.max()-s.min()).alias(\"reader_bingo_indexCount\"),\n                pl.col(\"elapsed_time\").filter(((pl.col(\"event_name\")=='navigate_click')&(pl.col(\"fqid\")=='journals'))|(pl.col(\"fqid\")==\"journals.pic_2.bingo\")).apply(lambda s: s.max()-s.min()).alias(\"journals_bingo_duration\"),\n                pl.col(\"index\").filter(((pl.col(\"event_name\")=='navigate_click')&(pl.col(\"fqid\")=='journals'))|(pl.col(\"fqid\")==\"journals.pic_2.bingo\")).apply(lambda s: s.max()-s.min()).alias(\"journals_bingo_indexCount\"),\n            ]\n            tmp = x.groupby([\"session_id\"], maintain_order=True).agg(aggs).sort(\"session_id\")\n            df = df.join(tmp, on=\"session_id\", how='left')\n\n        if grp=='13-22':\n            aggs = [\n                pl.col(\"elapsed_time\").filter(((pl.col(\"event_name\")=='navigate_click')&(pl.col(\"fqid\")=='reader_flag'))|(pl.col(\"fqid\")==\"tunic.library.microfiche.reader_flag.paper2.bingo\")).apply(lambda s: s.max()-s.min() if s.len()>0 else 0).alias(\"reader_flag_duration\"),\n                pl.col(\"index\").filter(((pl.col(\"event_name\")=='navigate_click')&(pl.col(\"fqid\")=='reader_flag'))|(pl.col(\"fqid\")==\"tunic.library.microfiche.reader_flag.paper2.bingo\")).apply(lambda s: s.max()-s.min() if s.len()>0 else 0).alias(\"reader_flag_indexCount\"),\n                pl.col(\"elapsed_time\").filter(((pl.col(\"event_name\")=='navigate_click')&(pl.col(\"fqid\")=='journals_flag'))|(pl.col(\"fqid\")==\"journals_flag.pic_0.bingo\")).apply(lambda s: s.max()-s.min() if s.len()>0 else 0).alias(\"journalsFlag_bingo_duration\"),\n                pl.col(\"index\").filter(((pl.col(\"event_name\")=='navigate_click')&(pl.col(\"fqid\")=='journals_flag'))|(pl.col(\"fqid\")==\"journals_flag.pic_0.bingo\")).apply(lambda s: s.max()-s.min() if s.len()>0 else 0).alias(\"journalsFlag_bingo_indexCount\")\n            ]\n            tmp = x.groupby([\"session_id\"], maintain_order=True).agg(aggs).sort(\"session_id\")\n            df = df.join(tmp, on=\"session_id\", how='left')\n        \n    return df.to_pandas() ","metadata":{"execution":{"iopub.status.busy":"2023-03-07T05:04:28.243517Z","iopub.execute_input":"2023-03-07T05:04:28.244297Z","iopub.status.idle":"2023-03-07T05:04:28.272008Z","shell.execute_reply.started":"2023-03-07T05:04:28.244251Z","shell.execute_reply":"2023-03-07T05:04:28.270922Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pickle\n# f_read = open('/kaggle/input/magic-bingo-xgb-models/importance_dict.pkl', 'rb')\n# modified our path to `importance_dict.pkl`\nf_read = open('/kaggle/input/csc532-magic-bingo-catboost-baseline-train/importance_dict.pkl', 'rb')\nimportance_dict = pickle.load(f_read) # load pkl\nf_read.close()  # close the file reader","metadata":{"execution":{"iopub.status.busy":"2023-03-07T05:04:28.274425Z","iopub.execute_input":"2023-03-07T05:04:28.275195Z","iopub.status.idle":"2023-03-07T05:04:28.302797Z","shell.execute_reply.started":"2023-03-07T05:04:28.275141Z","shell.execute_reply":"2023-03-07T05:04:28.301581Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import jo_wilder\nenv = jo_wilder.make_env()\niter_test = env.iter_test() # gain test iterator","metadata":{"execution":{"iopub.status.busy":"2023-03-07T05:04:28.303787Z","iopub.execute_input":"2023-03-07T05:04:28.304138Z","iopub.status.idle":"2023-03-07T05:04:28.326876Z","shell.execute_reply.started":"2023-03-07T05:04:28.304103Z","shell.execute_reply":"2023-03-07T05:04:28.325855Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"limits = {'0-4':(1,4), '5-12':(4,14), '13-22':(14,19)}\n# Remember to change the threshold\nbest_threshold = 0.615\n\nhistorical_meta = defaultdict(list)","metadata":{"execution":{"iopub.status.busy":"2023-03-07T05:04:28.328354Z","iopub.execute_input":"2023-03-07T05:04:28.329523Z","iopub.status.idle":"2023-03-07T05:04:28.334899Z","shell.execute_reply.started":"2023-03-07T05:04:28.329476Z","shell.execute_reply":"2023-03-07T05:04:28.333854Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# `iter_test` is only called ONCE, it would throw error if we run it again.  \nfor (sample_submission, test) in iter_test: \n    grp = test.level_group.values[0]\n    session_id = test.session_id.values[0]\n    \n    columns = [\n        pl.col(\"page\").cast(pl.Float32),\n        (\n            (pl.col(\"elapsed_time\") - pl.col(\"elapsed_time\").shift(1))\n             .fill_null(0)\n             .clip(0, 1e9)\n             .alias(\"elapsed_time_diff\")\n        ),\n        (\n            (pl.col(\"screen_coor_x\") - pl.col(\"screen_coor_x\").shift(1)).abs()\n        ),\n        (\n            (pl.col(\"screen_coor_y\") - pl.col(\"screen_coor_y\").shift(1)).abs()\n        ),\n        pl.col(\"fqid\").fill_null(\"fqid_None\"),\n        pl.col(\"text_fqid\").fill_null(\"text_fqid_None\")\n    ]\n\n    test = (pl.from_pandas(test)\n          .drop([\"fullscreen\", \"hq\", \"music\"])\n          .with_columns(columns))\n    \n    # FEATURE ENGINEER TEST DATA\n    test = feature_engineer(test, grp, use_extra=True, feature_suffix='')\n    \n    # INFER TEST DATA\n    a,b = limits[grp]\n    for t in range(a, b):\n        \n        FEATURES = importance_dict[str(t)]\n#         model = XGBoostClassifier()\n        model = CatBoostClassifier() # using `CatBoostClassifier` instead of `XGBoostClassifier`\n        model.load_model(f'/kaggle/input/csc532-magic-bingo-catboost-baseline-train/CB_question{t}.cb')\n        \n        p = model.predict_proba(test[FEATURES].astype('float32'))[:,1]\n        mask = sample_submission.session_id.str.contains(f'q{t}')\n        sample_submission.loc[mask,'correct'] = int(p.item()>best_threshold)\n             \n    env.predict(sample_submission) # predict `sample_submission`","metadata":{"execution":{"iopub.status.busy":"2023-03-07T05:04:28.336836Z","iopub.execute_input":"2023-03-07T05:04:28.337672Z","iopub.status.idle":"2023-03-07T05:04:29.705990Z","shell.execute_reply.started":"2023-03-07T05:04:28.337628Z","shell.execute_reply":"2023-03-07T05:04:29.704724Z"},"trusted":true},"execution_count":null,"outputs":[]}]}