{"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":84896,"databundleVersionId":10305135,"sourceType":"competition"}],"dockerImageVersionId":31153,"isInternetEnabled":false,"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},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================================\n# 🩺 Insurance Regression - Kaggle Version (with Visualizations)\n# ============================================================\n\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom sklearn.model_selection import train_test_split, GridSearchCV\nfrom sklearn.pipeline import Pipeline\nfrom sklearn.compose import ColumnTransformer\nfrom sklearn.impute import SimpleImputer\nfrom sklearn.preprocessing import OneHotEncoder, StandardScaler\nfrom sklearn.linear_model import Ridge\nfrom sklearn.ensemble import RandomForestRegressor, HistGradientBoostingRegressor\nfrom sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score\nimport joblib\nimport warnings\nwarnings.filterwarnings('ignore')\n\n# ---------- 1) Load Kaggle datasets ----------\n# Kaggle provides these in /kaggle/input/insurance-regression/\ntrain_df = pd.read_csv(\"/kaggle/input/insurance-regression/train.csv\")\ntest_df = pd.read_csv(\"/kaggle/input/insurance-regression/test.csv\")\n\nprint(\"Train shape:\", train_df.shape)\nprint(\"Test shape:\", test_df.shape)\nprint(train_df.head())\n\n# ---------- 2) EDA (Text + Visual) ----------\nprint(\"\\nMissing values per column:\\n\", train_df.isnull().sum())\nprint(\"\\nTarget ('charges') summary:\")\nprint(train_df['charges'].describe())\n\n# Pairplot\nsns.pairplot(train_df[['age', 'bmi', 'children', 'charges']])\nplt.suptitle(\"Pairwise Relationships\", y=1.02)\nplt.show()\n\n# Boxplot: smoker vs charges\nplt.figure(figsize=(6,4))\nsns.boxplot(x='smoker', y='charges', data=train_df, palette='coolwarm')\nplt.title(\"Charges vs Smoker\")\nplt.show()\n\n# Correlation heatmap\nplt.figure(figsize=(6,4))\nsns.heatmap(train_df.corr(numeric_only=True), annot=True, cmap='coolwarm')\nplt.title(\"Correlation Heatmap\")\nplt.show()\n\n# ---------- 3) Prepare data ----------\nTARGET = 'charges'\nX = train_df.drop(columns=[TARGET])\ny_orig = train_df[TARGET].copy()\n\n# Handle skewness\nskew = y_orig.skew()\nprint(f\"\\nTarget skewness: {skew:.2f}\")\nuse_log_target = True if skew > 1.0 else False\nif use_log_target:\n    print(\"Applying log1p transform to target.\")\n    y = np.log1p(y_orig)\nelse:\n    y = y_orig.copy()\n\n# ---------- 4) Train/validation split ----------\nX_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.2, random_state=42)\n\n# ---------- 5) Preprocessing ----------\nnumeric_features = ['age', 'bmi', 'children']\ncategorical_features = ['sex', 'smoker', 'region']\n\nnumeric_transformer = Pipeline([\n    ('imputer', SimpleImputer(strategy='median')),\n    ('scaler', StandardScaler())\n])\n\ncategorical_transformer = Pipeline([\n    ('imputer', SimpleImputer(strategy='most_frequent')),\n    ('onehot', OneHotEncoder(handle_unknown='ignore', sparse_output=False))\n])\n\npreprocessor = ColumnTransformer([\n    ('num', numeric_transformer, numeric_features),\n    ('cat', categorical_transformer, categorical_features),\n])\n\n# ---------- 6) Define models & hyperparameter tuning ----------\ndef rmse(y_true, y_pred):\n    return np.sqrt(mean_squared_error(y_true, y_pred))\n\n# Ridge\npipe_ridge = Pipeline([('preprocessor', preprocessor), ('reg', Ridge(random_state=42))])\nparam_grid_ridge = {'reg__alpha': [0.01, 0.1, 1, 10, 50, 100]}\ngs_ridge = GridSearchCV(pipe_ridge, param_grid_ridge, cv=5, scoring='neg_mean_squared_error', n_jobs=-1)\ngs_ridge.fit(X_train, y_train)\n\n# Random Forest\npipe_rf = Pipeline([('preprocessor', preprocessor),\n                    ('reg', RandomForestRegressor(random_state=42, n_jobs=-1))])\nparam_grid_rf = {\n    'reg__n_estimators': [100, 200],\n    'reg__max_depth': [None, 6, 12],\n    'reg__max_features': ['sqrt', 0.5]\n}\ngs_rf = GridSearchCV(pipe_rf, param_grid_rf, cv=4, scoring='neg_mean_squared_error', n_jobs=-1)\ngs_rf.fit(X_train, y_train)\n\n# HistGradientBoosting\npipe_hgb = Pipeline([('preprocessor', preprocessor),\n                     ('reg', HistGradientBoostingRegressor(random_state=42))])\nparam_grid_hgb = {\n    'reg__learning_rate': [0.01, 0.05, 0.1],\n    'reg__max_iter': [100, 200],\n    'reg__max_depth': [3, 6]\n}\ngs_hgb = GridSearchCV(pipe_hgb, param_grid_hgb, cv=4, scoring='neg_mean_squared_error', n_jobs=-1)\ngs_hgb.fit(X_train, y_train)\n\n# ---------- 7) Evaluate on validation ----------\nmodels = {\n    'Ridge': gs_ridge.best_estimator_,\n    'RandomForest': gs_rf.best_estimator_,\n    'HistGB': gs_hgb.best_estimator_\n}\n\nresults = {}\nfor name, model in models.items():\n    ypred = model.predict(X_valid)\n    if use_log_target:\n        ypred_orig = np.expm1(ypred)\n        y_valid_orig = np.expm1(y_valid)\n    else:\n        ypred_orig = ypred\n        y_valid_orig = y_valid\n    results[name] = {\n        'RMSE': rmse(y_valid_orig, ypred_orig),\n        'MAE': mean_absolute_error(y_valid_orig, ypred_orig),\n        'R2': r2_score(y_valid, model.predict(X_valid))\n    }\n\nprint(\"\\nValidation Results:\")\nfor k, v in results.items():\n    print(f\"{k}: RMSE={v['RMSE']:.2f}, MAE={v['MAE']:.2f}, R2={v['R2']:.3f}\")\n\n# Visual comparison\nplt.figure(figsize=(6,4))\nsns.barplot(x=list(results.keys()), y=[v['RMSE'] for v in results.values()], palette=\"crest\")\nplt.title(\"Model Comparison - RMSE\")\nplt.ylabel(\"RMSE\")\nplt.show()\n\nbest_name = min(results, key=lambda k: results[k]['RMSE'])\nprint(f\"\\n✅ Best model: {best_name}\")\nbest_model = models[best_name]\n\n# ---------- 8) Visualize predictions ----------\ny_valid_pred = best_model.predict(X_valid)\nif use_log_target:\n    y_valid_pred = np.expm1(y_valid_pred)\n    y_valid_true = np.expm1(y_valid)\nelse:\n    y_valid_true = y_valid\n\nplt.figure(figsize=(6,5))\nsns.scatterplot(x=y_valid_true, y=y_valid_pred, alpha=0.6)\nplt.plot([0, max(y_valid_true)], [0, max(y_valid_true)], 'r--')\nplt.xlabel(\"Actual Charges\")\nplt.ylabel(\"Predicted Charges\")\nplt.title(f\"Actual vs Predicted ({best_name})\")\nplt.show()\n\nerrors = y_valid_true - y_valid_pred\nplt.figure(figsize=(6,4))\nsns.histplot(errors, bins=30, kde=True, color='purple')\nplt.title(\"Distribution of Prediction Errors\")\nplt.xlabel(\"Error (Actual - Predicted)\")\nplt.show()\n\n# ---------- 9) Train on full data & predict test ----------\nbest_model.fit(X, y)\ny_pred_test = best_model.predict(test_df)\nif use_log_target:\n    y_pred_test = np.expm1(y_pred_test)\n\n# ---------- 10) Create Kaggle submission ----------\nsubmission = pd.DataFrame({\n    'id': test_df['id'],   # Kaggle test file includes an id column\n    'charges': y_pred_test\n})\nsubmission.to_csv(\"submission.csv\", index=False)\nprint(\"\\n✅ Submission file 'submission.csv' created successfully!\")\nprint(submission.head())\n\n\n\n\n\n\n\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-09T05:27:25.962879Z","iopub.execute_input":"2025-10-09T05:27:25.963572Z","iopub.status.idle":"2025-10-09T05:27:25.998745Z","shell.execute_reply.started":"2025-10-09T05:27:25.963544Z","shell.execute_reply":"2025-10-09T05:27:25.997352Z"}},"outputs":[],"execution_count":null}]}