{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.10","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":45533,"databundleVersionId":5748852,"sourceType":"competition"},{"sourceId":7849969,"sourceType":"datasetVersion","datasetId":3321599}],"dockerImageVersionId":30513,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Notebook Memo\nEveryone, you all worked so hard during this long competition period!\nThe scripts I'm sharing here are a single LGBM model that achieved a Private Score of 0.701.\n\nFor the features, I basically nicked some ideas from ONELUX's Feature Engineering notebook. \nAnd from the raw data, I worked out the 'mouse moving distance' for each index, and then calculated the 'mouse speed' from this distance. \nThese features were used to fitting model. \nAlso, I tried adding the predicted probabilities for each question as features for the next question.\n\nBecause these features didn't perform well on the public score, I decided to abandon them, even though it made me a bit sad.\nBut after the competition, they actually showed pretty good performance on the private score. \nIf I had known there was such a gap between the private and public scores, I would have used these feature sets more. \nBut, as this was my first competition and I was participating solo, I lacked experience. \n\nThanks to Chris Deotte and ONELUX's code, I was able to smoothly finish this competition. I am very grateful!\n\n<b>** Scripts of Feature Engineering & Fitting parts are on my Github repository. \nhttps://github.com/Mokee04/KaggleHub/tree/77c43603443c6ebdeaff72ebb39bbeb25b6e21ec/Predict_Student_Performance\n\n1. Feature Engineering\n    - Features From ONELUX\n    https://www.kaggle.com/code/leehomhuang/catboost-baseline-with-lots-features-inference\n    - ++ Velocity(mouse speed) & moving distance Features\n    - No Processing Missing values\n    <br>\n    <br> The NB of Features by Questions \n    <br> 1301, 1931, 2282 + predict_proba for Prior-Questions \n    <br><br>\n2. Fitting LGBM Single model\n    - Tuned params\n    - Best threshold : 0.614\n    - CV : 0.705 / LB public 0.699,  private 0.701\n    - output : (AF)LGBM_v0.1.pickle","metadata":{}},{"cell_type":"code","source":"import re\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pylab as plt\nimport seaborn as sns \nimport pickle\nimport joblib\nfrom tqdm import tqdm\n\nimport polars as pl\nfrom sklearn.model_selection import StratifiedKFold\n\nfrom lightgbm import LGBMClassifier\nfrom sklearn.metrics import f1_score\n\nimport warnings\nwarnings.simplefilter(action='ignore')","metadata":{"papermill":{"duration":3.372177,"end_time":"2023-06-06T17:47:55.959140","exception":false,"start_time":"2023-06-06T17:47:52.586963","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-03-15T08:56:34.574712Z","iopub.execute_input":"2024-03-15T08:56:34.575035Z","iopub.status.idle":"2024-03-15T08:56:37.884532Z","shell.execute_reply.started":"2024-03-15T08:56:34.575006Z","shell.execute_reply":"2024-03-15T08:56:37.883733Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load fitted LGBM Model.\nfit_all = joblib.load('/kaggle/input/pspl-onkaggle/(RM)LGBM_v0.01_fs.pickle')\nbase_feats = fit_all[\"base_feats\"]\nbest_model = fit_all[\"best_model\"]\n#best_thr = fit_all[\"best_thr\"]\nbest_thr = 0.614","metadata":{"papermill":{"duration":1.971208,"end_time":"2023-06-06T17:47:57.936804","exception":false,"start_time":"2023-06-06T17:47:55.965596","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-03-15T08:56:37.887788Z","iopub.execute_input":"2024-03-15T08:56:37.889052Z","iopub.status.idle":"2024-03-15T08:56:39.700277Z","shell.execute_reply.started":"2024-03-15T08:56:37.889004Z","shell.execute_reply":"2024-03-15T08:56:39.699073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"feature_true = []\nfor q in range(1, 19) :\n    idx = 0 if q <= 3 else 1 if q <= 13 else 2\n    feature_true.append(base_feats[idx])","metadata":{"execution":{"iopub.status.busy":"2024-03-15T08:56:39.704589Z","iopub.execute_input":"2024-03-15T08:56:39.706542Z","iopub.status.idle":"2024-03-15T08:56:39.712477Z","shell.execute_reply.started":"2024-03-15T08:56:39.706506Z","shell.execute_reply":"2024-03-15T08:56:39.711472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"NB of Features : {[len(feature_true[q]) for q in range(18)]}\\n\")\nprint(f\"Model Params : {best_model['Q1'].get_params()}\\n\")\nprint(f\"Best threshold : {best_thr}\")","metadata":{"papermill":{"duration":0.026612,"end_time":"2023-06-06T17:47:57.970040","exception":false,"start_time":"2023-06-06T17:47:57.943428","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-03-15T08:56:39.716829Z","iopub.execute_input":"2024-03-15T08:56:39.718553Z","iopub.status.idle":"2024-03-15T08:56:39.729344Z","shell.execute_reply.started":"2024-03-15T08:56:39.718524Z","shell.execute_reply":"2024-03-15T08:56:39.728570Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# For Calculating Features from test data","metadata":{}},{"cell_type":"code","source":"# For making features from features' name list. \ndef remove_quotes(text):\n    return re.sub(r\"[`'/\\\\ *]\", \"\", text)\n\ndef ext_col(col_name) :\n    pattern = r\"col_\"\n    if col_name.startswith(pattern) :\n        pattern = r\"col_\"\n        ext = col_name[len(pattern):].split(\"_\")[0]\n    else :\n        ext = None\n                \n    return ext\n\ndef ext_agg(col_name) :\n    pattern = r\"_agg_(.*)\"\n    res = re.search(pattern, col_name)\n    if res :\n        ext = res.group(1)\n    else : \n        ext = None\n    \n    return ext\n\ndef ext_fil(col_name) :\n    start_index = col_name.find(\"fil_\")\n    if start_index != -1:\n        start_index += len(\"fil_\")\n        end_index = col_name.find(\"_\", start_index)\n        ext = col_name[start_index:end_index]\n    else:\n        ext = None\n    return ext\n\ndef ext_filc(col_name) :\n    start_index = col_name.find(\"filc_\")\n    if start_index != -1:\n        start_index += len(\"filc_\")\n        end_index = col_name.find(\"_\", start_index)\n        ext = col_name[start_index:end_index]\n    else:\n        ext = None\n    return ext\n\ndef ext_val(col_name) :\n    if \"val_\" in col_name:\n        start_index = col_name.find(\"val_\") + len(\"val_\")\n        end_index = col_name.find(\"_agg\", start_index)\n        ext = col_name[start_index:end_index]\n        if ext == '':\n            ext = None\n        return ext\n    else:\n        return None\n\ndef add_features(col_name) :\n    code_col = ext_col(col_name)\n    code_agg = ext_agg(col_name)\n    code_fil = ext_fil(col_name)\n    code_filc = ext_filc(col_name)\n    code_val = ext_val(col_name)\n\n    col_vs = { \"idx\" : \"index\", \n              \"et\" : \"elapsed_time\",\n              \"en\" : \"event_name\", \n              \"nm\" : \"name\",\n              \"lv\" : \"level\",\n              \"pg\" : \"page\",\n              \"rcx\" : \"room_coor_x\",\n              \"rcy\" : \"room_coor_y\", \n              \"scx\" : \"screen_coor_x\", \n              \"scy\" : \"screen_coor_y\", \n              \"hd\" : \"hover_duration\", \n              \"txt\" : \"text\", \n              \"fq\" : \"fqid\", \n              \"rf\" : \"room_fqid\", \n              \"tfq\" : \"text_fqid\", \n              \"lvg\" : \"level_group\", \n              \"etd\" : \"elapsed_time_diff\", \n              \"md\" : \"move_distance\",\n              \"vc\" : \"velocity\"}\n\n    if code_agg == \"nunique\" :\n        add_col = f\"pl.col('{col_vs[code_col]}').drop_nulls().n_unique().alias('{col_name}')\"\n    \n    elif code_agg == \"rep\" :  \n        ###############################################################################\n            if \"logbook_bingo_duration_agg_rep\" in col_name : \n                add_col = (pl.col(\"elapsed_time\").filter((pl.col(\"text\") == \"Here's the log book.\") | (pl.col(\"fqid\") == 'logbook.page.bingo'))\n            .apply(lambda s: s.max() - s.min()).alias(\"logbook_bingo_duration_agg_rep\"))\n\n            if \"logbook_bingo_indexCount_agg_rep\" in col_name :\n                 add_col = (pl.col(\"index\").filter((pl.col(\"text\") == \"Here's the log book.\") | (pl.col(\"fqid\") == 'logbook.page.bingo'))\n                    .apply(lambda s: s.max() - s.min()).alias(\"logbook_bingo_indexCount_agg_rep\"))\n\n            if \"reader_bingo_duration_agg_rep\" in col_name :\n                add_col = (pl.col(\"elapsed_time\").filter(((pl.col(\"event_name\") == 'navigate_click') & (pl.col(\"fqid\") == 'reader')) | \n                    (pl.col(\"fqid\") == \"reader.paper2.bingo\")).apply(lambda s: s.max() - s.min()).alias(\"reader_bingo_duration_agg_rep\"))\n\n            if \"reader_bingo_indexCount_agg_rep\" in col_name :\n                add_col = (pl.col(\"index\").filter(((pl.col(\"event_name\") == 'navigate_click') & (pl.col(\"fqid\") == 'reader')) | \n                    (pl.col(\"fqid\") == \"reader.paper2.bingo\")).apply(lambda s: s.max() - s.min()).alias(\"reader_bingo_indexCount_agg_rep\"))\n\n            if \"journals_bingo_duration_agg_rep\" in col_name :\n                add_col = (pl.col(\"elapsed_time\").filter(((pl.col(\"event_name\") == 'navigate_click') & (pl.col(\"fqid\") == 'journals')) | \n                (pl.col(\"fqid\") == \"journals.pic_2.bingo\")).apply(lambda s: s.max() - s.min()).alias(\"journals_bingo_duration_agg_rep\"))\n\n            if \"journals_bingo_indexCount_agg_rep\" in col_name : \n                add_col = (pl.col(\"index\").filter(((pl.col(\"event_name\") == 'navigate_click') & (pl.col(\"fqid\") == 'journals')) | \n                (pl.col(\"fqid\") == \"journals.pic_2.bingo\")).apply(lambda s: s.max() - s.min()).alias(\"journals_bingo_indexCount_agg_rep\"))\n\n            if \"reader_flag_duration_agg_rep\" in col_name :\n                add_col = (pl.col(\"elapsed_time\").filter(((pl.col(\"event_name\") == 'navigate_click') & (pl.col(\"fqid\") == 'reader_flag')) | \n                (pl.col(\"fqid\") == \"tunic.library.microfiche.reader_flag.paper2.bingo\"))\n                .apply(lambda s: s.max() - s.min() if s.len() > 0 else 0).alias(\"reader_flag_duration_agg_rep\"))\n\n            if \"reader_flag_indexCount_agg_rep\" in col_name :\n                add_col = (pl.col(\"index\").filter(((pl.col(\"event_name\") == 'navigate_click') & (pl.col(\"fqid\") == 'reader_flag')) | \n                (pl.col(\"fqid\") == \"tunic.library.microfiche.reader_flag.paper2.bingo\"))\n                .apply(lambda s: s.max() - s.min() if s.len() > 0 else 0).alias(\"reader_flag_indexCount_agg_rep\"))\n\n            if \"journalsFlag_bingo_duration_agg_rep\" in col_name :\n                add_col = (pl.col(\"elapsed_time\").filter(((pl.col(\"event_name\") == 'navigate_click') & (pl.col(\"fqid\") == 'journals_flag')) | \n                (pl.col(\"fqid\") == \"journals_flag.pic_0.bingo\"))\n                .apply(lambda s: s.max() - s.min() if s.len() > 0 else 0).alias(\"journalsFlag_bingo_duration_agg_rep\"))\n\n            if \"journalsFlag_bingo_indexCount_agg_rep\" in col_name :\n                add_col = (pl.col(\"index\").filter(((pl.col(\"event_name\") == 'navigate_click') & (pl.col(\"fqid\") == 'journals_flag')) | \n                (pl.col(\"fqid\") == \"journals_flag.pic_0.bingo\"))\n                .apply(lambda s: s.max() - s.min() if s.len() > 0 else 0).alias(\"journalsFlag_bingo_indexCount_agg_rep\"))\n\n        ###############################################################################\n    else :\n        if code_val == None :\n            add_col = f\"pl.col('{col_vs[code_col]}').{code_agg}().alias('{col_name}')\"\n\n        else :\n            if code_fil != None :\n                add_col = f\"pl.col('{col_vs[code_col]}').filter(pl.col('{col_vs[code_fil]}') == '{code_val}').{code_agg}().alias('{col_name}')\"\n            elif code_filc != None :\n                add_col = f\"pl.col('{col_vs[code_col]}').filter((pl.col('{col_vs[code_filc]}').str.contains('{code_val}'))).{code_agg}().alias('{col_name}')\"\n    \n    return eval(add_col) if type(add_col) == str else add_col","metadata":{"papermill":{"duration":0.060481,"end_time":"2023-06-06T17:47:58.037382","exception":false,"start_time":"2023-06-06T17:47:57.976901","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-03-15T08:56:39.732765Z","iopub.execute_input":"2024-03-15T08:56:39.734548Z","iopub.status.idle":"2024-03-15T08:56:39.759203Z","shell.execute_reply.started":"2024-03-15T08:56:39.734513Z","shell.execute_reply":"2024-03-15T08:56:39.757593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def time_feature(df):\n    df[\"year\"] = df[\"session_id\"].apply(lambda x: int(str(x)[:2])).astype(np.uint8)\n    df[\"month\"] = df[\"session_id\"].apply(lambda x: int(str(x)[2:4])+1).astype(np.uint8)\n    df[\"day\"] = df[\"session_id\"].apply(lambda x: int(str(x)[4:6])).astype(np.uint8)\n    df[\"hour\"] = df[\"session_id\"].apply(lambda x: int(str(x)[6:8])).astype(np.uint8)\n    df[\"minute\"] = df[\"session_id\"].apply(lambda x: int(str(x)[8:10])).astype(np.uint8)\n    df[\"second\"] = df[\"session_id\"].apply(lambda x: int(str(x)[10:12])).astype(np.uint8)\n\n    return df.set_index(\"session_id\")\n\ndef hm_feature(test, grp) :\n    if grp == \"0-4\":\n        idx = 0\n    elif grp == \"5-12\":\n        idx = 1\n    else:\n        idx = 2\n    #############################################################################################\n    \"\"\" 1st \"\"\"\n    feat = \"col_pluso_txt_agg_count_deal_mean\"\n    idx_feat0 = ['col_idx_filc_txt_val_the_agg_count',\n                 'col_idx_filc_txt_val_can_agg_count',\n                 'col_idx_filc_txt_val_is_agg_count',\n                 'col_idx_filc_txt_val_notebook_agg_count',\n                 'col_idx_filc_txt_val_need_agg_count',\n                 'col_idx_filc_txt_val_Ooh_agg_count',\n                 'col_idx_filc_txt_val_it_agg_count',\n                 'col_idx_filc_txt_val_that_agg_count',\n                 'col_idx_filc_txt_val_you_agg_count',\n                 'col_idx_filc_txt_val_Jo_agg_count',\n                 'col_idx_filc_txt_val_to_agg_count',\n                 'col_idx_filc_txt_val_Wells_agg_count',\n                 'col_idx_filc_txt_val_find_agg_count',\n                 'col_idx_filc_txt_val_help_agg_count',\n                 'col_idx_filc_txt_val_and_agg_count',\n                 'col_idx_filc_txt_val_Found_agg_count',\n                 'col_idx_filc_txt_val_this_agg_count']\n\n    idx_feat1 = ['col_idx_filc_txt_val_the_agg_count',\n                 'col_idx_filc_txt_val_can_agg_count',\n                 'col_idx_filc_txt_val_is_agg_count',\n                 'col_idx_filc_txt_val_Oh_agg_count',\n                 'col_idx_filc_txt_val_need_agg_count',\n                 'col_idx_filc_txt_val_Ooh_agg_count',\n                 'col_idx_filc_txt_val_it_agg_count',\n                 'col_idx_filc_txt_val_that_agg_count',\n                 'col_idx_filc_txt_val_you_agg_count',\n                 'col_idx_filc_txt_val_Jo_agg_count',\n                 'col_idx_filc_txt_val_to_agg_count',\n                 'col_idx_filc_txt_val_Wells_agg_count',\n                 'col_idx_filc_txt_val_found_agg_count',\n                 'col_idx_filc_txt_val_find_agg_count',\n                 'col_idx_filc_txt_val_help_agg_count',\n                 'col_idx_filc_txt_val_and_agg_count',\n                 'col_idx_filc_txt_val_this_agg_count']\n\n    idx_feat2 = ['col_idx_filc_txt_val_the_agg_count',\n                 'col_idx_filc_txt_val_can_agg_count',\n                 'col_idx_filc_txt_val_is_agg_count',\n                 'col_idx_filc_txt_val_Oh_agg_count',\n                 'col_idx_filc_txt_val_need_agg_count',\n                 'col_idx_filc_txt_val_Ooh_agg_count',\n                 'col_idx_filc_txt_val_it_agg_count',\n                 'col_idx_filc_txt_val_that_agg_count',\n                 'col_idx_filc_txt_val_you_agg_count',\n                 'col_idx_filc_txt_val_Jo_agg_count',\n                 'col_idx_filc_txt_val_to_agg_count',\n                 'col_idx_filc_txt_val_Wells_agg_count',\n                 'col_idx_filc_txt_val_found_agg_count',\n                 'col_idx_filc_txt_val_find_agg_count',\n                 'col_idx_filc_txt_val_help_agg_count',\n                 'col_idx_filc_txt_val_and_agg_count',\n                 'col_idx_filc_txt_val_this_agg_count',\n                 'col_idx_filc_txt_val_flag_agg_count']\n\n    idx_feat = [idx_feat0, idx_feat1, idx_feat2]\n    test[feat] = test[idx_feat[idx]].mean(axis=1)\n    #############################################################################################\n    \"\"\" 2nd \"\"\"\n    feat = \"col_pluso_txt_agg_count_deal_sum\"\n    idx_feat0 = ['col_idx_filc_txt_val_the_agg_count',\n                 'col_idx_filc_txt_val_can_agg_count',\n                 'col_idx_filc_txt_val_is_agg_count',\n                 'col_idx_filc_txt_val_notebook_agg_count',\n                 'col_idx_filc_txt_val_need_agg_count',\n                 'col_idx_filc_txt_val_Ooh_agg_count',\n                 'col_idx_filc_txt_val_it_agg_count',\n                 'col_idx_filc_txt_val_that_agg_count',\n                 'col_idx_filc_txt_val_you_agg_count',\n                 'col_idx_filc_txt_val_Jo_agg_count',\n                 'col_idx_filc_txt_val_to_agg_count',\n                 'col_idx_filc_txt_val_Wells_agg_count',\n                 'col_idx_filc_txt_val_find_agg_count',\n                 'col_idx_filc_txt_val_help_agg_count',\n                 'col_idx_filc_txt_val_and_agg_count',\n                 'col_idx_filc_txt_val_Found_agg_count',\n                 'col_idx_filc_txt_val_this_agg_count']\n\n    idx_feat1 = ['col_idx_filc_txt_val_the_agg_count',\n                 'col_idx_filc_txt_val_can_agg_count',\n                 'col_idx_filc_txt_val_is_agg_count',\n                 'col_idx_filc_txt_val_Oh_agg_count',\n                 'col_idx_filc_txt_val_need_agg_count',\n                 'col_idx_filc_txt_val_Ooh_agg_count',\n                 'col_idx_filc_txt_val_it_agg_count',\n                 'col_idx_filc_txt_val_that_agg_count',\n                 'col_idx_filc_txt_val_you_agg_count',\n                 'col_idx_filc_txt_val_Jo_agg_count',\n                 'col_idx_filc_txt_val_to_agg_count',\n                 'col_idx_filc_txt_val_Wells_agg_count',\n                 'col_idx_filc_txt_val_found_agg_count',\n                 'col_idx_filc_txt_val_find_agg_count',\n                 'col_idx_filc_txt_val_help_agg_count',\n                 'col_idx_filc_txt_val_and_agg_count',\n                 'col_idx_filc_txt_val_this_agg_count']\n\n    idx_feat2 = ['col_idx_filc_txt_val_the_agg_count',\n                 'col_idx_filc_txt_val_can_agg_count',\n                 'col_idx_filc_txt_val_is_agg_count',\n                 'col_idx_filc_txt_val_Oh_agg_count',\n                 'col_idx_filc_txt_val_need_agg_count',\n                 'col_idx_filc_txt_val_Ooh_agg_count',\n                 'col_idx_filc_txt_val_it_agg_count',\n                 'col_idx_filc_txt_val_that_agg_count',\n                 'col_idx_filc_txt_val_you_agg_count',\n                 'col_idx_filc_txt_val_Jo_agg_count',\n                 'col_idx_filc_txt_val_to_agg_count',\n                 'col_idx_filc_txt_val_Wells_agg_count',\n                 'col_idx_filc_txt_val_found_agg_count',\n                 'col_idx_filc_txt_val_find_agg_count',\n                 'col_idx_filc_txt_val_help_agg_count',\n                 'col_idx_filc_txt_val_and_agg_count',\n                 'col_idx_filc_txt_val_this_agg_count',\n                 'col_idx_filc_txt_val_flag_agg_count']\n\n    idx_feat = [idx_feat0, idx_feat1, idx_feat2]\n    test[feat] = test[idx_feat[idx]].mean(axis=1)\n    #############################################################################################\n    \"\"\" 3rd \"\"\"\n    feat = \"col_pluso_txt_agg_count_deal_std\"\n    idx_feat0 = ['col_idx_filc_txt_val_the_agg_count',\n                 'col_idx_filc_txt_val_can_agg_count',\n                 'col_idx_filc_txt_val_is_agg_count',\n                 'col_idx_filc_txt_val_notebook_agg_count',\n                 'col_idx_filc_txt_val_need_agg_count',\n                 'col_idx_filc_txt_val_Ooh_agg_count',\n                 'col_idx_filc_txt_val_it_agg_count',\n                 'col_idx_filc_txt_val_that_agg_count',\n                 'col_idx_filc_txt_val_you_agg_count',\n                 'col_idx_filc_txt_val_Jo_agg_count',\n                 'col_idx_filc_txt_val_to_agg_count',\n                 'col_idx_filc_txt_val_Wells_agg_count',\n                 'col_idx_filc_txt_val_find_agg_count',\n                 'col_idx_filc_txt_val_help_agg_count',\n                 'col_idx_filc_txt_val_and_agg_count',\n                 'col_idx_filc_txt_val_Found_agg_count',\n                 'col_idx_filc_txt_val_this_agg_count']\n\n    idx_feat1 = ['col_idx_filc_txt_val_the_agg_count',\n                 'col_idx_filc_txt_val_can_agg_count',\n                 'col_idx_filc_txt_val_is_agg_count',\n                 'col_idx_filc_txt_val_Oh_agg_count',\n                 'col_idx_filc_txt_val_need_agg_count',\n                 'col_idx_filc_txt_val_Ooh_agg_count',\n                 'col_idx_filc_txt_val_it_agg_count',\n                 'col_idx_filc_txt_val_that_agg_count',\n                 'col_idx_filc_txt_val_you_agg_count',\n                 'col_idx_filc_txt_val_Jo_agg_count',\n                 'col_idx_filc_txt_val_to_agg_count',\n                 'col_idx_filc_txt_val_Wells_agg_count',\n                 'col_idx_filc_txt_val_found_agg_count',\n                 'col_idx_filc_txt_val_find_agg_count',\n                 'col_idx_filc_txt_val_help_agg_count',\n                 'col_idx_filc_txt_val_and_agg_count',\n                 'col_idx_filc_txt_val_this_agg_count']\n\n    idx_feat2 = ['col_idx_filc_txt_val_the_agg_count',\n                 'col_idx_filc_txt_val_can_agg_count',\n                 'col_idx_filc_txt_val_is_agg_count',\n                 'col_idx_filc_txt_val_Oh_agg_count',\n                 'col_idx_filc_txt_val_need_agg_count',\n                 'col_idx_filc_txt_val_Ooh_agg_count',\n                 'col_idx_filc_txt_val_it_agg_count',\n                 'col_idx_filc_txt_val_that_agg_count',\n                 'col_idx_filc_txt_val_you_agg_count',\n                 'col_idx_filc_txt_val_Jo_agg_count',\n                 'col_idx_filc_txt_val_to_agg_count',\n                 'col_idx_filc_txt_val_Wells_agg_count',\n                 'col_idx_filc_txt_val_found_agg_count',\n                 'col_idx_filc_txt_val_find_agg_count',\n                 'col_idx_filc_txt_val_help_agg_count',\n                 'col_idx_filc_txt_val_and_agg_count',\n                 'col_idx_filc_txt_val_this_agg_count',\n                 'col_idx_filc_txt_val_flag_agg_count']\n\n    idx_feat = [idx_feat0, idx_feat1, idx_feat2]\n    test[feat] = test[idx_feat[idx]].mean(axis=1)\n    #############################################################################################\n    \"\"\" 4th \"\"\"\n    feat = \"col_pluso_txt_val_find_agg_count_deal_sum\"\n    idx_feat0 = ['col_idx_filc_txt_val_find_agg_count',\n                 'col_idx_filc_txt_val_Found_agg_count']\n\n    idx_feat1 = ['col_idx_filc_txt_val_found_agg_count',\n     'col_idx_filc_txt_val_find_agg_count']\n\n    idx_feat2 = ['col_idx_filc_txt_val_found_agg_count',\n     'col_idx_filc_txt_val_find_agg_count']\n\n    idx_feat = [idx_feat0, idx_feat1, idx_feat2]\n    test[feat] = test[idx_feat[idx]].mean(axis=1)\n    #############################################################################################\n    \"\"\" 5th \"\"\"\n    feat = \"col_pluso_en_val_click_agg_sum_deal_sum\"\n    idx_feat0 = ['col_md_fil_en_val_notebook_click_agg_sum',\n                 'col_md_fil_en_val_object_click_agg_sum',\n                 'col_md_fil_en_val_person_click_agg_sum',\n                 'col_md_fil_en_val_observation_click_agg_sum',\n                 'col_md_fil_en_val_cutscene_click_agg_sum',\n                 'col_md_fil_en_val_navigate_click_agg_sum',\n                 'col_md_fil_en_val_map_click_agg_sum',\n                 'col_md_fil_en_val_notification_click_agg_sum']\n\n    idx_feat1 = ['col_md_fil_en_val_notebook_click_agg_sum',\n                 'col_md_fil_en_val_object_click_agg_sum',\n                 'col_md_fil_en_val_person_click_agg_sum',\n                 'col_md_fil_en_val_observation_click_agg_sum',\n                 'col_md_fil_en_val_cutscene_click_agg_sum',\n                 'col_md_fil_en_val_navigate_click_agg_sum',\n                 'col_md_fil_en_val_map_click_agg_sum',\n                 'col_md_fil_en_val_notification_click_agg_sum']\n\n    idx_feat2 = ['col_md_fil_en_val_notebook_click_agg_sum',\n                 'col_md_fil_en_val_object_click_agg_sum',\n                 'col_md_fil_en_val_person_click_agg_sum',\n                 'col_md_fil_en_val_observation_click_agg_sum',\n                 'col_md_fil_en_val_cutscene_click_agg_sum',\n                 'col_md_fil_en_val_navigate_click_agg_sum',\n                 'col_md_fil_en_val_map_click_agg_sum',\n                 'col_md_fil_en_val_notification_click_agg_sum']\n\n    idx_feat = [idx_feat0, idx_feat1, idx_feat2]\n    test[feat] = test[idx_feat[idx]].mean(axis=1)\n    #############################################################################################\n    \"\"\" 6th \"\"\"\n    if idx == 2 :\n        feat = \"col_pluso_fq_val_flag_agg_mean_deal_mean\"\n        idx_feat = ['col_etd_fil_fq_val_reader_flag.paper1.next_agg_mean',\n                     'col_etd_fil_fq_val_groupconvo_flag_agg_mean',\n                     'col_etd_fil_fq_val_flag_girl_agg_mean',\n                     'col_etd_fil_fq_val_reader_flag.paper0.next_agg_mean',\n                     'col_etd_fil_fq_val_journals_flag.hub.topics_agg_mean',\n                     'col_etd_fil_fq_val_reader_flag.paper0.prev_agg_mean',\n                     'col_etd_fil_fq_val_tocollectionflag_agg_mean',\n                     'col_etd_fil_fq_val_journals_flag.pic_1.next_agg_mean',\n                     'col_etd_fil_fq_val_reader_flag.paper2.prev_agg_mean',\n                     'col_etd_fil_fq_val_journals_flag_agg_mean',\n                     'col_etd_fil_fq_val_tunic.flaghouse_agg_mean',\n                     'col_etd_fil_fq_val_journals_flag.pic_0.next_agg_mean',\n                     'col_etd_fil_fq_val_journals_flag.pic_1.bingo_agg_mean',\n                     'col_etd_fil_fq_val_journals_flag.pic_0.bingo_agg_mean',\n                     'col_etd_fil_fq_val_journals_flag.pic_2.next_agg_mean',\n                     'col_etd_fil_fq_val_reader_flag.paper2.bingo_agg_mean',\n                     'col_etd_fil_fq_val_journals_flag.hub.topics_old_agg_mean',\n                     'col_etd_fil_fq_val_reader_flag.paper2.next_agg_mean',\n                     'col_etd_fil_fq_val_reader_flag_agg_mean',\n                     'col_etd_fil_fq_val_journals_flag.pic_2.bingo_agg_mean']\n\n        test[feat] = test[idx_feat].mean(axis=1)\n    #############################################################################################\n    \"\"\" 7th \"\"\"\n    feat = \"col_pluso_en_val_click_agg_sum_deal_prod\"\n    idx_feat0 = ['col_md_fil_en_val_notebook_click_agg_sum',\n                 'col_md_fil_en_val_object_click_agg_sum',\n                 'col_md_fil_en_val_person_click_agg_sum',\n                 'col_md_fil_en_val_observation_click_agg_sum',\n                 'col_md_fil_en_val_cutscene_click_agg_sum',\n                 'col_md_fil_en_val_navigate_click_agg_sum',\n                 'col_md_fil_en_val_map_click_agg_sum',\n                 'col_md_fil_en_val_notification_click_agg_sum']\n\n    idx_feat1 = ['col_md_fil_en_val_notebook_click_agg_sum',\n                 'col_md_fil_en_val_object_click_agg_sum',\n                 'col_md_fil_en_val_person_click_agg_sum',\n                 'col_md_fil_en_val_observation_click_agg_sum',\n                 'col_md_fil_en_val_cutscene_click_agg_sum',\n                 'col_md_fil_en_val_navigate_click_agg_sum',\n                 'col_md_fil_en_val_map_click_agg_sum',\n                 'col_md_fil_en_val_notification_click_agg_sum']\n\n    idx_feat2 = ['col_md_fil_en_val_notebook_click_agg_sum',\n                 'col_md_fil_en_val_object_click_agg_sum',\n                 'col_md_fil_en_val_person_click_agg_sum',\n                 'col_md_fil_en_val_observation_click_agg_sum',\n                 'col_md_fil_en_val_cutscene_click_agg_sum',\n                 'col_md_fil_en_val_navigate_click_agg_sum',\n                 'col_md_fil_en_val_map_click_agg_sum',\n                 'col_md_fil_en_val_notification_click_agg_sum']\n\n    idx_feat = [idx_feat0, idx_feat1, idx_feat2]\n    test[feat] = test[idx_feat[idx]].mean(axis=1)\n    \n    return test","metadata":{"papermill":{"duration":0.060724,"end_time":"2023-06-06T17:47:58.104537","exception":false,"start_time":"2023-06-06T17:47:58.043813","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-03-15T08:56:39.761457Z","iopub.execute_input":"2024-03-15T08:56:39.761870Z","iopub.status.idle":"2024-03-15T08:56:39.788429Z","shell.execute_reply.started":"2024-03-15T08:56:39.761838Z","shell.execute_reply":"2024-03-15T08:56:39.787327Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"q_cols = [f'Q{q}' for q in range(1, 19)]\nday_cols = ['year', 'month', 'day', 'hour', 'minute', 'second']\nfor q in range(18) :\n    feature_true[q] = [feat for feat in feature_true[q] if (ext_col(feat) != \"pluso\") & (feat not in day_cols+q_cols)] ","metadata":{"papermill":{"duration":0.081831,"end_time":"2023-06-06T17:47:58.192639","exception":false,"start_time":"2023-06-06T17:47:58.110808","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-03-15T08:56:39.789357Z","iopub.execute_input":"2024-03-15T08:56:39.789576Z","iopub.status.idle":"2024-03-15T08:56:39.862171Z","shell.execute_reply.started":"2024-03-15T08:56:39.789557Z","shell.execute_reply":"2024-03-15T08:56:39.860732Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#########################################################################################\ncolumns = [\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        .over([\"session_id\", \"level\"])\n        .alias(\"elapsed_time_diff\")\n    ),\n    (\n        (pl.col(\"screen_coor_x\") - pl.col(\"screen_coor_x\").shift(1))\n        .abs()\n        .over([\"session_id\", \"level\"])\n    ),\n    (\n        (pl.col(\"screen_coor_y\") - pl.col(\"screen_coor_y\").shift(1))\n        .abs()\n        .over([\"session_id\", \"level\"])\n    ),\n    (\n        np.sqrt( ( (pl.col(\"screen_coor_y\") - pl.col(\"screen_coor_y\").shift(1)) )**2 \n        + ( (pl.col(\"screen_coor_x\") - pl.col(\"screen_coor_x\").shift(1)) )**2 )\n        .abs()\n        .over([\"session_id\", \"level\"])\n        .alias(\"move_distance\")\n    ),\n    pl.col(\"fqid\").fill_null(\"fqid_None\"),\n    pl.col(\"level\").apply(lambda x : str(x)),\n    pl.col(\"text_fqid\").fill_null(\"text_fqid_None\")\n\n    ]\n#########################################################################################\n\n    \ndef preprocess_test (test, columns, grp) :\n    \n    if grp == \"0-4\":\n        idx = 0\n    elif grp == \"5-12\":\n        idx = 3\n    else:\n        idx = 13\n    \n    test = test.sort_values(by=['session_id', 'elapsed_time'], ascending=True)\n    test = pl.from_pandas(test).with_columns(columns)\n    \n    test = test.with_columns(\n           (\n            (pl.col(\"move_distance\") / pl.col(\"elapsed_time_diff\"))\n            .fill_null(0)\n            .clip(0, 1e9)\n            .over([\"session_id\", \"level\"])\n            .alias(\"velocity\")\n            ))\n    \n    test = test.filter(pl.col(\"level_group\") == grp)\n    \n    add_cols = [add_features(feat) for feat in feature_true[idx]]\n    aggs = [*add_cols]\n    test = test.groupby(['session_id'], maintain_order=True).agg(aggs).sort(\"session_id\").to_pandas()\n    \n    test = time_feature(test)\n    test = hm_feature(test, grp)\n    \n    return test ","metadata":{"papermill":{"duration":0.05304,"end_time":"2023-06-06T17:47:58.252349","exception":false,"start_time":"2023-06-06T17:47:58.199309","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-03-15T08:56:39.863796Z","iopub.execute_input":"2024-03-15T08:56:39.864142Z","iopub.status.idle":"2024-03-15T08:56:39.898831Z","shell.execute_reply.started":"2024-03-15T08:56:39.864113Z","shell.execute_reply":"2024-03-15T08:56:39.897305Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Inferencing Part","metadata":{}},{"cell_type":"code","source":"# IMPORT KAGGLE API\nimport jo_wilder_310\nenv = jo_wilder_310.make_env()\niter_test = env.iter_test()\n\n# CLEAR MEMORY\nimport gc\n_ = gc.collect()","metadata":{"papermill":{"duration":0.19162,"end_time":"2023-06-06T17:47:58.450266","exception":false,"start_time":"2023-06-06T17:47:58.258646","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-03-15T08:56:39.902990Z","iopub.execute_input":"2024-03-15T08:56:39.904831Z","iopub.status.idle":"2024-03-15T08:56:40.105891Z","shell.execute_reply.started":"2024-03-15T08:56:39.904797Z","shell.execute_reply":"2024-03-15T08:56:40.104708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"limits = {'0-4':(1,4), '5-12':(4,14), '13-22':(14,19)}\ncorrectyn_df = pd.DataFrame()\n\nfor (test, sample_submission) in iter_test :\n    \n    grp = test.level_group.values[0]\n    a,b = limits[grp]\n    idx = 0 if grp == \"0-4\" else 1 if grp == \"5-12\" else 2\n    \n    test.drop(columns = [\"fullscreen\", \"hq\", \"music\"], axis = 1, inplace = True)\n    testset = preprocess_test(test, columns, grp)\n    \n    del test\n    _ = gc.collect()\n    \n    for q in range(a, b) :\n        \n        if q > 1 :\n            for ii in range(1, q) :\n                testset[f\"Q{ii}\"] = correctyn_df[f\"Q{ii}\"].tolist()\n        \n        print(\"  ==========================================================================  \\n\")\n        print(f\" Predict Q{q} ... \\n\")\n        model = best_model[f\"Q{q}\"]\n        \n        pred_proba = model.predict_proba(testset[model.feature_name_])[0, 1]\n        correctyn_df[f\"Q{q}\"] = [pred_proba]\n        \n        print('#feats : ', len(testset[model.feature_name_].columns), \"\\n\")\n        \n        mask = sample_submission.session_id.str.contains(f\"q{q}\")\n        sample_submission.loc[mask, \"correct\"] = int(pred_proba > best_thr)\n    \n    env.predict(sample_submission)\n    print(f\"Predicting Level {grp} Was Done.\\n\")\n    ","metadata":{"papermill":{"duration":5.535116,"end_time":"2023-06-06T17:48:03.991581","exception":false,"start_time":"2023-06-06T17:47:58.456465","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-03-15T08:56:40.108629Z","iopub.execute_input":"2024-03-15T08:56:40.109205Z","iopub.status.idle":"2024-03-15T08:56:44.487035Z","shell.execute_reply.started":"2024-03-15T08:56:40.109173Z","shell.execute_reply":"2024-03-15T08:56:44.485292Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df = pd.read_csv(\"submission.csv\")\nprint(submission_df.shape)\nsubmission_df","metadata":{"papermill":{"duration":0.052499,"end_time":"2023-06-06T17:48:04.069444","exception":false,"start_time":"2023-06-06T17:48:04.016945","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-03-15T08:56:44.489389Z","iopub.execute_input":"2024-03-15T08:56:44.489799Z","iopub.status.idle":"2024-03-15T08:56:44.526208Z","shell.execute_reply.started":"2024-03-15T08:56:44.489768Z","shell.execute_reply":"2024-03-15T08:56:44.524737Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.set_style(\"whitegrid\")\nsns.countplot(x = 'correct', data = submission_df)\nplt.show()","metadata":{"papermill":{"duration":0.287165,"end_time":"2023-06-06T17:48:04.371661","exception":false,"start_time":"2023-06-06T17:48:04.084496","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-03-15T08:56:44.530346Z","iopub.execute_input":"2024-03-15T08:56:44.530670Z","iopub.status.idle":"2024-03-15T08:56:44.689484Z","shell.execute_reply.started":"2024-03-15T08:56:44.530647Z","shell.execute_reply":"2024-03-15T08:56:44.688817Z"},"trusted":true},"execution_count":null,"outputs":[]}]}