简单记录一下我的随机森林调参经历
用的特征是我脑机接口数据预处理后,特征融合后,降维(分组lda,去除相关性高的特征,随机森林选择重要的特征)后的数据,内容过于复杂,这里就不详细介绍了
由于我对调参不太了解,对调参对效果的影响没有概念,在这里浅浅记录一下
前3组:训练集1186个样本,测试集297个样本,特征45维
后2组:训练集947个样本,测试集240个样本,特征45维
随机种子random_state:34
刚开始,所有参数都用默认值,可以参考官网:
class sklearn.ensemble.RandomForestClassifier(n_estimators=100, ***, criterion=‘gini’, max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=‘sqrt’, max_leaf_nodes=None, min_impurity_decrease=0.0, bootstrap=True, oob_score=False, n_jobs=None, random_state=None, verbose=0, warm_start=False, class_weight=None, ccp_alpha=0.0, max_samples=None)
得出的结果可以作为baseline:
第 1 个被试 accuracy 0.7912457912457912
第 2 个被试 accuracy 0.8243243243243243
第 3 个被试 accuracy 0.7811447811447811
第 4 个被试 accuracy 0.8416666666666667
第 5 个被试 accuracy 0.7291666666666666
每一次调参,都是只改一个参数,其他参数(除了随机种子)都是默认值
在调参的过程中,我也会分别选择参数,最后组合到一起,和baseline比较
改n_estimators
n_estimators是森林中树木的数量
默认的n_estimators是100
改成50:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.797979797979798
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8175675675675675
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.7811447811447811
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8291666666666667
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7333333333333333
改成150:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.8114478114478114
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8243243243243243
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.7878787878787878
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8458333333333333
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7458333333333333
改成200:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.8114478114478114
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8277027027027027
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.8047138047138047
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8666666666666667
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7583333333333333
改成250:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.8215488215488216
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8277027027027027
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.8114478114478114
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.85
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7583333333333333
改成300:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.8181818181818182
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.831081081081081
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.8013468013468014
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8541666666666666
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7541666666666667
改成350:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.8148148148148148
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8344594594594594
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.8080808080808081
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8625
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.75
改成400:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.8047138047138047
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8344594594594594
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.7946127946127947
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8583333333333333
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.75
感觉,不管改成啥样,都比默认值强
但是总体感觉还是差差不多的
选个250
改criterion
衡量分割质量的函数
默认的criterion是"gini"
这里改成别的试试
(改成log_loss会报错,就不改成那个了)
改成"entropy":
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.8080808080808081
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8513513513513513
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.8114478114478114
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8541666666666666
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7666666666666667
提升还是比较明显的
那就改成entropy
改max_depth
树的最大深度。如果没有,则扩展节点,直到所有叶子都是纯的或直到所有叶子包含少于 min_samples_split 样本。
默认:max_depth=None
参考了
这里改成:3,5,8,15,25,30试一试
改成3:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.7272727272727273
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.7804054054054054
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.7272727272727273
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.7958333333333333
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7041666666666667
有明显的下降
改成5:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.7845117845117845
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8006756756756757
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.7676767676767676
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8333333333333334
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7125
有明显的下降
改成8:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.7912457912457912
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8074324324324325
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.7777777777777778
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8458333333333333
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7666666666666667
有的下降了,有的提升了
改成15:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.7912457912457912
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8209459459459459
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.7878787878787878
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8416666666666667
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.725
总体没有明显变化
改成25:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.7912457912457912
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8243243243243243
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.7811447811447811
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8416666666666667
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7291666666666666
完全没变。
改成30:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.7912457912457912
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8243243243243243
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.7811447811447811
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8416666666666667
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7291666666666666
完全没变。(因为25就已经完全没变了)
所以,在这一部分,我选择None。
改min_samples_split
分裂一个内部节点所需的最小样本数
如果是 int,则将 min_samples_split
视为最小数字。
如果是float,则 min_samples_split
是分数, ceil(min_samples_split * n_samples)
是每次分割的最小样本数。
默认是2.
根据参考的博客,这里取3,5,10,15,100试试
改成3:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.8181818181818182
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8412162162162162
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.7946127946127947
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8583333333333333
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7458333333333333
提升了
改成5:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.797979797979798
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8243243243243243
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.7845117845117845
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8375
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7625
有的提升,有的降低,感觉差别不大
改成10:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.8047138047138047
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8108108108108109
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.7777777777777778
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.85
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7625
有的提升了,有的降低了
改成15:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.8013468013468014
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8243243243243243
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.7946127946127947
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8541666666666666
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7458333333333333
有一点点提升
改成100:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.7643097643097643
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.7837837837837838
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.7474747474747475
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7291666666666666
有明显降低
所以,这一部分,我选择min_samples_split=3
改min_samples_leaf
叶节点所需的最小样本数。只有在左右分支中至少留下 min_samples_leaf
个训练样本时,才会考虑任何深度的分割点。
我觉得改得稍微大一点,有利于减少过拟合。
如果是 int,则将 min_samples_leaf
视为最小数字。
如果是浮点型,则 min_samples_leaf
是分数, ceil(min_samples_leaf * n_samples)
是每个节点的最小样本数。
这里改成:2,5,10
改成2:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.797979797979798
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8277027027027027
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.7878787878787878
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8625
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7625
有一点点提升
改成5:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.7845117845117845
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8243243243243243
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.7845117845117845
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8625
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7541666666666667
3个往上走,1个往下走
改成10:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.7777777777777778
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8074324324324325
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.7744107744107744
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8166666666666667
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7375
4个往下走,1个往上走
这种情况,我觉得是欠拟合了
所以,这一部分,选择min_samples_leaf=2
改max_features:
寻找最佳分割时要考虑的特征数量。
如果是 int,则考虑每次分割的 max_features
个特征。
如果是float,则 max_features
是一个分数,并且在每次分割时都会考虑 max(1, int(max_features * n_features_in_))
特征。
如果是“sqrt”,则 max_features=sqrt(n_features)
。
如果是“log2”,则 max_features=log2(n_features)
。
如果是None,则 max_features=n_features
。
版本 1.1 中的更改: max_features
的默认值从 "auto"
更改为 "sqrt"
。
我这里的默认值是auto,我会试一试:sqrt,log2,None
改成"sqrt"
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.7912457912457912
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8243243243243243
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.7811447811447811
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8416666666666667
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7291666666666666
完全一致。
改成"log2"
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.7878787878787878
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8412162162162162
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.8215488215488216
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8458333333333333
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7458333333333333
1个往下走,4个往上走。
改成None
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.7609427609427609
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8040540540540541
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.7878787878787878
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8458333333333333
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7458333333333333
2个往下走,3个往上走。
这个参数,我选择改成log2
综合改一改试试
根据上边的结果,改成:
clf_random_forest =
RandomForestClassifier(n_estimators=250,criterion="entropy",max_depth=None,min_samples_split=3,max_features="log2", random_state=34)
结果如下:
第 1 个被试 baseline 0.7912457912457912
第 1 个被试 修改后的accuracy 0.8181818181818182
第 2 个被试 baseline 0.8243243243243243
第 2 个被试 修改后的accuracy 0.8344594594594594
第 3 个被试 baseline 0.7811447811447811
第 3 个被试 修改后的accuracy 0.8181818181818182
第 4 个被试 baseline 0.8416666666666667
第 4 个被试 修改后的accuracy 0.8458333333333333
第 5 个被试 baseline 0.7291666666666666
第 5 个被试 修改后的accuracy 0.7541666666666667
可以看出,有时只调整一个参数,是比把这些参数组合在一起效果要好的
不过这么一改,至少是超过了baseline一点点
而且这里有一个bug,就是我实际是通过测试集来选择参数的,而不是通过验证集,所以也存在数据泄露的问题
所以,我还是把这些参数组合在一起吧,虽然可能acc比不上只改动一个参数
其实,划分一个验证集,用网格搜索的方式,也可以找出合适的参数,不过我还没有学到那一部分,目前只是想感受一下参数对结果的影响