摘要
随机森林回归算法的应用领域很广,可用于市场销售预测、客户细分、商品推荐等领域,也可应用于气候模型预测、土地利用分析、水资源管理等环境领域问题。其算法的Python实现涉及到多参数调优问题,本文使用了网格搜索法,以MSE作为评价指标,选取最佳MSE的参数组合构建随机森林回归模型。基于该模型,建立了空气污染(air_pollution)与露点温度(Dew Point Temperature)、温度(Temperature)、气压(Pressure)、风速(Wind Speed)、降雪量(Snowfall)和降雨量(Rainfall)的随机森林回归模型。
0 引言
随机森林回归模型广泛应用于数据分析、数据挖掘和统计学等领域中,在建立模型前,需要读者提前准备相关训练和测试数据,并完成对数据集的数据清洗和预处理等工作。
1 材料准备
Python编译器:PyCharm社区版或个人版等
数据集:本文所使用的数据集样例如图1.1所示,如有需要,请私发笔者电子邮箱,获取元数据。
图1.1 数据集准备
2 网格搜索法
网格搜索法(Grid Search)是一种用于确定机器学习模型参数的方法。它通过穷举搜索给定参数空间中的所有可能组合,然后根据某种评价指标选择最佳参数组合。主要分为以下三个步骤:
1、参数空间网格化:将超参数的取值范围离散化成一个个节点,构建成一个网格参数空间。设超参数为,取值范围为,则参数空间网格化后为:
2、创建参数组合:生成参数空间中的所有可能组合,在网格搜索中通常使用笛卡尔积来创建参数组合。
3、穷举搜索:遍历网格中的每个节点,将每个超参数组合代入模型,使用交叉验证等方法评估模型在验证集上的性能。
4、选择最佳参数:选择验证集上性能最佳的那组超参数组合作为最终的最佳超参数。
3 随机森林回归模型
随机森林回归算法是一种基于决策树的集成学习方法。它通过构建多个决策树,并将它们的预测结果进行平均,从而提高模型的准确性和稳定性,其算法原理示意图如图3.1所示。
图3.1 随机森林回归算法原理示意图
3.1 随机森林回归模型训练
随机森林回归由多个决策树组成,每个决策树都是一个回归器,且每个决策树都是由随机选取的样本和特征进行训练得到的。可划分为以下三个步骤:
1、从训练集中有放回地随机抽取样本,构建一个新的训练集,样本数量与原始训练集相同,但可能有重复样本。对于新的训练集D',有:
式中:是抽样得到的样本特征,是对应的样本标签。
2、 从所有特征中随机选择一部分特征,构建决策树时只使用这部分特征进行划分。对于特征子集F'的选择,有:
式中:是从所有特征中随机选择得到的特征。
3、通过使用特征子集F'和训练集D'构建一个决策树回归器T。
3.2 随机森林回归模型预测
对于随机森林回归模型的预测,则是使用随机森林中的所有决策树对新样本进行预测,对于每棵决策树,将新样本从根节点开始根据特征进行划分,直到到达叶节点,然后将叶节点中训练样本的平均值作为预测值。而对于当前随机森林回归模型,则是将所有决策树的预测结果进行平均,得到最终的预测结果。
3.3 随机森林回归模型性能评估
模型评估上,随机森林回归的常用指标包括均方误差(MSE)和R-squared(R2),一般来说,MSE的值越小,说明模型对数据的拟合程度越好,R2的值越接近于1,说明模型对数据的拟合程度越好,反之亦然。其计算公式如下:
式中,表示样本数量, 表示第 个样本的真实值, 表示第 个样本的预测值。
式中: 表示所有样本真实值的平均值。
4 基于网格搜索的随机森林回归算法的Python实现
4.1 数据加载
在此处,使用pandas的read_csv函数加载训练和测试数据,并将自变量和目标变量分开。使用train_test_split函数将数据集划分为70%的训练集和30%的测试集。
import pandas as pd
from sklearn.model_selection import train_test_split
df = pd.read_csv('air_pollution.csv')
# 划分自变量和目标变量
X = df.iloc[:, 2:]
y = df.iloc[:, 1]
# 将数据集拆分为70%训练样本数据,30%为测试样本数据
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.7,test_size=0.3, random_state=42)
4.2 设置随机森林回归模型的参数
基于Python的官方文档,对随机森林回归模型的参数n_estimators、max_depth、min_samples_split、min_samples_leaf和max_features进行区间设置。
# 设置随机森林回归模型的参数
param_grid = {
'n_estimators': [10, 50, 100, 200, 400],
'max_depth': [None, 10, 20, 30, 50],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4],
'max_features': ['log2', 'sqrt']
}
4.3 网格搜索法的实现
基于所设置的参数集合,使用网格搜索法GridSearchCV,基于五折交叉验证,使用负均方误差(neg_mean_squared_error)作为评估指标进行最佳参数组合的选择。
在网格搜索GridSearchCV方法中,其各属性的含义如下:
estimator
:指定机器学习模型,这里是使用随机森林回归模型,即rf
变量。param_grid
:指定超参数搜索空间,这里是一个字典类型,包含了随机森林回归模型的超参数和它们的取值范围。cv
:指定交叉验证的折数,这里是5。scoring
:指定评估指标,这里是使用均方误差的负值作为评估指标,即neg_mean_squared_error
。这是因为GridSearchCV
函数默认会选择评估指标的最大值,而我们想要选择均方误差最小的模型,因此需要将评估指标设为负均方误差。verbose
:指定输出的详细程度,这里是2,表示输出每个参数组合的详细信息。n_jobs
:指定并行运行的作业数,这里是-1,表示使用所有可用的CPU核心。
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import GridSearchCV
# 网格搜索法确定最佳参数
rf = RandomForestRegressor(random_state=42)
grid_search = GridSearchCV(estimator=rf, param_grid=param_grid, cv=5, scoring='neg_mean_squared_error', verbose=2, n_jobs=-1)
grid_search.fit(X_train, y_train)
# 输出最佳参数
print(grid_search.best_params_)
4.4 网格搜索过程可视化
from matplotlib import pyplot as plt
# 可视化处理
results = pd.DataFrame(grid_search.cv_results_)
print(results)
mse = abs(results['mean_test_score'])
plt.figure(figsize=(10, 8))
plt.title("Random Forest Grid Search MSEs", fontsize=16)
plt.xlabel("Parameter Set", fontsize=16)
plt.ylabel("MSE Score", fontsize=16)
plt.plot(range(1, len(mse) + 1), mse, color='#d7191c', linestyle='--', label='MSE')
plt.grid(False)
plt.legend(loc='best', fontsize=14)
plt.show()
plt.clf()
上述代码通过绘制折线图,展示了随机森林模型在网格搜索过程中不同参数组合的MSE得分,如图4.1所示。
图4.1 网格搜索过程可视化
4.5 基于最佳参数组合建立预测模型
基于网格搜索法所得到的最佳参数组合best_estimator_建立随机森林回归模型,使用测试集进行模型性能评估,输出评估指标MSE和R^2的数据。
from sklearn.metrics import mean_squared_error, r2_score
# 输出最佳模型的MSE和R^2
best_rf = grid_search.best_estimator_
predictions = best_rf.predict(X_test)
best_mse = mean_squared_error(y_test, predictions)
best_r2 = r2_score(y_test, predictions)
print('MSE of the best model: ', best_mse)
print('R^2 of the best model: ', best_r2)
4.6 特征重要性进行可视化
Python的随机森林回归模型特征重要性的计算是基于Gini指数的方法,在sklearn.ensemble
模块中的RandomForestRegressor
类中,特征重要性是通过计算每个特征在随机森林中的平均不纯度减少(impurity decrease)来确定的。
# 设置马克龙色调
colors = [ '#FCE38A', '#EAFFD0', '#95E1D3', '#F38181', '#dfc27d', '#fbb4b9','#7fcdbb','#377eb8','#abdda4']
# 可视化特征重要性
feature_importances = best_rf.feature_importances_
print(feature_importances)
feature_names = X.columns
sorted_idx = feature_importances.argsort()
plt.figure(figsize=(10, 8))
plt.barh(range(len(sorted_idx)), feature_importances[sorted_idx], color=colors)
plt.yticks(range(len(sorted_idx)), feature_names[sorted_idx], fontsize=12)
plt.xlabel("Feature Importance", fontsize=16)
plt.title("Random Forest Feature Importance", fontsize=16)
# 添加数值标签
for i, v in enumerate(feature_importances[sorted_idx]):
plt.text(v + 0.001, i, f"{v:.3f}", fontsize=12)
plt.tight_layout()
plt.show()
为了使色调更好看一点,本文使用了马克龙色调进行润色,如图4.2所示。
图4.2 特征重要性结果
4.7 完整实现代码
import pandas as pd
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.metrics import mean_squared_error, r2_score
from matplotlib import pyplot as plt
# 读取数据
# df = pd.read_excel('附件0.2.xlsx')
df = pd.read_csv('air_pollution.csv')
# 划分自变量和目标变量
X = df.iloc[:, 2:]
y = df.iloc[:, 1]
# 将数据集拆分为70%训练样本数据,30%为测试样本数据
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.7,test_size=0.3, random_state=42)
# 设置随机森林回归模型的参数
param_grid = {
'n_estimators': [10, 50, 100, 200, 400],
'max_depth': [None, 10, 20, 30, 50],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4],
'max_features': ['log2', 'sqrt']
}
# 网格搜索法确定最佳参数
rf = RandomForestRegressor(random_state=42)
grid_search = GridSearchCV(estimator=rf, param_grid=param_grid, cv=5, scoring='neg_mean_squared_error', verbose=2, n_jobs=-1)
grid_search.fit(X_train, y_train)
# 输出最佳参数
print(grid_search.best_params_)
# 可视化处理
results = pd.DataFrame(grid_search.cv_results_)
print(results)
mse = abs(results['mean_test_score'])
plt.figure(figsize=(10, 8))
plt.title("Random Forest Grid Search MSEs", fontsize=16)
plt.xlabel("Parameter Set", fontsize=16)
plt.ylabel("MSE Score", fontsize=16)
plt.plot(range(1, len(mse) + 1), mse, color='#d7191c', linestyle='--', label='MSE')
plt.grid(False)
plt.legend(loc='best', fontsize=14)
plt.show()
plt.clf()
# 输出最佳模型的MSE和R^2
best_rf = grid_search.best_estimator_
predictions = best_rf.predict(X_test)
best_mse = mean_squared_error(y_test, predictions)
best_r2 = r2_score(y_test, predictions)
print('MSE of the best model: ', best_mse)
print('R^2 of the best model: ', best_r2)
# 设置马克龙色调
colors = [ '#FCE38A', '#EAFFD0', '#95E1D3', '#F38181', '#dfc27d', '#fbb4b9','#7fcdbb','#377eb8','#abdda4']
# 可视化特征重要性
feature_importances = best_rf.feature_importances_
print(feature_importances)
feature_names = X.columns
sorted_idx = feature_importances.argsort()
plt.figure(figsize=(10, 8))
plt.barh(range(len(sorted_idx)), feature_importances[sorted_idx], color=colors)
plt.yticks(range(len(sorted_idx)), feature_names[sorted_idx], fontsize=12)
plt.xlabel("Feature Importance", fontsize=16)
plt.title("Random Forest Feature Importance", fontsize=16)
# 添加数值标签
for i, v in enumerate(feature_importances[sorted_idx]):
plt.text(v + 0.001, i, f"{v:.3f}", fontsize=12)
plt.tight_layout()
plt.show()
5 结论
本文将空气污染数据划分为70%的训练集和30%的训练集,基于70%训练集使用了网格搜索法确定随机森林回归模型的最优参数组合,并建立起随机森林回归预测模型,通过30%的测试集对该模型进行测试,使用MSE和R^2作为评估指标对模型性能进行评价。
6 备注
本文为原创文章,禁止私自转载,违者必究。如需原始数据,请点赞+收藏,然后私聊笔者或在评论区留下你的邮箱,即可获取原始数据一份。