如何调参
对于随机森林如何调参,这里给出一些好的建议,如果你是网格搜索,而且是那种毫无规则的网格搜索,那么模型跑个三天三夜也未必有结果,此外,你的机器可能没有这么好的配置,根本跑不动!
在下图中,我们可以看到这些参数对Random Forest整体模型性能的影响:
① 基于泛化误差与模型复杂度的关系来进行调参;
② 根据对模型的影响程度,由大到小对参数排序,并确定哪些参数会使模型复杂度减小,哪些会增大;
③ 依次选择合适的参数,通过绘制学习曲线或网格搜索的方法调参,直到找到最大准确得分。
讲了做这么多的干货,下面上点实际的,代码整起
代码实现
案例代码
导入第三方库
#导入所需要的包 from sklearn.metrics import precision_score from sklearn.model_selection import train_test_split from sklearn.svm import SVC from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier import numpy as np import pandas as pd import matplotlib.pyplot as plt from matplotlib.colors import ListedColormap from sklearn.preprocessing import LabelEncoder from sklearn.metrics import classification_report#评估报告 from sklearn.model_selection import cross_val_score #交叉验证 from sklearn.model_selection import GridSearchCV #网格搜索 import matplotlib.pyplot as plt#可视化 import seaborn as sns#绘图包 from sklearn.preprocessing import StandardScaler,MinMaxScaler,MaxAbsScaler#归一化,标准化 # 忽略警告 import warnings warnings.filterwarnings("ignore")
计算皮尔逊系数,并绘制热力相关图
1. X_valus=df.corr()[["n23"]].sort_values(by="n23",ascending=False).iloc[1:] 2. X_valus
figure, ax = plt.subplots(figsize=(20, 20)) sns.heatmap(df.corr(), square=True, annot=True, ax=ax) plt.show()
不加入任何的参数,直接原生态的随机森林,效果还是不错的
model=RandomForestClassifier() # 训练模型 model.fit(X_train,y_train) # 预测值 y_pred = model.predict(X_test) ''' 评估指标 ''' # 求出预测和真实一样的数目 true = np.sum(y_pred == y_test ) print('预测对的结果数目为:', true) print('预测错的的结果数目为:', y_test.shape[0]-true) # 评估指标 from sklearn.metrics import accuracy_score,precision_score,recall_score,f1_score,cohen_kappa_score print('预测数据的准确率为: {:.4}%'.format(accuracy_score(y_test,y_pred)*100)) print('预测数据的精确率为:{:.4}%'.format( precision_score(y_test,y_pred)*100)) print('预测数据的召回率为:{:.4}%'.format( recall_score(y_test,y_pred)*100)) # print("训练数据的F1值为:", f1score_train) print('预测数据的F1值为:', f1_score(y_test,y_pred)) print('预测数据的Cohen’s Kappa系数为:', cohen_kappa_score(y_test,y_pred)) # 打印分类报告 print('预测数据的分类报告为:','\n', classification_report(y_test,y_pred))
n_estimators调参(学习曲线)
scorel = [] for i in range(0,200,10): model = RandomForestClassifier(n_estimators=i+1, n_jobs=-1, random_state=90).fit(X_train,y_train) score = model.score(X_test,y_test) scorel.append(score) print(max(scorel),(scorel.index(max(scorel))*10)+1) #作图反映出准确度随着估计器数量的变化,51的附近最好 plt.figure(figsize=[20,5]) plt.plot(range(1,201,10),scorel) plt.show()
确定了大致的范围,那么我们就可以在这个基础上缩小范围,迭代看看
## 根据上面的显示最优点在51附近,进一步细化学习曲线 scorel = [] for i in range(40,60): RFC = RandomForestClassifier(n_estimators=i, n_jobs=-1, random_state=90).fit(X_train,y_train) score = RFC.score(X_test,y_test) scorel.append(score) print(max(scorel),([*range(40,60)][scorel.index(max(scorel))])) #112是最优的估计器数量 #最优得分是0.98945 plt.figure(figsize=[20,5]) plt.plot(range(40,60),scorel) plt.show()
虽然给出的最佳是45,但是我依然会选择51,因为在接近某一个数字,它就是平稳的,效果肯定要好,并且模型的扰动性较好
优化max_depth
## 优化max_depth scorel = [] for i in range(3,30): RFC = RandomForestClassifier(max_depth=i,n_estimators=51, n_jobs=-1, random_state=90).fit(X_train,y_train) score = RFC.score(X_test,y_test) scorel.append(score) print(max(scorel),([*range(3,30)][scorel.index(max(scorel))])) #112是最优的估计器数量 #最优得分是0.951462 plt.figure(figsize=[20,5]) plt.plot(range(3,30),scorel) plt.show()
决策树最大深度max_depth: 默认可以不输入,如果不输入的话,决策树在建立子树的时候不会限制子树的深度。一般来说,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。常用的可以取值10-100之间。
本数据集特征也不是很多,其实是不需要对这个参数进行调整
调整min_samples_leaf
## 调整min_samples_leaf scorel = [] for i in range(1,20): RFC = RandomForestClassifier(max_depth=20,n_estimators=51,min_samples_leaf=i, n_jobs=-1, random_state=90).fit(X_train,y_train) score = RFC.score(X_test,y_test) scorel.append(score) print(max(scorel),([*range(1,20)][scorel.index(max(scorel))])) #112是最优的估计器数量 #最优得分是0.951462 plt.figure(figsize=[20,5]) plt.plot(range(1,20),scorel) plt.show() min_samples_split优化 # min_samples_split优化 scorel = [] for i in range(2,20): RFC = RandomForestClassifier(max_depth=20,n_estimators=51,min_samples_leaf=1,min_samples_split=i, n_jobs=-1, random_state=90).fit(X_train,y_train) score = RFC.score(X_test,y_test) scorel.append(score) print(max(scorel),([*range(2,20)][scorel.index(max(scorel))])) #112是最优的估计器数量 #最优得分是0.951462 plt.figure(figsize=[20,5]) plt.plot(range(2,20),scorel) plt.show()