{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.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":115000,"databundleVersionId":13897013,"sourceType":"competition"}],"dockerImageVersionId":31153,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"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)\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","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:35:21.146542Z","iopub.execute_input":"2025-10-14T16:35:21.146771Z","iopub.status.idle":"2025-10-14T16:35:23.158123Z","shell.execute_reply.started":"2025-10-14T16:35:21.146749Z","shell.execute_reply":"2025-10-14T16:35:23.157218Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfrom sklearn.impute import SimpleImputer","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:37:47.480965Z","iopub.execute_input":"2025-10-14T16:37:47.481298Z","iopub.status.idle":"2025-10-14T16:37:48.878530Z","shell.execute_reply.started":"2025-10-14T16:37:47.481274Z","shell.execute_reply":"2025-10-14T16:37:48.877638Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dt_train = pd.read_csv('/kaggle/input/carnival-risk-analytics-challenge/train.csv')\ndt_test = pd.read_csv('/kaggle/input/carnival-risk-analytics-challenge/test.csv')\ndt_train.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:36:35.280830Z","iopub.execute_input":"2025-10-14T16:36:35.281173Z","iopub.status.idle":"2025-10-14T16:36:41.425270Z","shell.execute_reply.started":"2025-10-14T16:36:35.281116Z","shell.execute_reply":"2025-10-14T16:36:41.424446Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"cols = ['id','Occupation']\ndt_train.drop_duplicates(inplace=True)\ndt_test.drop_duplicates(inplace=True)\nX = dt_train.drop(columns=cols)            \nX = X.drop(columns='Premium Amount')\nXt = dt_test.drop(columns=cols)\ny = dt_train['Premium Amount']","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:36:53.295597Z","iopub.execute_input":"2025-10-14T16:36:53.295926Z","iopub.status.idle":"2025-10-14T16:36:55.214924Z","shell.execute_reply.started":"2025-10-14T16:36:53.295900Z","shell.execute_reply":"2025-10-14T16:36:55.214213Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X.isnull().sum() / X.shape[0]*100","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:36:59.735410Z","iopub.execute_input":"2025-10-14T16:36:59.735723Z","iopub.status.idle":"2025-10-14T16:37:00.085185Z","shell.execute_reply.started":"2025-10-14T16:36:59.735699Z","shell.execute_reply":"2025-10-14T16:37:00.084420Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def data_Filling(data) :\n    # Fillling NaN values of Customer Feedback\n    for occ in data['Smoking Status'].unique():\n        for edu in data['Exercise Frequency'].unique():\n\n            mask = ((data['Smoking Status'] == occ) &\n                    (data['Exercise Frequency'] == edu))\n\n            group = data.loc[mask, 'Customer Feedback']\n\n            if group.isna().sum() == 0:\n                continue\n\n            value_counts = group.value_counts(normalize=True)\n    \n            if value_counts.empty:\n                probs = [0.333,0.333,0.334]\n                choices = ['Poor','Good','Average']\n            else:\n                probs = []\n                choices = []\n                for cat in ['Poor','Good','Average']:\n                    choices.append(cat)\n                    probs.append(value_counts.get(cat, 0))\n\n                probs = np.array(probs)\n                if probs.sum() > 0:\n                    probs = probs / probs.sum()\n                else:\n                    probs = [0.333,0.333,0.334]\n\n            n_missing = group.isna().sum()\n            fill_values = np.random.choice(choices, size=n_missing, p=probs)\n\n            data.loc[mask & data['Customer Feedback'].isna(), 'Customer Feedback'] = fill_values\n\n\n    # Fillling NaN values of Marital Status\n    for occ in data['Location'].unique():\n        for edu in data['Education Level'].unique():\n\n            mask = ((data['Location'] == occ) &\n                    (data['Education Level'] == edu))\n\n            group = data.loc[mask, 'Marital Status']\n\n            if group.isna().sum() == 0:\n                continue\n\n            value_counts = group.value_counts(normalize=True)\n    \n            if value_counts.empty:\n                probs = [0.333,0.333,0.334] \n                choices = ['Single','Married','Divorced']\n            else:\n                probs = []\n                choices = []\n                for cat in ['Single','Married','Divorced']:\n                    choices.append(cat)\n                    probs.append(value_counts.get(cat, 0))\n\n                probs = np.array(probs)\n                if probs.sum() > 0:\n                    probs = probs / probs.sum()\n                else:\n                    probs = [0.333,0.333,0.334]\n\n            n_missing = group.isna().sum()\n            fill_values = np.random.choice(choices, size=n_missing, p=probs)\n\n            data.loc[mask & data['Marital Status'].isna(), 'Marital Status'] = fill_values\n\n    # Fillling NaN values of No. of Children\n    for occ in data['Location'].unique():\n        for edu in data['Education Level'].unique():\n\n            mask = ((data['Location'] == occ) &\n                    (data['Education Level'] == edu))\n\n            group = data.loc[mask, 'Number of Children']\n\n            if group.isna().sum() == 0:\n                continue\n\n            value_counts = group.value_counts(normalize=True)\n    \n            if value_counts.empty:\n                probs = [0.2, 0.2, 0.2, 0.2, 0.2] \n                choices = [0.0, 1.0, 2.0, 3.0, 4.0]\n            else:\n                probs = []\n                choices = []\n                for cat in [0.0, 1.0, 2.0, 3.0, 4.0]:\n                    choices.append(cat)\n                    probs.append(value_counts.get(cat, 0))\n\n                probs = np.array(probs)\n                if probs.sum() > 0:\n                    probs = probs / probs.sum()\n                else:\n                    probs = [0.2, 0.2, 0.2, 0.2, 0.2]\n\n            n_missing = group.isna().sum()\n            fill_values = np.random.choice(choices, size=n_missing, p=probs)\n\n            data.loc[mask & data['Number of Children'].isna(), 'Number of Children'] = fill_values\n\n    # Filling the NaN values of Age : \n    for child in data['Number of Children'].unique():\n        for marital in data['Policy Type'].unique():\n\n            mask = ((data['Number of Children'] == child) &\n                    (data['Policy Type'] == marital))\n\n            group = data.loc[mask, 'Age']\n\n            \n            if group.isna().sum() == 0:\n                continue\n\n        \n            if group.dropna().shape[0] > 0:\n                mean_age = group.mean()\n                std_age = group.std()\n\n                \n                if np.isnan(std_age) or std_age == 0:\n                    std_age = 5  \n\n                n_missing = group.isna().sum()\n                fill_values = np.random.normal(mean_age, std_age, n_missing)\n\n                \n                fill_values = np.clip(fill_values, 18, 64)\n\n            else:\n            \n                n_missing = group.isna().sum()\n                fill_values = np.random.randint(18, 65, n_missing)\n\n            data.loc[mask & data['Age'].isna(), 'Age'] = fill_values\n    \n    # Filling NaN values of Insurance Duration and Vehicle Age\n    imputer = SimpleImputer(strategy='mean')\n    data[['Vehicle Age','Insurance Duration','Previous Claims']] = imputer.fit_transform(data[['Vehicle Age','Insurance Duration','Previous Claims']])\n\n    # Filling NaN values of Annual Income \n    original_income = data['Annual Income'].dropna().copy()\n    segment_count = 0\n    imputed_count = 0\n    fallback_count = 0\n    for marital in data['Policy Type'].unique():\n            for edu in data['Education Level'].unique():\n                for children in data['Number of Children'].unique():\n                    \n                    mask = ((data['Policy Type'] == marital) &\n                        (data['Education Level'] == edu) &\n                        (data['Number of Children'] == children))\n                    \n                    group = data.loc[mask, 'Annual Income']\n                    \n                    if group.isna().sum() == 0:\n                        continue\n                    \n                    segment_count += 1\n                    n_missing = group.isna().sum()\n                    \n                    existing_values = group.dropna()\n                    \n                    if len(existing_values) >= 5:  \n                        fill_values = np.random.choice(existing_values, size=n_missing, replace=True)\n                        imputed_count += n_missing\n                    else:\n                        fallback_mask = ((data['Policy Type'] == marital) &\n                                        (data['Education Level'] == edu))\n                        fallback_group = data.loc[fallback_mask, 'Annual Income'].dropna()\n                        \n                        if len(fallback_group) >= 5:\n                            fill_values = np.random.choice(fallback_group, size=n_missing, replace=True)\n                            fallback_count += n_missing\n                        else:\n                            fill_values = np.random.choice(original_income, size=n_missing, replace=True)\n                            fallback_count += n_missing\n                    data.loc[mask & data['Annual Income'].isna(), 'Annual Income'] = fill_values\n\n    # # Filling NaN values of Credit Score\n    original_income = data['Credit Score'].dropna().copy()\n    segment_count = 0\n    imputed_count = 0\n    fallback_count = 0\n    for marital in data['Location'].unique():\n            for edu in data['Policy Type'].unique():\n                for children in data['Property Type'].unique():\n                    \n                    mask = ((data['Location'] == marital) &\n                        (data['Policy Type'] == edu) &\n                        (data['Property Type'] == children))\n                    \n                    group = data.loc[mask, 'Credit Score']\n                    \n                    if group.isna().sum() == 0:\n                        continue\n                    \n                    segment_count += 1\n                    n_missing = group.isna().sum()\n                    \n                    existing_values = group.dropna()\n                    \n                    if len(existing_values) >= 5:  \n                        fill_values = np.random.choice(existing_values, size=n_missing, replace=True)\n                        imputed_count += n_missing\n                    else:\n                        fallback_mask = ((data['Location'] == marital) &\n                                        (data['Policy Type'] == edu))\n                        fallback_group = data.loc[fallback_mask, 'Credit Score'].dropna()\n                        \n                        if len(fallback_group) >= 5:\n                            fill_values = np.random.choice(fallback_group, size=n_missing, replace=True)\n                            fallback_count += n_missing\n                        else:\n                            fill_values = np.random.choice(original_income, size=n_missing, replace=True)\n                            fallback_count += n_missing\n                    data.loc[mask & data['Credit Score'].isna(), 'Credit Score'] = fill_values\n\n    # Filling NaN values of health Score    \n    original_income = data['Health Score'].dropna().copy()\n    segment_count = 0\n    imputed_count = 0\n    fallback_count = 0\n    for marital in data['Location'].unique():\n            for edu in data['Exercise Frequency'].unique():\n                for children in data['Smoking Status'].unique():\n                    \n                    mask = ((data['Location'] == marital) &\n                        (data['Exercise Frequency'] == edu) &\n                        (data['Smoking Status'] == children))\n                    \n                    group = data.loc[mask, 'Health Score']\n                    \n                    if group.isna().sum() == 0:\n                        continue\n                    \n                    segment_count += 1\n                    n_missing = group.isna().sum()\n                    \n                    existing_values = group.dropna()\n                    \n                    if len(existing_values) >= 5:  \n                        fill_values = np.random.choice(existing_values, size=n_missing, replace=True)\n                        imputed_count += n_missing\n                    else:\n                        fallback_mask = ((data['Location'] == marital) &\n                                        (data['Exercise Frequency'] == edu))\n                        fallback_group = data.loc[fallback_mask, 'Health Score'].dropna()\n                        \n                        if len(fallback_group) >= 5:\n                            fill_values = np.random.choice(fallback_group, size=n_missing, replace=True)\n                            fallback_count += n_missing\n                        else:\n                            fill_values = np.random.choice(original_income, size=n_missing, replace=True)\n                            fallback_count += n_missing\n                    data.loc[mask & data['Health Score'].isna(), 'Health Score'] = fill_values\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:37:11.992751Z","iopub.execute_input":"2025-10-14T16:37:11.993328Z","iopub.status.idle":"2025-10-14T16:37:12.023259Z","shell.execute_reply.started":"2025-10-14T16:37:11.993301Z","shell.execute_reply":"2025-10-14T16:37:12.022423Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data_Filling(X)\ndata_Filling(Xt)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:37:58.760415Z","iopub.execute_input":"2025-10-14T16:37:58.760850Z","iopub.status.idle":"2025-10-14T16:38:37.625684Z","shell.execute_reply.started":"2025-10-14T16:37:58.760826Z","shell.execute_reply":"2025-10-14T16:38:37.624899Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X.isnull().sum()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:38:37.626913Z","iopub.execute_input":"2025-10-14T16:38:37.627127Z","iopub.status.idle":"2025-10-14T16:38:37.973032Z","shell.execute_reply.started":"2025-10-14T16:38:37.627110Z","shell.execute_reply":"2025-10-14T16:38:37.972349Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.preprocessing import OrdinalEncoder, OneHotEncoder\nfrom sklearn.compose import ColumnTransformer\nimport pandas as pd\n\nordinal_cols = [\n    'Education Level', 'Location', 'Policy Type', 'Smoking Status',\n    'Exercise Frequency', 'Property Type', 'Customer Feedback'\n]\n\nordinal_categories = [\n    ['High School', \"Bachelor's\", 'Master\\'s', 'PhD'],\n    ['Rural', 'Suburban', 'Urban'],\n    ['Basic', 'Comprehensive', 'Premium'],\n    ['No', 'Yes'],\n    ['Rarely', 'Monthly', 'Weekly', 'Daily'],\n    ['House', 'Condo', 'Apartment'],\n    ['Poor', 'Good', 'Average'],]\n\nonehot_cols = ['Marital Status']\n\ntransformer = ColumnTransformer(transformers=[\n    ('ord', OrdinalEncoder(categories=ordinal_categories), ordinal_cols),\n    ('ohe', OneHotEncoder(drop='first', sparse_output=False), onehot_cols)\n], remainder='passthrough')\n\nX_enc = transformer.fit_transform(X)\nXt_enc = transformer.transform(Xt)\n\nencoded_feature_names = transformer.get_feature_names_out()\n\nX_enc = pd.DataFrame(X_enc, columns=encoded_feature_names, index=X.index)\nXt_enc = pd.DataFrame(Xt_enc, columns=encoded_feature_names, index=Xt.index)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:38:37.973743Z","iopub.execute_input":"2025-10-14T16:38:37.973943Z","iopub.status.idle":"2025-10-14T16:38:41.999706Z","shell.execute_reply.started":"2025-10-14T16:38:37.973926Z","shell.execute_reply":"2025-10-14T16:38:41.998783Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"cols = ['Education Level', 'Location', 'Policy Type',\n       'Smoking Status', 'Exercise Frequency', 'Property Type',\n       'Customer Feedback',\n       'Status_Married', 'Status_Single',\n       'Age', 'Annual Income',\n       'Number of Children', 'Health Score','Previous Claims',\n       'Vehicle Age', 'Credit Score',\n       'Insurance Duration','Policy Start Date']\n\nX_enc.columns = cols\nXt_enc.columns = cols","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:39:49.268736Z","iopub.execute_input":"2025-10-14T16:39:49.269035Z","iopub.status.idle":"2025-10-14T16:39:49.274270Z","shell.execute_reply.started":"2025-10-14T16:39:49.269014Z","shell.execute_reply":"2025-10-14T16:39:49.273199Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_enc.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:39:56.778837Z","iopub.execute_input":"2025-10-14T16:39:56.779183Z","iopub.status.idle":"2025-10-14T16:39:56.794731Z","shell.execute_reply.started":"2025-10-14T16:39:56.779135Z","shell.execute_reply":"2025-10-14T16:39:56.793757Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_enc['Children_Insurance_Vehicle'] = X_enc['Number of Children'] + X_enc['Insurance Duration'] + X_enc['Vehicle Age'] \nXt_enc['Children_Insurance_Vehicle'] = Xt_enc['Number of Children'] + Xt_enc['Insurance Duration'] + Xt_enc['Vehicle Age'] ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:40:10.310614Z","iopub.execute_input":"2025-10-14T16:40:10.310936Z","iopub.status.idle":"2025-10-14T16:40:10.483684Z","shell.execute_reply.started":"2025-10-14T16:40:10.310913Z","shell.execute_reply":"2025-10-14T16:40:10.482867Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sns.kdeplot(X_enc['Number of Children'])\nplt.show()\nsns.kdeplot(X_enc['Children_Insurance_Vehicle'])\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:40:38.833742Z","iopub.execute_input":"2025-10-14T16:40:38.834067Z","iopub.status.idle":"2025-10-14T16:40:46.057933Z","shell.execute_reply.started":"2025-10-14T16:40:38.834044Z","shell.execute_reply":"2025-10-14T16:40:46.057005Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_enc['Edu_Loc_Policy_Smoking'] = X_enc['Education Level'] + X_enc['Location'] + X_enc['Policy Type'] + X_enc['Smoking Status']\nXt_enc['Edu_Loc_Policy_Smoking'] = Xt_enc['Education Level'] + Xt_enc['Location'] + Xt_enc['Policy Type'] + Xt_enc['Smoking Status']","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:40:52.654805Z","iopub.execute_input":"2025-10-14T16:40:52.655166Z","iopub.status.idle":"2025-10-14T16:40:52.969013Z","shell.execute_reply.started":"2025-10-14T16:40:52.655120Z","shell.execute_reply":"2025-10-14T16:40:52.968273Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_enc['Exer_Pro_Cust_Status'] = X_enc['Exercise Frequency'] + X_enc['Property Type'] + X_enc['Customer Feedback'] + X_enc['Status_Married'] + X_enc['Status_Single']\nXt_enc['Exer_Pro_Cust_Status'] = Xt_enc['Exercise Frequency'] + Xt_enc['Property Type'] + Xt_enc['Customer Feedback'] + Xt_enc['Status_Married'] + Xt_enc['Status_Single']","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:40:57.199869Z","iopub.execute_input":"2025-10-14T16:40:57.200565Z","iopub.status.idle":"2025-10-14T16:40:57.584944Z","shell.execute_reply.started":"2025-10-14T16:40:57.200535Z","shell.execute_reply":"2025-10-14T16:40:57.584194Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def extract_date_features(data, date_col='Policy Start Date'):\n    data = data.copy()\n    if date_col in data.columns:\n        data[date_col] = pd.to_datetime(data[date_col])\n        data['Policy_Year'] = data[date_col].dt.year\n        data['Policy_Month'] = data[date_col].dt.month\n        data['Policy_Quarter'] = data[date_col].dt.quarter\n        data['Policy_DayOfYear'] = data[date_col].dt.dayofyear\n        data['Policy_DayOfWeek'] = data[date_col].dt.dayofweek\n        ref_date = pd.Timestamp('2025-10-05')\n        data['Policy_Age_Days'] = (ref_date - data[date_col]).dt.days\n        data.drop(columns=[date_col], inplace=True)\n    return data\n\n\ndef create_features(data):\n    data = data.copy()\n    if 'Age' in data.columns and 'Smoking Status' in data.columns:\n        data['Age_Smoking_Interaction'] = data['Age'] * (data['Smoking Status'] == 1.0).astype(int)\n    if 'Health Score' in data.columns and 'Exercise Frequency' in data.columns:\n        freq_map = {'Daily': 4, 'Weekly': 3, 'Monthly': 2, 'Rarely': 1, 'Never': 0}\n        data['Health_Exercise_Interaction'] = data['Health Score'] * data['Exercise Frequency'].map(freq_map).fillna(0)\n    if 'Annual Income' in data.columns and 'Number of Children' in data.columns:\n        data['Income_per_Child'] = data['Annual Income'] / (data['Number of Children'] + 1)\n    if 'Credit Score' in data.columns and 'Annual Income' in data.columns:\n        data['Credit_to_Income_Ratio'] = data['Credit Score'] / (data['Annual Income'] + 1)\n    if 'Previous Claims' in data.columns and 'Insurance Duration' in data.columns:\n        data['Claims_per_Year'] = data['Previous Claims'] / (data['Insurance Duration'] + 0.1)\n    if 'Vehicle Age' in data.columns:\n        data['Vehicle_Age_Squared'] = data['Vehicle Age'] ** 2\n    if 'Age' in data.columns:\n        bins = [0, 25, 35, 45, 55, 65, 100]\n        labels = [1, 2, 3, 4, 5, 6]\n        data['Age_Group'] = pd.cut(data['Age'], bins=bins, labels=labels, right=False)\n        data['Age_Group'] = data['Age_Group'].astype(float).fillna(0).astype(int)\n    return data\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:43:14.095183Z","iopub.execute_input":"2025-10-14T16:43:14.095513Z","iopub.status.idle":"2025-10-14T16:43:14.106425Z","shell.execute_reply.started":"2025-10-14T16:43:14.095492Z","shell.execute_reply":"2025-10-14T16:43:14.105451Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_enc = extract_date_features(X_enc)\nXt_enc = extract_date_features(Xt_enc)\nX_enc = create_features(X_enc)\nXt_enc = create_features(Xt_enc)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:43:31.349829Z","iopub.execute_input":"2025-10-14T16:43:31.350193Z","iopub.status.idle":"2025-10-14T16:43:38.729009Z","shell.execute_reply.started":"2025-10-14T16:43:31.350129Z","shell.execute_reply":"2025-10-14T16:43:38.728002Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def winsorize_outliers(df, lower=0.01, upper=0.99):\n    df_win = df.copy()\n    for col in df.columns:\n        if not col.endswith('_missing'):  \n            lower_bound = df[col].quantile(lower)\n            upper_bound = df[col].quantile(upper)\n            df_win[col] = df[col].clip(lower=lower_bound, upper=upper_bound)\n    return df_win\n\nX_enc = winsorize_outliers(X_enc, lower=0.01, upper=0.99)\nXt_enc = winsorize_outliers(Xt_enc, lower=0.01, upper=0.99)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:43:42.374815Z","iopub.execute_input":"2025-10-14T16:43:42.375177Z","iopub.status.idle":"2025-10-14T16:44:43.481617Z","shell.execute_reply.started":"2025-10-14T16:43:42.375129Z","shell.execute_reply":"2025-10-14T16:44:43.480780Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_enc.drop(columns=['Number of Children','Insurance Duration','Vehicle Age'], inplace=True)\nXt_enc.drop(columns=['Number of Children','Insurance Duration','Vehicle Age'], inplace=True)\nX_enc.drop(columns=['Exercise Frequency','Property Type','Customer Feedback','Status_Married','Status_Single'], inplace=True)\nXt_enc.drop(columns=['Exercise Frequency','Property Type','Customer Feedback','Status_Married','Status_Single'], inplace=True)\nX_enc.drop(columns=['Education Level','Location','Policy Type','Smoking Status'], inplace=True)\nXt_enc.drop(columns=['Education Level','Location','Policy Type','Smoking Status'], inplace=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:44:43.483038Z","iopub.execute_input":"2025-10-14T16:44:43.483371Z","iopub.status.idle":"2025-10-14T16:44:45.194219Z","shell.execute_reply.started":"2025-10-14T16:44:43.483342Z","shell.execute_reply":"2025-10-14T16:44:45.193003Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"temp = X_enc.copy()\ntemp_test = Xt_enc.copy()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:44:45.195114Z","iopub.execute_input":"2025-10-14T16:44:45.195441Z","iopub.status.idle":"2025-10-14T16:44:46.118512Z","shell.execute_reply.started":"2025-10-14T16:44:45.195419Z","shell.execute_reply":"2025-10-14T16:44:46.117634Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\n\nX_enc_converted = X_enc.copy()\nfor col in X_enc_converted.select_dtypes(include='object').columns:\n   X_enc_converted[col] = pd.to_numeric(X_enc_converted[col], errors='coerce')\n\nX_enc_converted = X_enc_converted.fillna(0).astype(int)\n\nprint(X_enc_converted.dtypes)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:44:46.120023Z","iopub.execute_input":"2025-10-14T16:44:46.120364Z","iopub.status.idle":"2025-10-14T16:44:47.859609Z","shell.execute_reply.started":"2025-10-14T16:44:46.120328Z","shell.execute_reply":"2025-10-14T16:44:47.858678Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nXt_enc_converted = Xt_enc.copy()\nfor col in Xt_enc_converted.select_dtypes(include='object').columns:\n   Xt_enc_converted[col] = pd.to_numeric(Xt_enc_converted[col], errors='coerce')\n\nXt_enc_converted = Xt_enc_converted.fillna(0).astype(int)\n\nprint(Xt_enc_converted.dtypes)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:45:12.547988Z","iopub.execute_input":"2025-10-14T16:45:12.548312Z","iopub.status.idle":"2025-10-14T16:45:13.460073Z","shell.execute_reply.started":"2025-10-14T16:45:12.548289Z","shell.execute_reply":"2025-10-14T16:45:13.459278Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nX_train,X_test,y_train,y_test = train_test_split(X_enc_converted,y,test_size=0.4,random_state=42)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:45:21.341794Z","iopub.execute_input":"2025-10-14T16:45:21.342118Z","iopub.status.idle":"2025-10-14T16:45:21.588666Z","shell.execute_reply.started":"2025-10-14T16:45:21.342092Z","shell.execute_reply":"2025-10-14T16:45:21.587694Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.linear_model import ElasticNet\nfrom sklearn.tree import DecisionTreeRegressor\nfrom sklearn.ensemble import RandomForestRegressor, ExtraTreesRegressor, GradientBoostingRegressor\nfrom sklearn.neighbors import KNeighborsRegressor\nfrom sklearn.svm import SVR\nfrom sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score\n\nfrom xgboost import XGBClassifier\nfrom lightgbm import LGBMClassifier\nfrom catboost import CatBoostClassifier","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:45:27.253473Z","iopub.execute_input":"2025-10-14T16:45:27.254235Z","iopub.status.idle":"2025-10-14T16:45:33.556424Z","shell.execute_reply.started":"2025-10-14T16:45:27.254197Z","shell.execute_reply":"2025-10-14T16:45:33.555589Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score\nimport numpy as np\n\ndef calculate_rmse(y_true, y_pred):\n    return np.sqrt(mean_squared_error(y_true, y_pred))\n\n# Universal model evaluation function\ndef evaluate_model(model, X_train, y_train, X_test, y_test, X_final, model_name):\n    print(f\"\\n{'='*60}\")\n    print(f\"Training {model_name}...\")\n    print(f\"{'='*60}\")\n    \n    # Train the model\n    model.fit(X_train, y_train)\n    \n    # Predictions\n    y_train_pred = model.predict(X_train)\n    y_test_pred = model.predict(X_test)\n    final_pred = model.predict(X_final)\n    \n    # Calculate metrics\n    train_rmse = calculate_rmse(y_train, y_train_pred)\n    test_rmse = calculate_rmse(y_test, y_test_pred)\n    train_mae = mean_absolute_error(y_train, y_train_pred)\n    test_mae = mean_absolute_error(y_test, y_test_pred)\n    train_r2 = r2_score(y_train, y_train_pred)\n    test_r2 = r2_score(y_test, y_test_pred)\n    \n    # Print results\n    print(f\"\\nRMSE: {train_rmse:.4f}\")\n    # print(f\"Test RMSE:  {test_rmse:.4f}\")\n    print(f\"MAE:  {train_mae:.4f}\")\n    # print(f\"Test MAE:   {test_mae:.4f}\")\n    print(f\"R² Score:   {train_r2:.4f}\")\n    # print(f\"Test R²:    {test_r2:.4f}\")\n    \n    # Target variable statistics\n    print(\"\\nTarget Variable Statistics:\")\n    print(f\"Min:   {y_train.min():.4f}\")\n    print(f\"Max:   {y_train.max():.4f}\")\n    print(f\"Range: {(y_train.max() - y_train.min()):.4f}\")\n    print(f\"Mean:  {y_train.mean():.4f}\")\n    print(f\"Std:   {y_train.std():.4f}\")\n\n    # RMSE percentage errors\n    range_y = y_train.max() - y_train.min()\n    rmse_pct_range = (test_rmse / range_y) * 100\n    rmse_pct_mean = (test_rmse / y_train.mean()) * 100\n\n    # print(f\"\\nRMSE as % of range: {rmse_pct_range:.2f}%\")\n    # print(f\"RMSE as % of mean:  {rmse_pct_mean:.2f}%\")\n    \n    # Return test RMSE and final predictions\n    return {\n        \"model_name\": model_name,\n        \"train_rmse\": train_rmse,\n        \"test_rmse\": test_rmse,\n        \"train_r2\": train_r2,\n        \"test_r2\": test_r2,\n        \"predictions\": final_pred\n    }\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:46:30.143018Z","iopub.execute_input":"2025-10-14T16:46:30.143779Z","iopub.status.idle":"2025-10-14T16:46:30.153045Z","shell.execute_reply.started":"2025-10-14T16:46:30.143752Z","shell.execute_reply":"2025-10-14T16:46:30.152053Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dt = DecisionTreeRegressor(random_state=42, max_depth=10)\npred_dt = evaluate_model(dt, X_train, y_train, X_test, y_test,Xt_enc, \"Decision Tree\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:46:43.542996Z","iopub.execute_input":"2025-10-14T16:46:43.543553Z","iopub.status.idle":"2025-10-14T16:46:48.267774Z","shell.execute_reply.started":"2025-10-14T16:46:43.543527Z","shell.execute_reply":"2025-10-14T16:46:48.266925Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from xgboost import XGBRegressor\nxgb = XGBRegressor(n_estimators=100, random_state=42, learning_rate=0.01, max_depth=10, n_jobs=-1)\npred_xg = evaluate_model(xgb, X_train, y_train, X_test, y_test,Xt_enc_converted, \"XGBoost\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:47:05.623085Z","iopub.execute_input":"2025-10-14T16:47:05.623902Z","iopub.status.idle":"2025-10-14T16:47:12.950700Z","shell.execute_reply.started":"2025-10-14T16:47:05.623872Z","shell.execute_reply":"2025-10-14T16:47:12.949779Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from lightgbm import LGBMRegressor\n\n# Initialize LightGBM model\nlgb_model = LGBMRegressor(\n    n_estimators=100,\n    random_state=42,\n    learning_rate=0.01,\n    max_depth=13\n)\n\n# Evaluate using your evaluate_model() function\npred_lgb = evaluate_model(lgb_model, X_train, y_train, X_test, y_test, Xt_enc_converted, \"LightGBM\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:47:27.788378Z","iopub.execute_input":"2025-10-14T16:47:27.788721Z","iopub.status.idle":"2025-10-14T16:47:34.675086Z","shell.execute_reply.started":"2025-10-14T16:47:27.788699Z","shell.execute_reply":"2025-10-14T16:47:34.674227Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from catboost import CatBoostRegressor\ncat = CatBoostRegressor(n_estimators=100, random_state=42, learning_rate=0.01, max_depth=16)\npred_cat = evaluate_model(cat, X_train, y_train, X_test, y_test,Xt_enc_converted, \"CatBoost\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:47:40.968439Z","iopub.execute_input":"2025-10-14T16:47:40.968736Z","iopub.status.idle":"2025-10-14T16:49:21.635919Z","shell.execute_reply.started":"2025-10-14T16:47:40.968714Z","shell.execute_reply":"2025-10-14T16:49:21.635056Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"final_pred = (pred_cat['predictions'] + pred_dt['predictions'] + pred_lgb['predictions'] + pred_xg['predictions'])/4","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:49:21.637136Z","iopub.execute_input":"2025-10-14T16:49:21.637405Z","iopub.status.idle":"2025-10-14T16:49:21.644989Z","shell.execute_reply.started":"2025-10-14T16:49:21.637386Z","shell.execute_reply":"2025-10-14T16:49:21.644185Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_ids = pd.read_csv('/kaggle/input/carnival-risk-analytics-challenge/test.csv')['id']","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:49:21.645905Z","iopub.execute_input":"2025-10-14T16:49:21.646136Z","iopub.status.idle":"2025-10-14T16:49:23.710567Z","shell.execute_reply.started":"2025-10-14T16:49:21.646117Z","shell.execute_reply":"2025-10-14T16:49:23.709875Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission = pd.DataFrame({\n    'id': test_ids,\n    'Premium Amount': final_pred\n})\nsubmission.to_csv('submission.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:49:30.847636Z","iopub.execute_input":"2025-10-14T16:49:30.847974Z","iopub.status.idle":"2025-10-14T16:49:32.103554Z","shell.execute_reply.started":"2025-10-14T16:49:30.847951Z","shell.execute_reply":"2025-10-14T16:49:32.102691Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission = pd.DataFrame({\n    'id': test_ids,\n    'Premium Amount': pred_cat['predictions']\n})\nsubmission.to_csv('submission1.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:52:35.258257Z","iopub.execute_input":"2025-10-14T16:52:35.258588Z","iopub.status.idle":"2025-10-14T16:52:36.540444Z","shell.execute_reply.started":"2025-10-14T16:52:35.258565Z","shell.execute_reply":"2025-10-14T16:52:36.539612Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_sampled1 = X_train.sample(n=260000, random_state=64)\ny_sample1 = y_train.loc[X_sampled1.index]\ncat1 = CatBoostRegressor(n_estimators=100, random_state=64, learning_rate=0.01, max_depth=16)\npred_cat1 = evaluate_model(cat1, X_sampled1, y_sample1, X_test, y_test,Xt_enc_converted, \"CatBoost\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:57:11.304699Z","iopub.execute_input":"2025-10-14T16:57:11.304998Z","iopub.status.idle":"2025-10-14T16:58:56.699083Z","shell.execute_reply.started":"2025-10-14T16:57:11.304978Z","shell.execute_reply":"2025-10-14T16:58:56.698176Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_sampled2 = X_train.sample(n=260000, random_state=46)\ny_sample2 = y_train.loc[X_sampled2.index]\ncat2 = CatBoostRegressor(n_estimators=100, random_state=46, learning_rate=0.01, max_depth=16)\npred_cat2 = evaluate_model(cat2, X_sampled2, y_sample2, X_test, y_test,Xt_enc_converted, \"CatBoost\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T16:58:56.700304Z","iopub.execute_input":"2025-10-14T16:58:56.700553Z","iopub.status.idle":"2025-10-14T17:00:48.474180Z","shell.execute_reply.started":"2025-10-14T16:58:56.700532Z","shell.execute_reply":"2025-10-14T17:00:48.473203Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_sampled3 = X_train.sample(n=260000, random_state=123)\ny_sample3 = y_train.loc[X_sampled2.index]\ncat3 = CatBoostRegressor(n_estimators=100, random_state=123, learning_rate=0.02, max_depth=16)\npred_cat3 = evaluate_model(cat3, X_sampled3, y_sample3, X_test, y_test,Xt_enc_converted, \"CatBoost\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T17:00:48.475207Z","iopub.execute_input":"2025-10-14T17:00:48.475519Z","iopub.status.idle":"2025-10-14T17:02:48.517634Z","shell.execute_reply.started":"2025-10-14T17:00:48.475498Z","shell.execute_reply":"2025-10-14T17:02:48.516705Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_sampled4 = X_train.sample(n=260000, random_state=321)\ny_sample4 = y_train.loc[X_sampled2.index]\ncat4 = CatBoostRegressor(n_estimators=100, random_state=321, learning_rate=0.02, max_depth=16)\npred_cat4 = evaluate_model(cat4, X_sampled4, y_sample4, X_test, y_test,Xt_enc_converted, \"CatBoost\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T17:02:48.519199Z","iopub.execute_input":"2025-10-14T17:02:48.519464Z","iopub.status.idle":"2025-10-14T17:04:21.571413Z","shell.execute_reply.started":"2025-10-14T17:02:48.519443Z","shell.execute_reply":"2025-10-14T17:04:21.570433Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"final_pred = (pred_cat1['predictions'] + pred_cat2['predictions'] + pred_cat3['predictions'] + pred_cat4['predictions'])/4","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T17:04:21.572823Z","iopub.execute_input":"2025-10-14T17:04:21.573513Z","iopub.status.idle":"2025-10-14T17:04:21.579355Z","shell.execute_reply.started":"2025-10-14T17:04:21.573488Z","shell.execute_reply":"2025-10-14T17:04:21.578512Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission = pd.DataFrame({\n    'id': test_ids,\n    'Premium Amount': final_pred\n})\nsubmission.to_csv('submission2.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-14T17:04:21.580090Z","iopub.execute_input":"2025-10-14T17:04:21.580332Z","iopub.status.idle":"2025-10-14T17:04:22.842976Z","shell.execute_reply.started":"2025-10-14T17:04:21.580313Z","shell.execute_reply":"2025-10-14T17:04:22.842173Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}