最近在做随机森林回归实验时,遇到了一个问题:
在做回归时,用的是excel点数据做的回归,像这样:
但是如何把这个训练好的模型应用到整幅含有地理信息的遥感影像上去,并保存这个预测图像呢?对这个问题,展开了一些思考,废话不多说,直接上代码。
1 随机森林回归模型构建
导入数据,这里把Merge_Data替换成自己的数据;
import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score,mean_absolute_error
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
file_path = r"Merge_Data.xlsx"
data = pd.read_excel(file_path)
# Separating features and label
X = data.iloc[:, :-1] # Assuming the last column is the label
y = data.iloc[:, -1]
# Splitting the dataset into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Feature scaling
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
训练模型:
# 初始化模型
rf_model = RandomForestRegressor(n_estimators=100, random_state=42, n_jobs=-1)
# 训练模型
rf_model.fit(X_train_scaled, y_train)
# 预测
y_pred = rf_model.predict(X_test_scaled)
# 计算评估指标
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
mae = mean_absolute_error(y_test, y_pred)
results = {'Random Forest': {'MSE': mse, 'R2': r2, 'MAE': mae}}
# 绘图
plt.rcParams["font.family"] = "Times New Roman"
plt.figure(figsize=(5, 4.5))
plt.plot(range(0, 30), range(0, 30), color='black', alpha=0.7)
plt.scatter(y_test, y_pred, marker='.', s=1)
plt.title("Random Forest - Actual vs Predicted", fontsize=15)
plt.xlabel("Actual Values", fontsize=15)
plt.ylabel("Predicted Values", fontsize=15)
plt.tick_params(axis='both', which='major', labelsize=15)
filename = f"{file_path}Random_Forest_plot.png"
plt.tight_layout()
# plt.savefig(filename, dpi=600)
plt.show()
2 应用该模型到遥感影像上
这里首先利用rasterio打开图像;因为我这里是用了特定波段进行的预测,所以设置了一个selected_bands,其实是不需要这个的,全波段的话selected_bands设置为None;
之后创建一个空数组来存放预测结果,后利用rf_model来预测,最后重塑;
predicted_image就是预测结果,即完成了预测部分。文章来源:https://www.toymoban.com/news/detail-852970.html
import rasterio
# 打开影像
selected_bands = None
with rasterio.open(r"\img.tif") as src:
# 读取指定的波段
img = src.read(selected_bands)
# 将影像数据转换为二维数组(像素数 x 波段数)
reshaped_img = img.transpose(1, 2, 0).reshape(-1, img.shape[0]))
# 创建一个空数组来存放预测结果,初始化为NaN
predictions = np.full(reshaped_img.shape[0], np.nan)
# 归一化
reshaped_img = scaler.transform(reshaped_img)
# 找出没有NaN值的行索引
valid_data_mask = ~np.isnan(reshaped_img).any(axis=1)
valid_data = reshaped_img[valid_data_mask]
# 批量预测,对所有有效数据一次性进行
predictions[valid_data_mask] = rf_model.predict(valid_data)
# 重塑预测结果以匹配原始影像的形状
predicted_image = predictions.reshape(src.height, src.width)
3 为预测影像添加地理信息
首先设置一些基本的输入和输出路径,这里有地理信息的栅格就是原始的遥感影像,需要读取原始图像的地理信息并将其应用到预测影像上,注释比较清楚,不多解释了。文章来源地址https://www.toymoban.com/news/detail-852970.html
from rasterio.transform import from_origin
# 路径设置
source_raster = r"\img3_CASK.tif" # 有地理信息的栅格
target_data = predicted_image # 没有地理信息的栅格
output_raster = r'output.tif' # 输出文件路径
# 读取有地理信息的栅格数据
with rasterio.open(source_raster) as src:
transform = src.transform
crs = src.crs
data = src.read(1)
# 创建一个新的栅格文件,应用地理信息
with rasterio.open(
output_raster, 'w', driver='GTiff', height=target_data.shape[0],
width=target_data.shape[1], count=1, dtype=target_data.dtype,
crs=crs, transform=transform
) as dst:
dst.write(target_data, 1)
到了这里,关于利用Python对含有地理信息的遥感影像,使用随机森林模型回归,并保存预测影像的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!