{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":125766,"databundleVersionId":14873485,"sourceType":"competition"}],"dockerImageVersionId":31260,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"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":"2026-02-18T07:11:04.001110Z","iopub.execute_input":"2026-02-18T07:11:04.001749Z","iopub.status.idle":"2026-02-18T07:11:05.064423Z","shell.execute_reply.started":"2026-02-18T07:11:04.001719Z","shell.execute_reply":"2026-02-18T07:11:05.063701Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport xgboost as xgb\nimport lightgbm as lgb\nfrom sklearn.model_selection import StratifiedKFold\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.metrics import accuracy_score\n\n# ==========================================\n# 1. Configuration\n# ==========================================\nN_FOLDS = 5  # Number of splits for Cross-Validation\nSEED = 42\n\n# Load Data\ntrain = pd.read_csv('/kaggle/input/bigdata2025classification/train.csv')\ntest = pd.read_csv('/kaggle/input/bigdata2025classification/test_without_labels.csv')\n\nprint(f\"Train Shape: {train.shape}\")\nprint(f\"Test Shape: {test.shape}\")\n\n# ==========================================\n# 2. Automated Preprocessing\n# ==========================================\n\n# A. Identify Target Column\n# It's the column in Train that isn't in Test\ntarget_col = list(set(train.columns) - set(test.columns))[0]\nprint(f\"Target Column: {target_col}\")\n\n# B. Identify ID Column\n# Remove ID to prevent the model from memorizing it\nid_col = None\nfor col in ['id', 'ID', 'Id']:\n    if col in test.columns:\n        id_col = col\n        break\n\n# Separate Target\ny = train[target_col]\nX = train.drop(columns=[target_col])\nX_test = test.copy()\n\n# Drop ID from features\nif id_col:\n    X = X.drop(columns=[id_col])\n    X_test = X_test.drop(columns=[id_col])\n\n# C. Encode Target (if it's text)\nle_target = LabelEncoder()\ny_encoded = le_target.fit_transform(y)\n\n# D. Handle Features (Label Encoding for Categoricals)\n# Gradient Boosters handle label-encoded categoricals very well\nobject_cols = X.select_dtypes(include=['object', 'category']).columns\n\nfor col in object_cols:\n    le = LabelEncoder()\n    # Combine to fit all categories\n    combined = pd.concat([X[col], X_test[col]], axis=0).astype(str)\n    le.fit(combined)\n    X[col] = le.transform(X[col].astype(str))\n    X_test[col] = le.transform(X_test[col].astype(str))\n\n# ==========================================\n# 3. Model Definition\n# ==========================================\n\n# XGBoost Parameters (Tuned for general performance)\nxgb_params = {\n    'n_estimators': 1000,\n    'learning_rate': 0.05,\n    'max_depth': 6,\n    'subsample': 0.8,\n    'colsample_bytree': 0.8,\n    'objective': 'multi:softmax' if len(np.unique(y_encoded)) > 2 else 'binary:logistic',\n    'num_class': len(np.unique(y_encoded)) if len(np.unique(y_encoded)) > 2 else None,\n    'n_jobs': -1,\n    'random_state': SEED,\n    'tree_method': 'hist' # Faster training\n}\n\n# LightGBM Parameters\nlgb_params = {\n    'n_estimators': 1000,\n    'learning_rate': 0.05,\n    'num_leaves': 31,\n    'subsample': 0.8,\n    'colsample_bytree': 0.8,\n    'objective': 'multiclass' if len(np.unique(y_encoded)) > 2 else 'binary',\n    'num_class': len(np.unique(y_encoded)) if len(np.unique(y_encoded)) > 2 else 1,\n    'n_jobs': -1,\n    'random_state': SEED,\n    'verbose': -1\n}\n\n# ==========================================\n# 4. Training Loop (Stratified K-Fold)\n# ==========================================\nskf = StratifiedKFold(n_splits=N_FOLDS, shuffle=True, random_state=SEED)\n\n# Arrays to store predictions\noof_preds_xgb = np.zeros(X.shape[0])\noof_preds_lgb = np.zeros(X.shape[0])\ntest_preds_xgb = []\ntest_preds_lgb = []\n\nprint(f\"\\nStarting {N_FOLDS}-Fold Cross-Validation...\")\n\nfor fold, (train_idx, val_idx) in enumerate(skf.split(X, y_encoded)):\n    X_tr, X_val = X.iloc[train_idx], X.iloc[val_idx]\n    y_tr, y_val = y_encoded[train_idx], y_encoded[val_idx]\n\n    # --- Train XGBoost ---\n    model_xgb = xgb.XGBClassifier(**xgb_params)\n    model_xgb.fit(X_tr, y_tr, eval_set=[(X_val, y_val)], verbose=False)\n    \n    val_pred_xgb = model_xgb.predict(X_val)\n    oof_preds_xgb[val_idx] = val_pred_xgb\n    test_preds_xgb.append(model_xgb.predict(X_test))\n    \n    # --- Train LightGBM ---\n    model_lgb = lgb.LGBMClassifier(**lgb_params)\n    model_lgb.fit(X_tr, y_tr, eval_set=[(X_val, y_val)])\n    \n    val_pred_lgb = model_lgb.predict(X_val)\n    oof_preds_lgb[val_idx] = val_pred_lgb\n    test_preds_lgb.append(model_lgb.predict(X_test))\n\n    print(f\"Fold {fold+1} | XGB Acc: {accuracy_score(y_val, val_pred_xgb):.4f} | LGB Acc: {accuracy_score(y_val, val_pred_lgb):.4f}\")\n\n# ==========================================\n# 5. Ensemble & Submission\n# ==========================================\n\n# Simple Voting: Mode of all predictions across folds and models\n# We combine predictions from both models across all folds (2 models * 5 folds = 10 predictions per row)\nfrom scipy.stats import mode\n\nall_preds = np.array(test_preds_xgb + test_preds_lgb) # Shape: (10, n_test_samples)\nfinal_preds_encoded, _ = mode(all_preds, axis=0)\nfinal_preds_encoded = final_preds_encoded.ravel()\n\n# Decode back to original labels\nfinal_preds = le_target.inverse_transform(final_preds_encoded)\n\n# Create Submission\nif id_col:\n    submission = pd.DataFrame({id_col: test[id_col], target_col: final_preds})\nelse:\n    submission = pd.DataFrame({target_col: final_preds})\n\nsubmission.to_csv('submission_advanced.csv', index=False)\nprint(\"\\nSuccess! 'submission_advanced.csv' saved.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-18T07:11:38.878138Z","iopub.execute_input":"2026-02-18T07:11:38.878760Z","iopub.status.idle":"2026-02-18T07:14:46.806185Z","shell.execute_reply.started":"2026-02-18T07:11:38.878728Z","shell.execute_reply":"2026-02-18T07:14:46.805510Z"}},"outputs":[],"execution_count":null}]}