本文已参与「新人创作礼」活动,一同敞开创作之路。

  本文介绍在Python环境中,完成随机森林(Random Forest,RF)回归与各自变量重要性分析与排序的进程。

  其间,关于根据MATLAB完成相同进程的代码与实战,咱们能够点击检查MATLAB完成随机森林回归猜测并对变量的影响程度进行排序。

  本文分为两部分,第一部分为代码的分段讲解,第二部分为完整代码。

1 代码分段讲解

1.1 模块与数据预备

  首要,导入所需求的模块。在这里,需求pydotgraphviz这两个相对不太常用的模块,即使我用了Anaconda,也需求单独下载、装置。详细下载与装置,假如相同是在用Anaconda,咱们参考Anaconda环境装备Python的pydot与graphviz模块即可。

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)

  针对上述两个数据处理进程,首要,数据练习集与测验集的区分在机器学习、深度学习中是不可或缺的效果,这一部分咱们能够检查Python中TensorFlow完成根据DNNRegressor的深度学习回归的2.4部分,或Python中TensorFlow根据keras.Sequential完成深度神经网络回归的2.3部分;其次,关于类别变量的独热编码,关于随机森林等传统机器学习办法而言能够说相同是十分重要的,这一部分咱们能够检查Python完成类别变量独热编码One-hot Encoding的办法。

  在本文中,如前所述,咱们直接将现已存在.csv中,现已区分好练习集与测验集且现已对类别变量做好了独热编码之后的数据加以导入。在这里,我所导入的数据第一行是表头,即每一列的称号。关于.csv数据导入的代码详解,咱们能够检查根据Python的seaborn制作多变量联合分布图pairplot的数据导入部分。

# 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 variables
train_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中的完成办法咱们能够检查MATLAB完成随机森林回归猜测并对变量的影响程度进行排序的1.1部分;而在Python中的完成办法,咱们检查咱们后期的文章即可。

# Build RF regression model
random_forest_model=RandomForestRegressor(n_estimators=200,random_state=random_forest_seed)
random_forest_model.fit(train_X,train_Y)
# Predict test set data
random_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 猜测图像制作、精度衡量目标核算与保存

  首要,进行猜测图像制作,其间包含猜测成果的拟合图与误差分布直方图。关于这一部分代码的解说,咱们能够检查Python中TensorFlow完成根据DNNRegressor的深度学习回归的2.9部分。

# Draw test plot
plt.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)

  以上两幅图的绘图成果如下所示。

Python实现随机森林RF回归、自变量重要性排序

Python实现随机森林RF回归、自变量重要性排序

  接下来,进行精度衡量目标的核算与保存。在这里,咱们用皮尔逊相关系数决定系数RMSE作为精度的衡量目标,并将每一次模型运转的精度衡量目标成果保存在一个Excel文件中。这一部分咱们相同检查Python中TensorFlow完成根据DNNRegressor的深度学习回归的2.9部分即可。

# Verify the accuracy
random_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 parameters
excel_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 plot
random_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)中抽取了找一个来画图,做一个示范。如下图所示。

Python实现随机森林RF回归、自变量重要性排序

  能够看到,单单是这一棵树就现已十分十分巨大了。咱们将上图其间最顶端(也便是最上方的节点——根节点)部分放大,就能够看见每一个节点对应的信息。如下图

Python实现随机森林RF回归、自变量重要性排序

  在这里提一句,上图根节点中有一个samples=151,可是我的样本总数是315个,为什么这棵树的样本个数不是悉数的样本个数呢?

  其实这便是随机森林的内涵地点:随机森林的每一棵树的输入数据(也便是该棵树的根节点中的数据),都是随机选取的(也便是上面咱们说的使用Bagging战略中的Bootstrap进行随机抽样),终究再将每一棵树的成果聚合起来(聚合这个进程便是Aggregation,咱们常说的Bagging其实便是BootstrapAggregation的合称),形成随机森林算法终究的成果。

1.6 变量重要性分析

  在这里,咱们进行变量重要性的分析,并以图的方式进行可视化。

# Calculate the importance of variables
random_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多个,导致横坐标的标签(也便是自变量的称号)都重叠了;咱们一般的自变量个数都不会太多,就不会有问题~

Python实现随机森林RF回归、自变量重要性排序

  以上便是悉数的代码分段介绍~

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 Encoding
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)
# 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 variables
train_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 model
random_forest_model=RandomForestRegressor(n_estimators=200,random_state=random_forest_seed)
random_forest_model.fit(train_X,train_Y)
# Predict test set data
random_forest_predict=random_forest_model.predict(test_X)
random_forest_error=random_forest_predict-test_Y
# Draw test plot
plt.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 accuracy
random_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 parameters
excel_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 plot
random_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 variables
random_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')