Программирование

Расчет R² для анализа угодий спутниковыми данными и ML

Руководство по расчету коэффициента детерминации R² в машинном обучении для анализа сельскохозяйственных угодий. Используйте XGBoost, rasterio, numpy, pandas с Python для спутниковых данных и оценки урожайности.

Как рассчитать значения R² для анализа сельскохозяйственных угодий с использованием спутниковых данных и машинного обучения?

Я работаю над проектом машинного обучения в ГИС, посвященным анализу сельскохозяйственных угодий с использованием спутниковых данных. У меня возникают трудности с расчетом значений R² для моего анализа ферм.

Используемый технический стек:

  • rasterio
  • xgboost
  • numpy
  • pandas

Не могли бы вы предоставить руководство по правильному подходу к расчету значений R² при работе со спутниковыми изображениями и данными о фермах с использованием этих библиотек?

Расчет коэффициента детерминации R² (r2 score) для анализа сельскохозяйственных угодий с спутниковыми данными и машинным обучением сводится к использованию sklearn.metrics.r2_score после предсказаний модели XGBoost. Вы загружаете растровые данные ферм через rasterio, обрабатываете их с numpy и pandas, обучаете регрессионную модель на признаках вроде NDVI или высот, а затем сравниваете истинные значения урожайности с предсказанными. Это покажет, насколько модель объясняет вариацию данных — идеально для оценки качества в агроанализе спутниковых снимков.


Содержание


Что такое коэффициент детерминации R² и зачем он нужен в анализе угодий

Представьте: у вас тонны спутниковых снимков полей, индексы растительности NDVI, данные по почве — и модель, которая пытается предсказать урожайность. Но работает ли она? Вот тут и вступает коэффициент детерминации R² (или просто r2 в машинном обучении). Это метрика, которая показывает долю дисперсии целевой переменной (скажем, тонны с гектара), объясненную моделью. Диапазон от 0 до 1: 1 — идеальное совпадение, 0 — модель не лучше среднего значения. А отрицательные значения? Они говорят, что среднее предсказывает лучше вашей модели. Больно, но честно.

В контексте машинного обучения в сельском хозяйстве R² критичен. Спутниковые данные шумные — облака, сезоны, разные сенсоры. Если R² около 0.8, как в примерах с XGBoost, модель объясняет 80% вариации. По данным Habr, для линейной регрессии R² = r² коэффициента корреляции, но в нелинейных моделях вроде градиентного бустинга это универсальный индикатор. Почему именно для агро? Потому что фермеры хотят знать: предскажет ли модель засуху или переувлажнение по снимкам Landsat/Sentinel?

А теперь вопрос: вы уверены, что ваша модель не переобучается? R² на тесте ниже, чем на трейне? Это сигнал к действию.


Подготовка спутниковых данных с rasterio, numpy и pandas

Спутниковые снимки — это растры, многополосные массивы. Без правильной подготовки XGBoost просто сломается на NaN или несоответствиях форм. Начните с rasterio: оно читает GeoTIFF с метаданными.

Вот базовый пайплайн. Допустим, у вас файл farm_satellite.tif с бандами B4 (красный), B8 (NIR) для NDVI, плюс маска угодий и CSV с реальными урожаями.

python
import rasterio
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split

# Загрузка растра
with rasterio.open('farm_satellite.tif') as src:
 red = src.read(1) # B4
 nir = src.read(4) # B8 NIR
 height, width = red.shape

# Расчет NDVI: (NIR - Red) / (NIR + Red)
ndvi = (nir.astype(float) - red.astype(float)) / (nir + red + 1e-10) # Избегаем деления на 0

# Маска валидных пикселей (не NaN, не облака)
mask = ~np.isnan(ndvi) & (ndvi > -1) & (ndvi < 1)

# Флэттеним в фичи
X_sat = np.column_stack([ndvi[mask], red[mask], nir[mask]]) # Добавьте больше банд

# Цели: урожайность по ферме (из shapefile или CSV, агрегировано по пикселям)
df_yields = pd.read_csv('farm_yields.csv') # Колонка 'yield_t_ha'
y = df_yields['yield_t_ha'].values # Соответствует маске

# Pandas для финальной сборки
df = pd.DataFrame(X_sat, columns=['NDVI', 'Red', 'NIR'])
df['yield'] = np.repeat(y, np.sum(mask)) # Если агрегировано

