{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":84896,"databundleVersionId":10305135,"sourceType":"competition"}],"dockerImageVersionId":30804,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Insurance Premium\n\nIn this notebook, I do a very quick and simple EDA to get a general understanding of the data so I can create a pipeline for preprocessing it. Then, I train a CatBoost model as a base line for subsequent submissions. Hope you find something useful in it!","metadata":{}},{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport missingno as msno\n\nfrom sklearn.pipeline import Pipeline\nfrom sklearn.impute import SimpleImputer\nfrom sklearn.compose import ColumnTransformer\nfrom sklearn.ensemble import RandomForestRegressor\nfrom sklearn.model_selection import train_test_split\nfrom catboost import CatBoostRegressor\nfrom sklearn.metrics import mean_squared_log_error\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session\n\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2024-12-04T04:36:10.857795Z","iopub.execute_input":"2024-12-04T04:36:10.858353Z","iopub.status.idle":"2024-12-04T04:36:10.87497Z","shell.execute_reply.started":"2024-12-04T04:36:10.85816Z","shell.execute_reply":"2024-12-04T04:36:10.873432Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train = pd.read_csv('/kaggle/input/playground-series-s4e12/train.csv')\ndf_test = pd.read_csv('/kaggle/input/playground-series-s4e12/test.csv')\nsubmission = pd.read_csv('/kaggle/input/playground-series-s4e12/sample_submission.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T04:39:07.607526Z","iopub.execute_input":"2024-12-04T04:39:07.607972Z","iopub.status.idle":"2024-12-04T04:39:16.130633Z","shell.execute_reply.started":"2024-12-04T04:39:07.607936Z","shell.execute_reply":"2024-12-04T04:39:16.129401Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train.drop(['id', 'Policy Start Date'], axis=1, inplace=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T02:18:50.916697Z","iopub.execute_input":"2024-12-04T02:18:50.917034Z","iopub.status.idle":"2024-12-04T02:18:51.136905Z","shell.execute_reply.started":"2024-12-04T02:18:50.917003Z","shell.execute_reply":"2024-12-04T02:18:51.135707Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T02:18:51.138345Z","iopub.execute_input":"2024-12-04T02:18:51.138789Z","iopub.status.idle":"2024-12-04T02:18:51.723509Z","shell.execute_reply.started":"2024-12-04T02:18:51.138744Z","shell.execute_reply":"2024-12-04T02:18:51.722241Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# EDA","metadata":{}},{"cell_type":"code","source":"msno.bar(df_train);","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T02:18:51.724679Z","iopub.execute_input":"2024-12-04T02:18:51.724969Z","iopub.status.idle":"2024-12-04T02:18:53.634712Z","shell.execute_reply.started":"2024-12-04T02:18:51.724941Z","shell.execute_reply":"2024-12-04T02:18:53.63328Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Separate features\ncat_object_cols = [col for col in df_train.columns if df_train[col].dtype == \"object\"]\n\ncat_num_cols = [col for col in df_train.columns if df_train[col].dtype in ['int64', 'float64'] and \n                        df_train[col].nunique() <= 10]\n\nnum_cols = [col for col in df_train.columns if df_train[col].dtype in ['int64', 'float64'] and \n                        df_train[col].nunique() > 10 and col != 'Premium Amount']","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T03:35:17.041774Z","iopub.execute_input":"2024-12-04T03:35:17.043611Z","iopub.status.idle":"2024-12-04T03:35:17.470367Z","shell.execute_reply.started":"2024-12-04T03:35:17.043561Z","shell.execute_reply":"2024-12-04T03:35:17.469347Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(f\"Data has {len(cat_object_cols)} categorical object columns\")\nprint(f\"Data has {len(cat_num_cols)} categorical numerical columns\")\nprint(f\"Data has {len(num_cols)} numerical columns\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T03:35:18.707348Z","iopub.execute_input":"2024-12-04T03:35:18.707753Z","iopub.status.idle":"2024-12-04T03:35:18.714667Z","shell.execute_reply.started":"2024-12-04T03:35:18.707719Z","shell.execute_reply":"2024-12-04T03:35:18.713116Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sns.histplot(x=\"Premium Amount\", data=df_train);\nplt.title('Distribution of Premium Amount', fontsize=18);","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T03:35:31.152592Z","iopub.execute_input":"2024-12-04T03:35:31.152962Z","iopub.status.idle":"2024-12-04T03:35:32.230821Z","shell.execute_reply.started":"2024-12-04T03:35:31.152931Z","shell.execute_reply":"2024-12-04T03:35:32.229646Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sns.heatmap(df_train[num_cols + cat_num_cols].corr(), vmin=0, vmax=1, linewidths=2, square=True, cmap='Blues')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T02:18:55.024341Z","iopub.execute_input":"2024-12-04T02:18:55.024776Z","iopub.status.idle":"2024-12-04T02:18:55.697514Z","shell.execute_reply.started":"2024-12-04T02:18:55.024731Z","shell.execute_reply":"2024-12-04T02:18:55.69616Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train[cat_object_cols].head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T02:18:55.699155Z","iopub.execute_input":"2024-12-04T02:18:55.699579Z","iopub.status.idle":"2024-12-04T02:18:55.840633Z","shell.execute_reply.started":"2024-12-04T02:18:55.699538Z","shell.execute_reply":"2024-12-04T02:18:55.839364Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(14, 12))\n\nfor i, col in enumerate(df_train[cat_object_cols].columns, 1):\n    plt.subplot(5, 3, i)\n    sns.countplot(x=col, data=df_train, palette='pastel')\n    plt.title(col, weight='bold', fontsize=12)\n    plt.ylabel(\"\")  # Remove redundant y-axis label\n    plt.xlabel(\"\")  # Remove redundant x-axis label\n    plt.xticks(rotation=30, fontsize=10)  # Rotate x-axis labels for better visibility\n    plt.yticks(fontsize=10)  # Adjust y-axis ticks size\n\n# Adjust layout to prevent overlap\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T02:36:53.186328Z","iopub.execute_input":"2024-12-04T02:36:53.186719Z","iopub.status.idle":"2024-12-04T02:37:01.282107Z","shell.execute_reply.started":"2024-12-04T02:36:53.186688Z","shell.execute_reply":"2024-12-04T02:37:01.28108Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(14, 12))\n\nfor i, col in enumerate(df_train[cat_num_cols].columns, 1):\n    plt.subplot(5, 3, i)  # Create subplots dynamically\n    sns.histplot(data=df_train, x=col, kde=False, bins=10, color='skyblue')  # Add histograms\n    plt.title(col, weight='bold', fontsize=12)  # Adjust font size for better readability\n    plt.ylabel(\"\")  # Remove redundant y-axis label\n    plt.xlabel(\"\")  # Remove redundant x-axis label\n    plt.xticks(rotation=30, fontsize=10)  # Rotate x-axis labels for better visibility\n    plt.yticks(fontsize=10)  # Adjust y-axis ticks size\n\n# Adjust layout to prevent overlap\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T03:42:04.994181Z","iopub.execute_input":"2024-12-04T03:42:04.99466Z","iopub.status.idle":"2024-12-04T03:42:07.057201Z","shell.execute_reply.started":"2024-12-04T03:42:04.994622Z","shell.execute_reply":"2024-12-04T03:42:07.055958Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(14, 12))\n\nfor i, col in enumerate(df_train[num_cols].columns, 1):\n    plt.subplot(5, 3, i)  # Create subplots dynamically\n    sns.histplot(data=df_train, x=col, kde=False, bins=10, color='skyblue')  # Add histograms\n    plt.title(col, weight='bold', fontsize=12)  # Adjust font size for better readability\n    plt.ylabel(\"\")  # Remove redundant y-axis label\n    plt.xlabel(\"\")  # Remove redundant x-axis label\n    plt.xticks(rotation=30, fontsize=10)  # Rotate x-axis labels for better visibility\n    plt.yticks(fontsize=10)  # Adjust y-axis ticks size\n\n# Adjust layout to prevent overlap\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T03:35:42.307807Z","iopub.execute_input":"2024-12-04T03:35:42.308199Z","iopub.status.idle":"2024-12-04T03:35:45.415862Z","shell.execute_reply.started":"2024-12-04T03:35:42.308161Z","shell.execute_reply":"2024-12-04T03:35:45.414709Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Insights from EDA**\n\n* Some columns have missing data but we can impute them.\n* The categorical columns are balanced.\n* The distribution of the target variable is skewed.","metadata":{}},{"cell_type":"markdown","source":"## Preprocessing pipeline","metadata":{}},{"cell_type":"code","source":"# Convert cat_object_cols that are of type float","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"numerical_transformer = SimpleImputer(strategy=\"median\")\ncategorical_obj_transformer = SimpleImputer(strategy=\"most_frequent\")\ncategorical_num_transformer = SimpleImputer(strategy=\"most_frequent\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T03:42:41.971497Z","iopub.execute_input":"2024-12-04T03:42:41.971883Z","iopub.status.idle":"2024-12-04T03:42:41.978647Z","shell.execute_reply.started":"2024-12-04T03:42:41.971848Z","shell.execute_reply":"2024-12-04T03:42:41.97728Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"preprocessor = ColumnTransformer(\n    transformers=[\n        ('num', numerical_transformer, num_cols),\n        ('cat_obj', categorical_obj_transformer, cat_object_cols),\n        ('cat_num', categorical_num_transformer, cat_num_cols)\n    ]\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T03:44:51.56619Z","iopub.execute_input":"2024-12-04T03:44:51.566659Z","iopub.status.idle":"2024-12-04T03:44:51.572194Z","shell.execute_reply.started":"2024-12-04T03:44:51.56662Z","shell.execute_reply":"2024-12-04T03:44:51.570799Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pipeline = Pipeline(steps=[\n    ('preprocessor', preprocessor)])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T03:45:19.152023Z","iopub.execute_input":"2024-12-04T03:45:19.152442Z","iopub.status.idle":"2024-12-04T03:45:19.158042Z","shell.execute_reply.started":"2024-12-04T03:45:19.152407Z","shell.execute_reply":"2024-12-04T03:45:19.15674Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Split and preprocess data","metadata":{}},{"cell_type":"code","source":"X = df_train.drop(columns=[\"Premium Amount\"])\ny = df_train[\"Premium Amount\"]\nX_preprocessed = pipeline.fit_transform(X)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T03:47:03.462489Z","iopub.execute_input":"2024-12-04T03:47:03.462904Z","iopub.status.idle":"2024-12-04T03:47:07.846965Z","shell.execute_reply.started":"2024-12-04T03:47:03.462867Z","shell.execute_reply":"2024-12-04T03:47:07.845817Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_preprocessed = pd.DataFrame(X_preprocessed)\ndf_preprocessed = df_preprocessed.infer_objects()\ncat_object_cols_new = [df_preprocessed.columns.get_loc(col) for col in df_preprocessed.select_dtypes(include=['object', 'bool']).columns]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T04:06:20.659133Z","iopub.execute_input":"2024-12-04T04:06:20.660062Z","iopub.status.idle":"2024-12-04T04:06:21.695087Z","shell.execute_reply.started":"2024-12-04T04:06:20.66002Z","shell.execute_reply":"2024-12-04T04:06:21.693879Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"cat_object_cols_new","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T04:06:38.305564Z","iopub.execute_input":"2024-12-04T04:06:38.305979Z","iopub.status.idle":"2024-12-04T04:06:38.313647Z","shell.execute_reply.started":"2024-12-04T04:06:38.305943Z","shell.execute_reply":"2024-12-04T04:06:38.312446Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train, X_val, y_train, y_val = train_test_split(X_preprocessed, y, test_size=0.2, random_state=42)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T03:54:50.161609Z","iopub.execute_input":"2024-12-04T03:54:50.16201Z","iopub.status.idle":"2024-12-04T03:54:55.489198Z","shell.execute_reply.started":"2024-12-04T03:54:50.16198Z","shell.execute_reply":"2024-12-04T03:54:55.488073Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Baseline model","metadata":{}},{"cell_type":"code","source":"model = CatBoostRegressor(iterations=1000, \n                          depth=10,       \n                          learning_rate=0.05, \n                          loss_function='RMSE',\n                          cat_features=cat_object_cols_new,\n                          random_seed=42,\n                          verbose=100)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T04:06:48.973925Z","iopub.execute_input":"2024-12-04T04:06:48.974989Z","iopub.status.idle":"2024-12-04T04:06:48.98004Z","shell.execute_reply.started":"2024-12-04T04:06:48.974934Z","shell.execute_reply":"2024-12-04T04:06:48.978971Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.fit(X_train, y_train, eval_set=(X_val, y_val), plot=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T04:06:54.920092Z","iopub.execute_input":"2024-12-04T04:06:54.921153Z","iopub.status.idle":"2024-12-04T04:34:35.551667Z","shell.execute_reply.started":"2024-12-04T04:06:54.921102Z","shell.execute_reply":"2024-12-04T04:34:35.550407Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_pred = model.predict(X_val)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T04:34:35.553779Z","iopub.execute_input":"2024-12-04T04:34:35.554128Z","iopub.status.idle":"2024-12-04T04:34:37.19499Z","shell.execute_reply.started":"2024-12-04T04:34:35.554095Z","shell.execute_reply":"2024-12-04T04:34:37.193765Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"rmsle = np.sqrt(mean_squared_log_error(y_val, y_pred))\nprint(f'RMSLE: {rmsle}')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T04:36:22.815089Z","iopub.execute_input":"2024-12-04T04:36:22.816693Z","iopub.status.idle":"2024-12-04T04:36:22.836699Z","shell.execute_reply.started":"2024-12-04T04:36:22.816632Z","shell.execute_reply":"2024-12-04T04:36:22.835441Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Submit","metadata":{}},{"cell_type":"code","source":"X_test = df_test.drop(columns=['id', 'Policy Start Date'])\nX_test_preprocessed = pipeline.transform(X_test)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T04:36:50.737801Z","iopub.execute_input":"2024-12-04T04:36:50.738204Z","iopub.status.idle":"2024-12-04T04:36:51.93626Z","shell.execute_reply.started":"2024-12-04T04:36:50.738166Z","shell.execute_reply":"2024-12-04T04:36:51.934968Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_test_pred = model.predict(X_test_preprocessed)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T04:37:35.863369Z","iopub.execute_input":"2024-12-04T04:37:35.863782Z","iopub.status.idle":"2024-12-04T04:37:40.021943Z","shell.execute_reply.started":"2024-12-04T04:37:35.863745Z","shell.execute_reply":"2024-12-04T04:37:40.020708Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission = pd.DataFrame({\n    'id': df_test['id'],\n    'Premium Amount': y_test_pred\n})\nsubmission.to_csv('submission.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T04:39:24.756698Z","iopub.execute_input":"2024-12-04T04:39:24.757071Z","iopub.status.idle":"2024-12-04T04:39:26.497788Z","shell.execute_reply.started":"2024-12-04T04:39:24.75704Z","shell.execute_reply":"2024-12-04T04:39:26.496544Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T04:39:36.005844Z","iopub.execute_input":"2024-12-04T04:39:36.006373Z","iopub.status.idle":"2024-12-04T04:39:36.017812Z","shell.execute_reply.started":"2024-12-04T04:39:36.006297Z","shell.execute_reply":"2024-12-04T04:39:36.01666Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}