{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":98450,"databundleVersionId":11749951,"sourceType":"competition"}],"dockerImageVersionId":31041,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import mean_absolute_error\nimport xgboost as xgb\n\n# --- Configuration ---\nBASE_DIR    = \"/kaggle/input/beyond-visible-spectrum-ai-for-agriculture-2025\"\nNPY_DIR     = os.path.join(BASE_DIR, \"ot/ot\")\nTRAIN_CSV   = os.path.join(BASE_DIR, \"train.csv\")\nTEST_CSV    = os.path.join(BASE_DIR, \"test.csv\")\nSUBMISSION  = \"submission_xgb2.csv\"\nMODEL_FILE  = \"xgb_model.json\" # <-- Added model filename\n\nIMG_SHAPE   = (128, 128, 125)\nTARGET_SIZE = np.prod(IMG_SHAPE)\n\n\ndef load_and_flatten(path):\n    \"\"\"\n    Load a .npy file (or raw .npy if header corrupt), flatten to 1D,\n    pad by repeating last value if too short, or truncate if too long.\n    \"\"\"\n    try:\n        arr = np.load(path)\n        flat = arr.ravel()\n    except Exception:\n        flat = np.fromfile(path, dtype=np.float32)\n\n    # pad/truncate to TARGET_SIZE\n    if flat.size < TARGET_SIZE:\n        if flat.size == 0:\n            flat = np.zeros(TARGET_SIZE, dtype=np.float32)\n        else:\n            pad_vals = np.full(TARGET_SIZE - flat.size, flat[-1], dtype=np.float32)\n            flat = np.concatenate([flat, pad_vals])\n    else:\n        flat = flat[:TARGET_SIZE]\n\n    return flat\n\n\ndef extract_features(df):\n    \"\"\"\n    For each row in df (with 'id'), load the patch, fix shape, and compute\n    mean reflectance for each of the 125 bands.\n    Returns an (n_samples, 125) array.\n    \"\"\"\n    features = []\n    for fn in df['id']:\n        path = os.path.join(NPY_DIR, fn)\n        flat = load_and_flatten(path)\n        # reshape and compute band means\n        cube = flat.reshape(IMG_SHAPE)\n        band_means = cube.mean(axis=(0, 1))\n        features.append(band_means)\n    return np.vstack(features)\n\n\n# --- 1) Load CSVs ---\ntrain_df = pd.read_csv(TRAIN_CSV)\ntest_df  = pd.read_csv(TEST_CSV)\n\n# --- 2) Build feature matrices ---\nprint(\"Extracting features for training set...\")\nX = extract_features(train_df)      # shape (n_train, 125)\ny = train_df['label'].values\n\nprint(\"Extracting features for test set...\")\nX_test = extract_features(test_df) # shape (n_test, 125)\n\n# --- 3) Train‐validation split ---\nX_train, X_val, y_train, y_val = train_test_split(\n    X, y, test_size=0.1, random_state=42\n)\n\n# --- 4) XGBoost Regressor setup ---\nxgb_model = xgb.XGBRegressor(\n    n_estimators=800,\n    learning_rate=0.08,\n    max_depth=8,\n    subsample=0.8,\n    colsample_bytree=0.8,\n    random_state=42,\n    tree_method='hist'  # or 'hist' if no GPU\n)\n\n# --- 5) Train with early stopping ---\nxgb_model.fit(\n    X_train, y_train,\n    eval_set=[(X_train, y_train), (X_val, y_val)],\n    eval_metric='mae',\n    early_stopping_rounds=20,\n    verbose=True\n)\n\n# --- 6) Validation performance ---\ny_pred_val = xgb_model.predict(X_val)\nval_mae = mean_absolute_error(y_val, y_pred_val)\nprint(f\"Validation MAE: {val_mae:.4f}\")\n\n# --- 7) Save the Trained Model ---\n# This is the new section to save your model\nprint(f\"Saving model to {MODEL_FILE}...\")\nxgb_model.save_model(MODEL_FILE)\nprint(f\"✅ Model saved successfully!\")\n\n\n# --- 8) Predict on test set & save submission ---\ny_pred_test = xgb_model.predict(X_test)\ny_pred_test = np.clip(np.round(y_pred_test), 1, 100).astype(int)\n\nsubmission_df = pd.DataFrame({\n    \"id\": test_df[\"id\"],\n    \"label\": y_pred_test\n})\nsubmission_df.to_csv(SUBMISSION, index=False)\nprint(f\"✅ Submission saved to {SUBMISSION}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-25T17:00:37.072573Z","iopub.execute_input":"2025-09-25T17:00:37.072961Z","iopub.status.idle":"2025-09-25T17:02:08.778602Z","shell.execute_reply.started":"2025-09-25T17:00:37.072935Z","shell.execute_reply":"2025-09-25T17:02:08.777465Z"}},"outputs":[],"execution_count":null}]}