print(df.head())

Этот подход из Medium-руководства по LULC адаптирован для регрессии. numpy ускоряет маскировку, pandas — обработку меток ферм. Разделите на train/test: X_train, X_test, y_train, y_test = train_test_split(df.drop('yield', axis=1), df['yield'], test_size=0.2).

Проблемы? Облака маскируйте по QA-банду Sentinel. И нормализуйте: from sklearn.preprocessing import StandardScaler.


Обучение модели XGBoost для регрессии на данных ферм

XGBoost — король градиентного бустинга для табличных данных, включая анализ спутниковых снимков. Он справляется с нелинейностями: NDVI нелинейно влияет на урожай.

Установка: pip install xgboost scikit-learn.

Код обучения:

python
import xgboost as xgb
from sklearn.metrics import r2_score # Уже импортируем!

model = xgb.XGBRegressor(
 n_estimators=100,
 learning_rate=0.1,
 max_depth=6,
 random_state=42
)

model.fit(X_train, y_train)

# Предсказания
y_pred_train = model.predict(X_train)
y_pred_test = model.predict(X_test)

Параметры тюньте через GridSearchCV. По Educative, это дает R² ~0.83 на регрессии. Для агро добавьте фичи: высоту из SRTM, как в MDPI-статье.

Модель готова? Переходим к метрике.


Расчет R²: шаг за шагом с кодом

Сердце вашего анализа — r2_score. Импортируйте из sklearn.metrics.

python
from sklearn.metrics import r2_score

# R² на трейне и тесте
r2_train = r2_score(y_train, y_pred_train)
r2_test = r2_score(y_test, y_pred_test)

print(f"R² train: {r2_train:.3f}")
print(f"R² test: {r2_test:.3f}")

Что происходит под капотом? Формула: $$ R^2 = 1 - \frac{\sum (y_i - \hat{y_i})^2}{\sum (y_i - \bar{y})^2} $$. По Machine Learning Wiki, это доля объясненной дисперсии.

Полный пайплайн в функции:

python
def evaluate_r2(model, X_test, y_test):
 preds = model.predict(X_test)
 return r2_score(y_test, preds)

r2_final = evaluate_r2(model, X_test, y_test)

Из Stack Overflow — это стандарт для любой регрессии. Для XGBoost есть model.score(X_test, y_test), но r2_score универсальнее.

Визуализация? import matplotlib.pyplot as plt; plt.scatter(y_test, y_pred_test); plt.xlabel('True'); plt.ylabel('Pred');


Интерпретация R² и улучшение модели

R²=0.7? Неплохо для спутниковых данных — погода непредсказуема. Но 0.3? Модель бесполезна. Скорректированный R² учитывает число фич: $$ \bar{R^2} = 1 - (1 - R^2) \frac{n-1}{n-p-1} $$, где p — фич.

Улучшения:

  • Добавьте лаговые фичи: NDVI за прошлые сезоны.
  • Кросс-валидация: from sklearn.model_selection import cross_val_score; scores = cross_val_score(model, X, y, cv=5, scoring='r2').
  • Feature importance: xgb.plot_importance(model).
  • Обработка выбросов в pandas: df = df[df['NDVI'] < 3 * df['NDVI'].std()].

Из Datafinder: высокий R² — признак хорошей модели, но проверяйте на переобучение. Для ферм цельтесь на 0.75+.

Экспериментировали с ensemble? Смешайте XGBoost с RandomForest.


Источники

  1. Stack Overflow: R² как метрика оценки
  2. Medium: Классификация земель с Python
  3. Educative: Регрессия с XGBoost
  4. MDPI: Обработка спутниковых изображений
  5. Habr: Корреляция и регрессия
  6. Machine Learning Wiki: Коэффициент детерминации
  7. Datafinder: Оценка R² в ML

Заключение

Расчет R² через sklearn.metrics.r2_score после XGBoost — простой и мощный способ оценить модель для анализа сельскохозяйственных угодий по спутниковым данным. С rasterio вы загружаете снимки, numpy/pandas чистите, модель обучаете — и получаете метрику, которая реально говорит о качестве предсказаний урожая. Стремитесь к R² >0.7, тюньте фичи вроде NDVI, и ваш агро-ГИС-проект взлетит. Попробуйте на своих данных — результаты удивят!

Авторы
Проверено модерацией
Модерация