{"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":31089,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# =================== FULL PIPELINE (Single Kaggle Cell) ===================\n\n# Cell 0 - Setup\n# !pip install lightgbm scikit-learn --quiet\n\nimport os\nimport numpy as np\nimport pandas as pd\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.pipeline import Pipeline\nfrom sklearn.impute import SimpleImputer\nfrom sklearn.preprocessing import OneHotEncoder, OrdinalEncoder, StandardScaler\nfrom sklearn.compose import ColumnTransformer\nfrom sklearn.metrics import mean_squared_error\n\n# LightGBM\ntry:\n    import lightgbm as lgb\nexcept Exception as e:\n    print(\"LightGBM not installed:\", e)\n    lgb = None\n\nprint(\"Libraries loaded. LightGBM available:\", bool(lgb))\n\n# =================== Cell 1 - Load Data ===================\nTRAIN_PATH = \"/kaggle/input/carnival-risk-analytics-challenge/train.csv\"\nTEST_PATH = \"/kaggle/input/carnival-risk-analytics-challenge/test.csv\"\nSUB_PATH = \"/kaggle/input/carnival-risk-analytics-challenge/sample_submission.csv\"\n\ntrain = pd.read_csv(TRAIN_PATH)\ntest = pd.read_csv(TEST_PATH)\nsub = pd.read_csv(SUB_PATH)\n\nprint(\"Train shape:\", train.shape, \"| Test shape:\", test.shape)\n\n# =================== Cell 2 - Detect TARGET & ID ===================\n# Force column names to match submission format\nTARGET = \"Premium Amount\"\nID_COL = \"id\"\n\nprint(\"Using TARGET:\", TARGET)\nprint(\"Using ID_COL:\", ID_COL)\n\n# =================== Cell 3 - Preprocessor ===================\ndef build_preprocessor(X, cat_threshold=50):\n    if ID_COL in X.columns:\n        X = X.drop(columns=[ID_COL])\n\n    num_cols = X.select_dtypes(include=[np.number]).columns.tolist()\n    cat_cols = X.select_dtypes(include=[\"object\", \"category\"]).columns.tolist()\n\n    if TARGET in num_cols:\n        num_cols.remove(TARGET)\n\n    low_card_cols = [c for c in cat_cols if X[c].nunique() <= cat_threshold]\n    high_card_cols = [c for c in cat_cols if X[c].nunique() > cat_threshold]\n\n    print(f\"Numerical: {len(num_cols)}, Low-card cat: {len(low_card_cols)}, High-card cat: {len(high_card_cols)}\")\n\n    num_pipe = Pipeline([\n        (\"imputer\", SimpleImputer(strategy=\"median\")),\n        (\"scaler\", StandardScaler())\n    ])\n    cat_low_pipe = Pipeline([\n        (\"imputer\", SimpleImputer(strategy=\"most_frequent\")),\n        (\"onehot\", OneHotEncoder(handle_unknown=\"ignore\", sparse_output=False))\n    ])\n    cat_high_pipe = Pipeline([\n        (\"imputer\", SimpleImputer(strategy=\"most_frequent\")),\n        (\"ord\", OrdinalEncoder(handle_unknown=\"use_encoded_value\", unknown_value=-1))\n    ])\n\n    transformers = []\n    if num_cols: transformers.append((\"num\", num_pipe, num_cols))\n    if low_card_cols: transformers.append((\"cat_low\", cat_low_pipe, low_card_cols))\n    if high_card_cols: transformers.append((\"cat_high\", cat_high_pipe, high_card_cols))\n\n    return ColumnTransformer(transformers, remainder=\"drop\")\n\n# =================== Cell 4 - Target Transform + Split ===================\ny_original = train[TARGET].values\ny_log = np.log1p(y_original)  # log(1 + y)\n\nX = train.drop(columns=[TARGET, ID_COL], errors=\"ignore\")\npreprocessor = build_preprocessor(X)\n\nX_train, X_val, y_train, y_val = train_test_split(X, y_log, test_size=0.2, random_state=42)\n\n# =================== Cell 5 - LightGBM Model ===================\nif lgb:\n    model = Pipeline([\n        (\"preproc\", preprocessor),\n        (\"model\", lgb.LGBMRegressor(\n            n_estimators=600,\n            learning_rate=0.03,\n            num_leaves=31,\n            subsample=0.85,\n            colsample_bytree=0.85,\n            random_state=42,\n            n_jobs=-1,\n        ))\n    ])\n\n    print(\"\\nTraining LightGBM...\")\n    model.fit(X_train, y_train)\n\n    # Validation\n    val_preds_log = model.predict(X_val)\n    val_preds = np.expm1(val_preds_log)\n    y_val_original = np.expm1(y_val)\n\n    rmse_original = mean_squared_error(y_val_original, val_preds, squared=False)\n    rmse_log = mean_squared_error(y_val, val_preds_log, squared=False)\n\n    print(f\"\\nLightGBM RMSE (Original Scale): {rmse_original:.5f}\")\n    print(f\"LightGBM RMSE (Log Scale): {rmse_log:.5f}\")\n\nelse:\n    raise ImportError(\"LightGBM not found.\")\n\n# =================== Cell 6 - Train on Full Data & Predict Test ===================\nprint(\"\\nRetraining on full dataset for final predictions...\")\nfull_X = train.drop(columns=[TARGET, ID_COL], errors=\"ignore\")\nfull_y = np.log1p(train[TARGET].values)\nmodel.fit(full_X, full_y)\n\n# Predict test set\ntest_X = test.drop(columns=[ID_COL], errors=\"ignore\")\ntest_preds_log = model.predict(test_X)\ntest_preds = np.expm1(test_preds_log)\ntest_preds[test_preds < 0] = 0  # Clamp negatives\n\n# =================== Cell 7 - Save Submission ===================\nsubmission = pd.DataFrame({\n    ID_COL: test[ID_COL],\n    TARGET: test_preds\n})\n\noutput_path = \"/kaggle/working/submission.csv\"\nsubmission.to_csv(output_path, index=False)\n\nprint(\"\\n✅ Submission file saved to:\", output_path)\nprint(submission.head())\nprint(f\"\\nPrediction stats → Min: {submission[TARGET].min():.4f}, Max: {submission[TARGET].max():.4f}, Mean: {submission[TARGET].mean():.4f}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-04T06:32:28.580507Z","iopub.execute_input":"2025-10-04T06:32:28.580897Z","iopub.status.idle":"2025-10-04T06:33:30.929393Z","shell.execute_reply.started":"2025-10-04T06:32:28.580862Z","shell.execute_reply":"2025-10-04T06:33:30.928424Z"}},"outputs":[],"execution_count":null}]}