{"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":"none","dataSources":[{"sourceType":"competition","sourceId":112509,"databundleVersionId":14254895},{"sourceType":"modelInstanceVersion","sourceId":773800,"databundleVersionId":15927866,"modelInstanceId":115450,"modelId":138703}],"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# For data manipulation\nimport os\nimport pandas as pd\nimport numpy as np\nfrom tqdm import tqdm\n\n# For machine learning model\nfrom sklearn.ensemble import RandomForestRegressor\n\n# For computer vision\nimport tensorflow as tf\nfrom tensorflow.keras.applications.vgg16 import VGG16, preprocess_input\nfrom tensorflow.keras.preprocessing import image\n\n\n# ===============================\n# PATHS\n# ===============================\n\n# Base dataset path\nBASE_PATH = \"/kaggle/input/competitions/csiro-biomass\"\nMODEL_PATH = \"/kaggle/input/models/keras/vgg/keras/vgg_16_imagenet/3\"\n\n# CSV files\nTRAIN_CSV_PATH = os.path.join(BASE_PATH, 'train.csv')\nTEST_CSV_PATH = os.path.join(BASE_PATH, 'test.csv')\n\n# Image folders\nTRAIN_IMG_DIR = BASE_PATH\nTEST_IMG_DIR = BASE_PATH\n\n\n# ===============================\n# LOAD DATA\n# ===============================\n\ntrain_df = pd.read_csv(TRAIN_CSV_PATH)\ntest_df = pd.read_csv(TEST_CSV_PATH)\n\n\n# Convert to wide format\ntrain_wide_df = train_df.pivot(\n    index='image_path',\n    columns='target_name',\n    values='target'\n).reset_index()\n\nprint(\"Train wide dataframe shape:\", train_wide_df.shape)\n\n\n# ===============================\n# CONFIG\n# ===============================\n\nIMG_SIZE = 224\nRANDOM_SEED = 999\n\n\n# ===============================\n# LOAD VGG16 MODEL\n# ===============================\nfull_model = tf.keras.models.load_model(MODEL_PATH)\n\n\nbase_model = tf.keras.Model(\n    inputs=full_model.input,\n    outputs=full_model.layers[-2].output\n)\n\nbase_model.trainable = False\n\nprint(f\"Model loaded. Feature vector output shape: {base_model.output_shape}\")\n\n\n# ===============================\n# FEATURE EXTRACTION FUNCTION\n# ===============================\n\ndef extract_features(img_path):\n\n    img = image.load_img(img_path, target_size=(IMG_SIZE, IMG_SIZE))\n    img_array = image.img_to_array(img)\n\n    img_array = np.expand_dims(img_array, axis=0)\n    img_array = preprocess_input(img_array)\n\n    features = base_model.predict(img_array, verbose=0)\n\n    return features.flatten()\n\n\n# ===============================\n# EXTRACT TRAIN FEATURES\n# ===============================\n\ntrain_features = []\n\nprint(\"Extracting TRAIN features...\")\n\nfor img_path in tqdm(train_wide_df[\"image_path\"]):\n\n    full_path = os.path.join(TRAIN_IMG_DIR, img_path)\n\n    features = extract_features(full_path)\n\n    train_features.append(features)\n\ntrain_features = np.array(train_features)\n\nprint(\"Train feature matrix:\", train_features)\n\n\n# ===============================\n# TRAIN MODEL\n# ===============================\n\nTARGET_COLS = train_wide_df.columns[1:]\n\nX_train = train_features\ny_train = train_wide_df[TARGET_COLS]\n\nprint(\"X_train shape:\", X_train.shape)\nprint(\"y_train shape:\\n\", y_train)\n\nprint(\"Training RandomForest...\")\n\nmodel = RandomForestRegressor(\n    n_estimators=300,\n    random_state=RANDOM_SEED,\n    n_jobs=-1,\n    verbose=2\n)\n\nmodel.fit(X_train, y_train)\n\nprint(\"Training completed.\")\n\n\n# =============================== TEST FEATURES AND PREDICTION ===============================\n\n# ===============================\n# EXTRACT TEST FEATURES\n# ===============================\n\ntest_features = []\n\nunique_image_paths = test_df[\"image_path\"].unique()  # <-- también aquí\n\nprint(\"Extracting TEST features...\")\n\nfor img_path in tqdm(unique_image_paths):\n\n    full_path = os.path.join(TEST_IMG_DIR, img_path)\n    features = extract_features(full_path)\n    test_features.append(features)\n\ntest_features = np.array(test_features)\n\n\n# ===============================\n# PREDICT\n# ===============================\n\nprint(\"Predicting...\")\n\ntest_predictions = model.predict(test_features)\nprint(\"Test predictions shape:\", test_predictions)\n\n# ===============================\n# CREATE SUBMISSION\n# ===============================\n\n# Armar dataframe wide con las predicciones\npredictions_df = pd.DataFrame(\n    test_predictions,\n    columns=TARGET_COLS\n)\npredictions_df.insert(0, \"image_path\", unique_image_paths)\n\n# Pasar de wide a long\npredictions_long_df = predictions_df.melt(\n    id_vars=[\"image_path\"],\n    value_vars=TARGET_COLS,\n    var_name=\"target_name\",\n    value_name=\"target\"\n)\n\n# Merge con test_df para recuperar el sample_id original\nsubmission_df = pd.merge(\n    test_df[[\"sample_id\", \"image_path\", \"target_name\"]],\n    predictions_long_df,\n    on=[\"image_path\", \"target_name\"]\n)[[\"sample_id\", \"target\"]].dropna()\n\nsubmission_df.to_csv(\"submission.csv\", index=False)\n\nprint(\"Submission file created: submission.csv\")\nprint(submission_df.head())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-14T22:56:44.361216Z","iopub.execute_input":"2026-03-14T22:56:44.362007Z","iopub.status.idle":"2026-03-14T23:05:34.180124Z","shell.execute_reply.started":"2026-03-14T22:56:44.361975Z","shell.execute_reply":"2026-03-14T23:05:34.179249Z"}},"outputs":[],"execution_count":null}]}