update 01 file train_odc.py
This commit is contained in:
+57
-22
@@ -726,7 +726,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 16,
|
"execution_count": null,
|
||||||
"id": "2e955884-d4af-422d-a8e6-d436199540e0",
|
"id": "2e955884-d4af-422d-a8e6-d436199540e0",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"tags": []
|
"tags": []
|
||||||
@@ -772,9 +772,37 @@
|
|||||||
" print(\" (Sử dụng nhiều spectral indices để cải thiện accuracy)\")\n",
|
" print(\" (Sử dụng nhiều spectral indices để cải thiện accuracy)\")\n",
|
||||||
" \n",
|
" \n",
|
||||||
" try:\n",
|
" try:\n",
|
||||||
|
" # ── FIX 1: Reproject training points to match raster CRS ──────────────\n",
|
||||||
|
" # Shapefile thường ở WGS84 (EPSG:4326, lon/lat ~105-106)\n",
|
||||||
|
" # Raster data ở UTM (EPSG:32648, easting ~500000+)\n",
|
||||||
|
" # Nếu không reproject → .sel() sẽ chọn sai pixel hoàn toàn!\n",
|
||||||
|
" raster_crs = None\n",
|
||||||
|
" try:\n",
|
||||||
|
" # Ưu tiên lấy CRS từ rioxarray\n",
|
||||||
|
" raster_crs = data.rio.crs\n",
|
||||||
|
" except Exception:\n",
|
||||||
|
" pass\n",
|
||||||
|
" if raster_crs is None:\n",
|
||||||
|
" # Fallback: dùng biến native_crs đã định nghĩa ở cell load data\n",
|
||||||
|
" raster_crs = native_crs if 'native_crs' in dir() else 'EPSG:32648'\n",
|
||||||
|
"\n",
|
||||||
|
" train_src_crs = train.crs if train.crs is not None else 'EPSG:4326'\n",
|
||||||
|
" print(f\" Training CRS : {train_src_crs}\")\n",
|
||||||
|
" print(f\" Raster CRS : {raster_crs}\")\n",
|
||||||
|
"\n",
|
||||||
|
" if str(train_src_crs).upper() != str(raster_crs).upper():\n",
|
||||||
|
" train_proj = train.to_crs(raster_crs)\n",
|
||||||
|
" print(f\" ✅ Reprojected training points → {raster_crs}\")\n",
|
||||||
|
" else:\n",
|
||||||
|
" train_proj = train\n",
|
||||||
|
" print(f\" ✅ CRS already match, no reprojection needed\")\n",
|
||||||
|
"\n",
|
||||||
" # Extract features at training point locations\n",
|
" # Extract features at training point locations\n",
|
||||||
" X = []\n",
|
" X = []\n",
|
||||||
" y = []\n",
|
" y = []\n",
|
||||||
|
" skipped_nan = 0\n",
|
||||||
|
" skipped_label = 0\n",
|
||||||
|
" skipped_other = 0\n",
|
||||||
"\n",
|
"\n",
|
||||||
" # Available features from data\n",
|
" # Available features from data\n",
|
||||||
" available_features = ['ndvi_mean', 'ndvi_min', 'ndvi_max', 'ndvi_std', 'ndvi_range',\n",
|
" available_features = ['ndvi_mean', 'ndvi_min', 'ndvi_max', 'ndvi_std', 'ndvi_range',\n",
|
||||||
@@ -790,33 +818,48 @@
|
|||||||
" else:\n",
|
" else:\n",
|
||||||
" print(f\" Using {len(features_to_use)} features: {features_to_use}\")\n",
|
" print(f\" Using {len(features_to_use)} features: {features_to_use}\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
" for idx, point in train.iterrows():\n",
|
" for idx, point in train_proj.iterrows():\n",
|
||||||
" try:\n",
|
" try:\n",
|
||||||
|
" # ── FIX 2: Dùng tọa độ đã reproject ──────────────────────\n",
|
||||||
|
" px, py = point.geometry.x, point.geometry.y\n",
|
||||||
|
"\n",
|
||||||
" # Extract all available features at this point\n",
|
" # Extract all available features at this point\n",
|
||||||
" feature_vec = []\n",
|
" feature_vec = []\n",
|
||||||
" for feat_name in features_to_use:\n",
|
" for feat_name in features_to_use:\n",
|
||||||
" feat_val = float(data[feat_name].sel(\n",
|
" feat_val = float(data[feat_name].sel(\n",
|
||||||
" x=point.geometry.x, \n",
|
" x=px, y=py, method='nearest'\n",
|
||||||
" y=point.geometry.y, \n",
|
|
||||||
" method='nearest'\n",
|
|
||||||
" ).values)\n",
|
" ).values)\n",
|
||||||
" feature_vec.append(feat_val)\n",
|
" feature_vec.append(feat_val)\n",
|
||||||
"\n",
|
"\n",
|
||||||
" # Get label\n",
|
" # Get label\n",
|
||||||
|
" try:\n",
|
||||||
" label = label_mapping[point.Hientrang]\n",
|
" label = label_mapping[point.Hientrang]\n",
|
||||||
|
" except KeyError:\n",
|
||||||
|
" skipped_label += 1\n",
|
||||||
|
" continue\n",
|
||||||
|
"\n",
|
||||||
|
" # ── FIX 3: np.isnan phải nhận numpy array, không phải list ─\n",
|
||||||
|
" feature_arr = np.array(feature_vec, dtype=np.float32)\n",
|
||||||
|
" if np.isnan(feature_arr).any():\n",
|
||||||
|
" skipped_nan += 1\n",
|
||||||
|
" continue\n",
|
||||||
"\n",
|
"\n",
|
||||||
" # Only add if no NaN values\n",
|
|
||||||
" if not np.isnan(feature_vec).any():\n",
|
|
||||||
" X.append(feature_vec)\n",
|
" X.append(feature_vec)\n",
|
||||||
" y.append(int(label))\n",
|
" y.append(int(label))\n",
|
||||||
|
"\n",
|
||||||
" except Exception as e:\n",
|
" except Exception as e:\n",
|
||||||
" # Skip points with errors\n",
|
" skipped_other += 1\n",
|
||||||
" continue\n",
|
" continue\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
" print(f\"\\n Points extracted : {len(X)}\")\n",
|
||||||
|
" print(f\" Skipped (NaN) : {skipped_nan}\")\n",
|
||||||
|
" print(f\" Skipped (label) : {skipped_label}\")\n",
|
||||||
|
" print(f\" Skipped (other) : {skipped_other}\")\n",
|
||||||
|
"\n",
|
||||||
" if len(X) > 0:\n",
|
" if len(X) > 0:\n",
|
||||||
" X = np.array(X)\n",
|
" X = np.array(X)\n",
|
||||||
" y = np.array(y)\n",
|
" y = np.array(y)\n",
|
||||||
" print(f\" ✅ Extracted {len(X)} samples with {X.shape[1]} features each\")\n",
|
" print(f\" ✅ {len(X)} samples × {X.shape[1]} features\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
" # Show feature statistics\n",
|
" # Show feature statistics\n",
|
||||||
" print(f\"\\n Feature statistics:\")\n",
|
" print(f\"\\n Feature statistics:\")\n",
|
||||||
@@ -844,7 +887,7 @@
|
|||||||
" from sklearn.metrics import accuracy_score, classification_report\n",
|
" from sklearn.metrics import accuracy_score, classification_report\n",
|
||||||
"\n",
|
"\n",
|
||||||
" model = RandomForestClassifier(\n",
|
" model = RandomForestClassifier(\n",
|
||||||
" n_estimators=200, # More trees for better accuracy\n",
|
" n_estimators=200,\n",
|
||||||
" max_depth=30,\n",
|
" max_depth=30,\n",
|
||||||
" min_samples_split=5,\n",
|
" min_samples_split=5,\n",
|
||||||
" random_state=42,\n",
|
" random_state=42,\n",
|
||||||
@@ -865,8 +908,8 @@
|
|||||||
" print(f\"\\n Feature importance:\")\n",
|
" print(f\"\\n Feature importance:\")\n",
|
||||||
" importances = model.feature_importances_\n",
|
" importances = model.feature_importances_\n",
|
||||||
" indices = np.argsort(importances)[::-1]\n",
|
" indices = np.argsort(importances)[::-1]\n",
|
||||||
" for i, idx in enumerate(indices):\n",
|
" for i, idx_fi in enumerate(indices):\n",
|
||||||
" print(f\" {i+1}. {features_to_use[idx]:15s}: {importances[idx]:.4f}\")\n",
|
" print(f\" {i+1}. {features_to_use[idx_fi]:15s}: {importances[idx_fi]:.4f}\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
" # Classification report\n",
|
" # Classification report\n",
|
||||||
" print(f\"\\n[4] Classification Report:\")\n",
|
" print(f\"\\n[4] Classification Report:\")\n",
|
||||||
@@ -874,7 +917,7 @@
|
|||||||
" print(classification_report(y_test, y_pred, target_names=class_names, zero_division=0))\n",
|
" print(classification_report(y_test, y_pred, target_names=class_names, zero_division=0))\n",
|
||||||
"\n",
|
"\n",
|
||||||
" else:\n",
|
" else:\n",
|
||||||
" print(f\" ❌ No samples extracted\")\n",
|
" print(f\" ❌ No valid samples extracted — kiểm tra CRS và tọa độ!\")\n",
|
||||||
" model = None\n",
|
" model = None\n",
|
||||||
"\n",
|
"\n",
|
||||||
" except Exception as e:\n",
|
" except Exception as e:\n",
|
||||||
@@ -890,7 +933,7 @@
|
|||||||
"print(\"📝 NOTE: Model này dự đoán PHÂN LOẠI SỬ DỤNG ĐẤT (8 lớp)\")\n",
|
"print(\"📝 NOTE: Model này dự đoán PHÂN LOẠI SỬ DỤNG ĐẤT (8 lớp)\")\n",
|
||||||
"print(\" NDVI là một trong các features đầu vào, không phải mục tiêu dự đoán\")\n",
|
"print(\" NDVI là một trong các features đầu vào, không phải mục tiêu dự đoán\")\n",
|
||||||
"print(\" Sau khi predict → có thể hiển thị NDVI map như chỉ số phụ\")\n",
|
"print(\" Sau khi predict → có thể hiển thị NDVI map như chỉ số phụ\")\n",
|
||||||
"print(\"=\"*70)"
|
"print(\"=\"*70)\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1094,14 +1137,6 @@
|
|||||||
"print(\"✅ PIPELINE COMPLETE\")\n",
|
"print(\"✅ PIPELINE COMPLETE\")\n",
|
||||||
"print(\"=\"*70)"
|
"print(\"=\"*70)"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"id": "ef65aa25-9032-4e1c-8808-64747e8005c6",
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": []
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
|
|||||||
Reference in New Issue
Block a user