基于Python的随机森林(RF)回归与变量重要性影响程度分析
本文详细介绍在Python中,实现随机森林(Random Forest,RF)回归与变量重要性分析、排序的代码编写与分析过程。其中,关于基于MATLAB实现同样过程的代码与实战,大家可以点击查看这篇博客1。
本文分为两部分,第一部分为代码的分段讲解,第二部分为完整代码。
1 代码分段讲解
1.1 模块与数据准备
首先,导入所需要的模块。在这里,需要pydot
与graphviz
这两个相对不太常用的模块,即使我用了Anaconda,也需要单独下载、安装。具体下载与安装,如果同样是在用Anaconda,大家就参考这篇博客即可。
import pydot
import numpy as np
import pandas as pd
import scipy.stats as stats
import matplotlib.pyplot as plt
from sklearn import metrics
from openpyxl import load_workbook
from sklearn.tree import export_graphviz
from sklearn.ensemble import RandomForestRegressor
接下来,我们将代码接下来需要用的主要变量加以定义。这一部分大家先不用过于在意,浏览一下继续向下看即可;待到对应的变量需要运用时我们自然会理解其具体含义。
train_data_path='G:/CropYield/03_DL/00_Data/AllDataAll_Train.csv'
test_data_path='G:/CropYield/03_DL/00_Data/AllDataAll_Test.csv'
write_excel_path='G:/CropYield/03_DL/05_NewML/ParameterResult_ML.xlsx'
tree_graph_dot_path='G:/CropYield/03_DL/05_NewML/tree.dot'
tree_graph_png_path='G:/CropYield/03_DL/05_NewML/tree.png'random_seed=44
random_forest_seed=np.random.randint(low=1,high=230)
接下来,我们需要导入输入数据。
在这里需要注意,本文对以下两个数据处理的流程并没有详细涉及与讲解(因为在写本文时,我已经做过了同一批数据的深度学习回归,本文就直接用了当时做深度学习时处理好的输入数据,因此以下两个数据处理的基本过程就没有再涉及啦),大家直接查看下方所列出的其它几篇博客即可。
初始数据划分训练集与测试集
类别变量的独热编码(One-hot Encoding)
针对上述两个数据处理过程,首先,数据训练集与测试集的划分在机器学习、深度学习中是不可或缺的作用,这一部分大家可以查看这篇博客2的2.4部分,或这篇博客3的2.3部分;其次,关于类别变量的独热编码,对于随机森林等传统机器学习方法而言可以说同样是非常重要的,这一部分大家可以查看这篇博客4。
在本文中,如前所述,我们直接将已经存在.csv
中,已经划分好训练集与测试集且已经对类别变量做好了独热编码之后的数据加以导入。在这里,我所导入的数据第一行是表头,即每一列的名称。关于.csv
数据导入的代码详解,大家可以查看这篇博客5的数据导入部分。
# Data import'''
column_name=['EVI0610','EVI0626','EVI0712','EVI0728','EVI0813','EVI0829','EVI0914','EVI0930','EVI1016','Lrad06','Lrad07','Lrad08','Lrad09','Lrad10','Prec06','Prec07','Prec08','Prec09','Prec10','Pres06','Pres07','Pres08','Pres09','Pres10','SIF161','SIF177','SIF193','SIF209','SIF225','SIF241','SIF257','SIF273','SIF289','Shum06','Shum07','Shum08','Shum09','Shum10','Srad06','Srad07','Srad08','Srad09','Srad10','Temp06','Temp07','Temp08','Temp09','Temp10','Wind06','Wind07','Wind08','Wind09','Wind10','Yield']
'''
train_data=pd.read_csv(train_data_path,header=0)
test_data=pd.read_csv(test_data_path,header=0)
1.2 特征与标签分离
特征与标签,换句话说其实就是自变量与因变量。我们要将训练集与测试集中对应的特征与标签分别分离开来。
# Separate independent and dependent variablestrain_Y=np.array(train_data['Yield'])
train_X=train_data.drop(['ID','Yield'],axis=1)
train_X_column_name=list(train_X.columns)
train_X=np.array(train_X)test_Y=np.array(test_data['Yield'])
test_X=test_data.drop(['ID','Yield'],axis=1)
test_X=np.array(test_X)
可以看到,直接借助drop
就可以将标签'Yield'
从原始的数据中剔除(同时还剔除了一个'ID'
,这个是初始数据的样本编号,后面就没什么用了,因此随着标签一起剔除)。同时在这里,还借助了train_X_column_name
这一变量,将每一个特征值列所对应的标题(也就是特征的名称)加以保存,供后续使用。
1.3 RF模型构建、训练与预测
接下来,我们就需要对随机森林模型加以建立,并训练模型,最后再利用测试集加以预测。在这里需要注意,关于随机森林的几个重要超参数(例如下方的n_estimators
)都是需要不断尝试找到最优的。关于这些超参数的寻优,在MATLAB中的实现方法大家可以查看这篇博客1的1.1部分;而在Python中的实现方法,大家查看这篇博客6即可。
# Build RF regression modelrandom_forest_model=RandomForestRegressor(n_estimators=200,random_state=random_forest_seed)
random_forest_model.fit(train_X,train_Y)# Predict test set datarandom_forest_predict=random_forest_model.predict(test_X)
random_forest_error=random_forest_predict-test_Y
其中,利用RandomForestRegressor
进行模型的构建,n_estimators
就是树的个数,random_state
是每一个树利用Bagging策略中的Bootstrap进行抽样(即有放回的袋外随机抽样)时,随机选取样本的随机数种子;fit
进行模型的训练,predict
进行模型的预测,最后一句就是计算预测的误差。
1.4 预测图像绘制、精度衡量指标计算与保存
首先,进行预测图像绘制,其中包括预测结果的拟合图与误差分布直方图。关于这一部分代码的解时,大家可以查看这篇博客2的2.9部分。
# Draw test plotplt.figure(1)
plt.clf()
ax=plt.axes(aspect='equal')
plt.scatter(test_Y,random_forest_predict)
plt.xlabel('True Values')
plt.ylabel('Predictions')
Lims=[0,10000]
plt.xlim(Lims)
plt.ylim(Lims)
plt.plot(Lims,Lims)
plt.grid(False)plt.figure(2)
plt.clf()
plt.hist(random_forest_error,bins=30)
plt.xlabel('Prediction Error')
plt.ylabel('Count')
plt.grid(False)
以上两幅图的绘图结果如下所示。
接下来,进行精度衡量指标的计算与保存。在这里,我们用皮尔逊相关系数、决定系数与RMSE作为精度的衡量指标,并将每一次模型运行的精度衡量指标结果保存在一个Excel文件中。这一部分大家同样查看这篇博客2的2.9部分即可。
# Verify the accuracyrandom_forest_pearson_r=stats.pearsonr(test_Y,random_forest_predict)
random_forest_R2=metrics.r2_score(test_Y,random_forest_predict)
random_forest_RMSE=metrics.mean_squared_error(test_Y,random_forest_predict)**0.5
print('Pearson correlation coefficient is {0}, and RMSE is {1}.'.format(random_forest_pearson_r[0],random_forest_RMSE))# Save key parametersexcel_file=load_workbook(write_excel_path)
excel_all_sheet=excel_file.sheetnames
excel_write_sheet=excel_file[excel_all_sheet[0]]
excel_write_sheet=excel_file.active
max_row=excel_write_sheet.max_row
excel_write_content=[random_forest_pearson_r[0],random_forest_R2,random_forest_RMSE,random_seed,random_forest_seed]
for i in range(len(excel_write_content)):exec("excel_write_sheet.cell(max_row+1,i+1).value=excel_write_content[i]")
excel_file.save(write_excel_path)
1.5 决策树可视化
这一部分我们借助DOT这一图像描述语言,进行随机森林算法中决策树的绘制。
# Draw decision tree visualizing plotrandom_forest_tree=random_forest_model.estimators_[5]
export_graphviz(random_forest_tree,out_file=tree_graph_dot_path,feature_names=train_X_column_name,rounded=True,precision=1)
(random_forest_graph,)=pydot.graph_from_dot_file(tree_graph_dot_path)
random_forest_graph.write_png(tree_graph_png_path)
其中,estimators_[5]
是指整个随机森林算法中的第6棵树(下标是从0
开始的),换句话说我们就是从很多的树(具体树的个数就是前面提到的超参数n_estimators
)中抽取了找一个来画图,做一个示范。如下图所示。
可以看到,单单是这一颗树就已经非常非常庞大了。我们将上图其中最顶端(也就是最上方的节点——根节点)部分放大,就可以看见每一个节点对应的信息。如下图
在这里提一句,上图根节点中有一个samples=151
,但是我的样本总数是315个,为什么这棵树的样本个数不是全部的样本个数呢?
其实这就是随机森林的内涵所在:随机森林的每一棵树的输入数据(也就是该棵树的根节点中的数据),都是随机选取的(也就是上面我们说的利用Bagging策略中的Bootstrap进行随机抽样),最后再将每一棵树的结果聚合起来(聚合这个过程就是Aggregation,我们常说的Bagging其实就是Bootstrap与Aggregation的合称),形成随机森林算法最终的结果。
1.6 变量重要性分析
在这里,我们进行变量重要性的分析,并以图的形式进行可视化。
# Calculate the importance of variablesrandom_forest_importance=list(random_forest_model.feature_importances_)
random_forest_feature_importance=[(feature,round(importance,8)) for feature, importance in zip(train_X_column_name,random_forest_importance)]
random_forest_feature_importance=sorted(random_forest_feature_importance,key=lambda x:x[1],reverse=True)
plt.figure(3)
plt.clf()
importance_plot_x_values=list(range(len(random_forest_importance)))
plt.bar(importance_plot_x_values,random_forest_importance,orientation='vertical')
plt.xticks(importance_plot_x_values,train_X_column_name,rotation='vertical')
plt.xlabel('Variable')
plt.ylabel('Importance')
plt.title('Variable Importances')
得到图像如下所示。这里是由于我的特征数量(自变量数量)过多,大概有150多个,导致横坐标的标签(也就是自变量的名称)都重叠了;大家一般的自变量个数都不会太多,就不会有问题~
以上就是全部的代码分段介绍~
2 完整代码
# -*- coding: utf-8 -*-
"""
Created on Sun Mar 21 22:05:37 2021@author: fkxxgis
"""import pydot
import numpy as np
import pandas as pd
import scipy.stats as stats
import matplotlib.pyplot as plt
from sklearn import metrics
from openpyxl import load_workbook
from sklearn.tree import export_graphviz
from sklearn.ensemble import RandomForestRegressor# Attention! Data Partition
# Attention! One-Hot Encodingtrain_data_path='G:/CropYield/03_DL/00_Data/AllDataAll_Train.csv'
test_data_path='G:/CropYield/03_DL/00_Data/AllDataAll_Test.csv'
write_excel_path='G:/CropYield/03_DL/05_NewML/ParameterResult_ML.xlsx'
tree_graph_dot_path='G:/CropYield/03_DL/05_NewML/tree.dot'
tree_graph_png_path='G:/CropYield/03_DL/05_NewML/tree.png'random_seed=44
random_forest_seed=np.random.randint(low=1,high=230)# Data import'''
column_name=['EVI0610','EVI0626','EVI0712','EVI0728','EVI0813','EVI0829','EVI0914','EVI0930','EVI1016','Lrad06','Lrad07','Lrad08','Lrad09','Lrad10','Prec06','Prec07','Prec08','Prec09','Prec10','Pres06','Pres07','Pres08','Pres09','Pres10','SIF161','SIF177','SIF193','SIF209','SIF225','SIF241','SIF257','SIF273','SIF289','Shum06','Shum07','Shum08','Shum09','Shum10','Srad06','Srad07','Srad08','Srad09','Srad10','Temp06','Temp07','Temp08','Temp09','Temp10','Wind06','Wind07','Wind08','Wind09','Wind10','Yield']
'''
train_data=pd.read_csv(train_data_path,header=0)
test_data=pd.read_csv(test_data_path,header=0)# Separate independent and dependent variablestrain_Y=np.array(train_data['Yield'])
train_X=train_data.drop(['ID','Yield'],axis=1)
train_X_column_name=list(train_X.columns)
train_X=np.array(train_X)test_Y=np.array(test_data['Yield'])
test_X=test_data.drop(['ID','Yield'],axis=1)
test_X=np.array(test_X)# Build RF regression modelrandom_forest_model=RandomForestRegressor(n_estimators=200,random_state=random_forest_seed)
random_forest_model.fit(train_X,train_Y)# Predict test set datarandom_forest_predict=random_forest_model.predict(test_X)
random_forest_error=random_forest_predict-test_Y# Draw test plotplt.figure(1)
plt.clf()
ax=plt.axes(aspect='equal')
plt.scatter(test_Y,random_forest_predict)
plt.xlabel('True Values')
plt.ylabel('Predictions')
Lims=[0,10000]
plt.xlim(Lims)
plt.ylim(Lims)
plt.plot(Lims,Lims)
plt.grid(False)plt.figure(2)
plt.clf()
plt.hist(random_forest_error,bins=30)
plt.xlabel('Prediction Error')
plt.ylabel('Count')
plt.grid(False)# Verify the accuracyrandom_forest_pearson_r=stats.pearsonr(test_Y,random_forest_predict)
random_forest_R2=metrics.r2_score(test_Y,random_forest_predict)
random_forest_RMSE=metrics.mean_squared_error(test_Y,random_forest_predict)**0.5
print('Pearson correlation coefficient is {0}, and RMSE is {1}.'.format(random_forest_pearson_r[0],random_forest_RMSE))# Save key parametersexcel_file=load_workbook(write_excel_path)
excel_all_sheet=excel_file.sheetnames
excel_write_sheet=excel_file[excel_all_sheet[0]]
excel_write_sheet=excel_file.active
max_row=excel_write_sheet.max_row
excel_write_content=[random_forest_pearson_r[0],random_forest_R2,random_forest_RMSE,random_seed,random_forest_seed]
for i in range(len(excel_write_content)):exec("excel_write_sheet.cell(max_row+1,i+1).value=excel_write_content[i]")
excel_file.save(write_excel_path)# Draw decision tree visualizing plotrandom_forest_tree=random_forest_model.estimators_[5]
export_graphviz(random_forest_tree,out_file=tree_graph_dot_path,feature_names=train_X_column_name,rounded=True,precision=1)
(random_forest_graph,)=pydot.graph_from_dot_file(tree_graph_dot_path)
random_forest_graph.write_png(tree_graph_png_path)# Calculate the importance of variablesrandom_forest_importance=list(random_forest_model.feature_importances_)
random_forest_feature_importance=[(feature,round(importance,8)) for feature, importance in zip(train_X_column_name,random_forest_importance)]
random_forest_feature_importance=sorted(random_forest_feature_importance,key=lambda x:x[1],reverse=True)
plt.figure(3)
plt.clf()
importance_plot_x_values=list(range(len(random_forest_importance)))
plt.bar(importance_plot_x_values,random_forest_importance,orientation='vertical')
plt.xticks(importance_plot_x_values,train_X_column_name,rotation='vertical')
plt.xlabel('Variable')
plt.ylabel('Importance')
plt.title('Variable Importances')
欢迎关注:疯狂学习GIS
基于Python的随机森林(RF)回归与变量重要性影响程度分析相关推荐
- 基于Python的随机森林(RF)回归与多种模型超参数自动优化方法
本文详细介绍基于Python的随机森林(Random Forest)回归算法代码与模型超参数(包括决策树个数与最大深度.最小分离样本数.最小叶子节点样本数.最大分离特征数等等)自动优化代码. ...
- 基于python的随机森林回归实现_python实现随机森林
定义: 随机森林指的是利用多棵决策树对样本进行训练并预测的一种分类器.可回归可分类. 所以随机森林是基于多颗决策树的一种集成学习算法,常见的决策树算法主要有以下几种: 1. ID3:使用信息增益g(D ...
- 基于python的随机森林回归实现_PYTHON | 随机森林实战(代码+详解)
大家好,我是菜鸟君,之前跟大家聊过R语言的随机森林建模,指路 R语言 | 随机森林建模实战(代码+详解),作为刚过完1024节日的码农算法工程师来说,怎么可能只会用一种语言呢?今天就来说说Python ...
- 基于python的随机森林回归实现_从零实现回归随机森林
一.前言 回归随机森林作为一种机器学习和数据分析领域常用且有效的算法,对其原理和代码实现过程的掌握是非常有必要的.为此,本文将着重介绍从零开始实现回归随机森林的过程,对于随机森林和决策树的相关理论原理 ...
- 基于python的随机森林回归实现_Python机器学习实践:随机森林算法训练及调参-附代码...
文章发布于公号[数智物语] (ID:decision_engine),关注公号不错过每一篇干货. 来源 | 博客园 作者 | 战争热诚 随机森林是一种有监督学习算法,是以决策树为基学习器的集成学习算法 ...
- 基于python的随机森林回归实现_随机森林理论与python代码实现
1,初品随机森林 随机森林,森林就是很多决策树放在一起一起叫森林,而随机体现在数据集的随机采样中和特征的随机选取中,具体下面再讲.通俗的说随机森林就是建立多颗决策树(CART),来做分类(回归),以多 ...
- 随机森林RF中的特征重要性的计算公式VIM
特征重要性评估 现实情况下,一个数据集中往往有成百上前个特征,如何在其中选择比结果影响最大的那几个特征,以此来缩减建立模型时的特征数是我们比较关心的问题.这样的方法其实很多,比如主成分分析,lasso ...
- python重要性_基于Python的随机森林特征重要性图
我正在使用python中的RandomForestRegressor,我想创建一个图表来说明特性重要性的排名.这是我使用的代码:from sklearn.ensemble import RandomF ...
- ML之mlxtend:基于iris鸢尾花数据集利用逻辑回归LoR/随机森林RF/支持向量机SVM/集成学习算法结合mlxtend库实现模型可解释性(决策边界可视化)
ML之mlxtend:基于iris鸢尾花数据集利用逻辑回归LoR/随机森林RF/支持向量机SVM/集成学习算法结合mlxtend库实现模型可解释性(决策边界可视化) 目录 相关文章 ML之mlxten ...
- python机器学习案例系列教程——集成学习(Bagging、Boosting、随机森林RF、AdaBoost、GBDT、xgboost)
全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 可以通过聚集多个分类器的预测结果提高分类器的分类准确率,这一方法称为集成(Ensemble)学习或分类器组合(Classifier C ...
最新文章
- [JS]手写动画最小时间间隔设置
- 【Java】计算当n=9时n!的值,并分别输出1!到9!各阶乘的值
- Linux—计划任务管理
- windows10环境下VMware14中Ubuntu16.04解决如何上网问题
- springboot 扫描jar包中bean_详解Spring Boot的Component Scan原理
- java infinity 处理_Java:如何执行向-Infinity而不是0的整数除法?
- step13. ubuntu18.04下载安装配置Hive(转)
- 【数学建模】CUMCM-2014B 创意平板折叠桌 解题思路整理
- 字符串(Linux应用编程篇)
- 【win10】配置系统未初始化
- 在android移动终端运行android应用程序
- coreldraw2022直装版下载 永久免费使用 附安装教程( 仅限 win 10 用户 )
- vba 读取图片尺寸
- 使用具有高性能事件流的数据库:关键注意事项
- 缺少配色灵感,整理超全超赞的配色工具帮你
- 模式识别算法之2--感知器(感知机)算法
- SQL入门之第二一讲——IF函数的使用
- scikit-learn:逻辑回归
- 利用CDN加速GithubPage访问速度
- 写给初入行,刚接触Auto CAD的新人一些建议——第一期
热门文章
- 新浪微博维护工具 推兔刷积分
- 纸鸢|物联设备PLC梯形图编程
- 计算机毕设人寿保险项目,2017年中国人寿集团在京各直属单位接收毕业生情况公示...
- 113.库存明细账案例(包含结存数)
- c语言怎么输入加减符号,C语言有符号加减溢出
- 001.Python安装及Pycharm安装破解
- 某商店规定,某商品一次购买5件以上(包含5件)打九折,一次购买10件以上(包含10件)打八折,请根据单价和数量球总价
- 2020西工大计算机考研经验贴
- 温度反转效应(文末附2018数字IC后端最新校招笔试题目)
- CAT分布式监控系统(一):CAT功能介绍 CAT监控系统是什么、能做什么?