{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":50160,"databundleVersionId":7921029,"sourceType":"competition"},{"sourceId":175067883,"sourceType":"kernelVersion"}],"dockerImageVersionId":30698,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport lightgbm as lgb\nimport glob\n\nimport matplotlib.pyplot as plt \nimport seaborn as sns","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-05-03T20:03:01.461174Z","iopub.execute_input":"2024-05-03T20:03:01.461602Z","iopub.status.idle":"2024-05-03T20:03:03.225946Z","shell.execute_reply.started":"2024-05-03T20:03:01.461567Z","shell.execute_reply":"2024-05-03T20:03:03.224575Z"},"_kg_hide-output":false,"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.set_palette('flare')\n\nmodel_dir = '/kaggle/input/hc-crms-lgbm-weekly-model/models'\nmodel_dict = {}\n\nfor file in glob.glob(model_dir+'/*.txt'):\n    model_name = file.split('/')[-1].split('.')[0]\n    step = int(model_name.split('_')[1])\n    model_dict[step] = model_name\n    ","metadata":{"execution":{"iopub.status.busy":"2024-05-03T20:03:03.233302Z","iopub.execute_input":"2024-05-03T20:03:03.233672Z","iopub.status.idle":"2024-05-03T20:03:03.243825Z","shell.execute_reply.started":"2024-05-03T20:03:03.233645Z","shell.execute_reply":"2024-05-03T20:03:03.241591Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"min_step = np.min(list(model_dict.keys()))\nmax_step = np.max(list(model_dict.keys()))","metadata":{"execution":{"iopub.status.busy":"2024-05-03T20:03:03.245724Z","iopub.execute_input":"2024-05-03T20:03:03.246159Z","iopub.status.idle":"2024-05-03T20:03:03.255961Z","shell.execute_reply.started":"2024-05-03T20:03:03.246131Z","shell.execute_reply":"2024-05-03T20:03:03.254506Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"feature_importance_array = np.empty((0,3))\n\nfor i in range(min_step, max_step):\n    booster = lgb.Booster(model_file=f'{model_dir}/{model_dict[i]}.txt')\n    \n    feature_name = booster.feature_name()\n    feature_importance = booster.feature_importance()\n    \n    temp = np.hstack((\n        np.full((len(feature_name),1), fill_value=i),\n        np.array(feature_name).reshape((-1,1)),\n        np.array(feature_importance).reshape((-1,1))\n    ))\n    \n    feature_importance_array = np.vstack((\n        feature_importance_array,\n        temp\n    ))","metadata":{"execution":{"iopub.status.busy":"2024-05-03T20:03:03.260193Z","iopub.execute_input":"2024-05-03T20:03:03.260623Z","iopub.status.idle":"2024-05-03T20:03:04.783727Z","shell.execute_reply.started":"2024-05-03T20:03:03.260593Z","shell.execute_reply":"2024-05-03T20:03:04.782638Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"feature_importance_df = pd.DataFrame({\n    'timestep':feature_importance_array[:,0],\n    'feature_name':feature_importance_array[:,1],\n    'feature_importance':feature_importance_array[:,2]\n})\n\nfeature_importance_df['timestep'] = feature_importance_df['timestep'].astype(int)\nfeature_importance_df['feature_importance'] = feature_importance_df['feature_importance'].astype(int)","metadata":{"execution":{"iopub.status.busy":"2024-05-03T20:03:04.785030Z","iopub.execute_input":"2024-05-03T20:03:04.786239Z","iopub.status.idle":"2024-05-03T20:03:04.843607Z","shell.execute_reply.started":"2024-05-03T20:03:04.786207Z","shell.execute_reply":"2024-05-03T20:03:04.842223Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"grouped_feature_importance_df = feature_importance_df.groupby('feature_name').agg(\n    median_feature_importance=pd.NamedAgg(column=\"feature_importance\", aggfunc=\"median\"),\n    std_feature_importance=pd.NamedAgg(column=\"feature_importance\", aggfunc=\"std\"),\n    min_feature_importance=pd.NamedAgg(column=\"feature_importance\", aggfunc=\"min\"),\n    max_feature_importance=pd.NamedAgg(column=\"feature_importance\", aggfunc=\"max\")\n).reset_index().sort_values(by=['min_feature_importance','median_feature_importance','std_feature_importance'], ascending=[False, False,True]).head(100)","metadata":{"execution":{"iopub.status.busy":"2024-05-03T20:03:04.844883Z","iopub.execute_input":"2024-05-03T20:03:04.845186Z","iopub.status.idle":"2024-05-03T20:03:04.876519Z","shell.execute_reply.started":"2024-05-03T20:03:04.845162Z","shell.execute_reply":"2024-05-03T20:03:04.875602Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# About the model\n\n- Multiple models were trained with 10 weeks of data.\n- Only data from week <= 72 were used.\n- There is overlap of weeks between different models\n- The pseudocode below can help you understand how weeks were used in the train loop","metadata":{}},{"cell_type":"code","source":"'''\nweeks = np.arange(0,73)\nweek_step=10\nfor week in weeks:\n    week_list = [x for x in range(week, week-week_step, -1) if x >=0 ]\n    if len(week_list) < week_step:\n        continue\n    print(week_list)\n'''","metadata":{"execution":{"iopub.status.busy":"2024-05-03T20:03:04.877630Z","iopub.execute_input":"2024-05-03T20:03:04.878723Z","iopub.status.idle":"2024-05-03T20:03:04.894103Z","shell.execute_reply.started":"2024-05-03T20:03:04.878693Z","shell.execute_reply":"2024-05-03T20:03:04.892401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The idea of this notebook is to use feature importance statistics collected over all weeks to classify which features are more important and stable.\nWe are assuming that stable features will have high median, high minimum and low standard deviation importance score.","metadata":{}},{"cell_type":"markdown","source":"# Feature Importance Distribution","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(8,3))\nsns.histplot(\n    data=feature_importance_df,\n    x='feature_importance',\n    ax=ax\n)\nax.set_title('Feature Importance Distribution')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-05-03T20:03:04.898269Z","iopub.execute_input":"2024-05-03T20:03:04.898673Z","iopub.status.idle":"2024-05-03T20:03:05.637078Z","shell.execute_reply.started":"2024-05-03T20:03:04.898647Z","shell.execute_reply":"2024-05-03T20:03:05.636013Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Median feature importance distribution","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(8,3))\nsns.histplot(\n    data=grouped_feature_importance_df,\n    x='median_feature_importance',\n    ax=ax\n)\nax.set_title('Median Feature Importance Distribution')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-05-03T20:03:05.638482Z","iopub.execute_input":"2024-05-03T20:03:05.639846Z","iopub.status.idle":"2024-05-03T20:03:05.865040Z","shell.execute_reply.started":"2024-05-03T20:03:05.639808Z","shell.execute_reply":"2024-05-03T20:03:05.862907Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Top 100 features over all time","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(4,20))\nsns.barplot(\n    data=grouped_feature_importance_df,\n    x='median_feature_importance',\n    y='feature_name',\n    ax=ax,\n    palette='flare'\n)\nax.set_title('Top 100 features over all time')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-05-03T20:03:05.866317Z","iopub.execute_input":"2024-05-03T20:03:05.866654Z","iopub.status.idle":"2024-05-03T20:03:07.028611Z","shell.execute_reply.started":"2024-05-03T20:03:05.866631Z","shell.execute_reply":"2024-05-03T20:03:07.027010Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Distribution of top 100 features over all time","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(10,20))\nsns.boxplot(\n    data=feature_importance_df.loc[feature_importance_df['feature_name'].isin(grouped_feature_importance_df['feature_name'].to_list())],\n    x='feature_importance',\n    y='feature_name',\n    order=grouped_feature_importance_df['feature_name'].to_list(),\n    ax=ax,\n    palette='flare'\n)\nax.set_title('Distribution of top 100 features over all time')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-05-03T20:03:07.030494Z","iopub.execute_input":"2024-05-03T20:03:07.030909Z","iopub.status.idle":"2024-05-03T20:03:09.063761Z","shell.execute_reply.started":"2024-05-03T20:03:07.030878Z","shell.execute_reply":"2024-05-03T20:03:09.062165Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}