{"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\nfrom xgboost import XGBClassifier\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-02-26T17:41:56.595193Z","iopub.execute_input":"2023-02-26T17:41:56.595612Z","iopub.status.idle":"2023-02-26T17:41:57.207522Z","shell.execute_reply.started":"2023-02-26T17:41:56.595577Z","shell.execute_reply":"2023-02-26T17:41:57.206410Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"CATS = ['event_name', 'name','fqid', 'room_fqid', 'text_fqid']\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-02-26T17:41:57.209519Z","iopub.execute_input":"2023-02-26T17:41:57.210105Z","iopub.status.idle":"2023-02-26T17:41:57.216669Z","shell.execute_reply.started":"2023-02-26T17:41:57.210068Z","shell.execute_reply":"2023-02-26T17:41:57.215327Z"},"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-02-26T17:41:57.218457Z","iopub.execute_input":"2023-02-26T17:41:57.218890Z","iopub.status.idle":"2023-02-26T17:41:57.247573Z","shell.execute_reply.started":"2023-02-26T17:41:57.218853Z","shell.execute_reply":"2023-02-26T17:41:57.246652Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pickle\nf_read = open('/kaggle/input/magic-bingo-xgb-models/importance_dict.pkl', 'rb')\nimportance_dict = pickle.load(f_read)\nf_read.close()","metadata":{"execution":{"iopub.status.busy":"2023-02-26T17:41:57.249686Z","iopub.execute_input":"2023-02-26T17:41:57.250346Z","iopub.status.idle":"2023-02-26T17:41:57.267513Z","shell.execute_reply.started":"2023-02-26T17:41:57.250308Z","shell.execute_reply":"2023-02-26T17:41:57.266350Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import jo_wilder\nenv = jo_wilder.make_env()\niter_test = env.iter_test()","metadata":{"execution":{"iopub.status.busy":"2023-02-26T17:41:57.269062Z","iopub.execute_input":"2023-02-26T17:41:57.269727Z","iopub.status.idle":"2023-02-26T17:41:57.283789Z","shell.execute_reply.started":"2023-02-26T17:41:57.269654Z","shell.execute_reply":"2023-02-26T17:41:57.282505Z"},"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)\n\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        FEATURES = importance_dict[str(t)]\n        \n        model = XGBClassifier()\n        model.load_model(f'/kaggle/input/magic-bingo-xgb-models/XGB_question{t}.xgb')\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)","metadata":{"execution":{"iopub.status.busy":"2023-02-26T17:41:57.285428Z","iopub.execute_input":"2023-02-26T17:41:57.286099Z","iopub.status.idle":"2023-02-26T17:41:58.412418Z","shell.execute_reply.started":"2023-02-26T17:41:57.286059Z","shell.execute_reply":"2023-02-26T17:41:58.411252Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}