Расчет 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² и зачем он нужен в анализе угодий
- Подготовка спутниковых данных с rasterio, numpy и pandas
- Обучение модели XGBoost для регрессии на данных ферм
- Расчет R²: шаг за шагом с кодом
- Интерпретация R² и улучшение модели
- Источники
- Заключение
Что такое коэффициент детерминации 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 с реальными урожаями.
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.
Код обучения:
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.
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, это доля объясненной дисперсии.
Полный пайплайн в функции:
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.
Источники
- Stack Overflow: R² как метрика оценки
- Medium: Классификация земель с Python
- Educative: Регрессия с XGBoost
- MDPI: Обработка спутниковых изображений
- Habr: Корреляция и регрессия
- Machine Learning Wiki: Коэффициент детерминации
- Datafinder: Оценка R² в ML
Заключение
Расчет R² через sklearn.metrics.r2_score после XGBoost — простой и мощный способ оценить модель для анализа сельскохозяйственных угодий по спутниковым данным. С rasterio вы загружаете снимки, numpy/pandas чистите, модель обучаете — и получаете метрику, которая реально говорит о качестве предсказаний урожая. Стремитесь к R² >0.7, тюньте фичи вроде NDVI, и ваш агро-ГИС-проект взлетит. Попробуйте на своих данных — результаты удивят!