text.html 6.8 KB
Newer Older
ToTensor's avatar
ToTensor 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
 
<p class="content">我们早已经知道了内容参数和超参数的区别。内容参数是算法内部的权重和偏置,而超参数是算法的参数,例如逻辑回归中的C值、神经网络的层数和优化器、KNN中的K值,都是超参数。</p> 
<p class="content">算法的内部参数,是算法通过梯度下降自行优化,而超参数通常依据经验手工调整。</p> 
<p class="content">在第4课的学习中,我们手工调整过逻辑回归算法中的C值,那时小冰就提出过一个问题:为什么要手工调整,而不能由机器自动地选择最优的超参数?</p> 
<p class="content">而本次课程中,我们看到了同一个KNN算法,不同K值所带来的不同结果。因此,机器是可以通过某种方法自动找到最佳的K值的。</p> 
<p class="content">现在揭晓这个“秘密武器”:利用Sklearn的网格搜索(Grid Search)功能,可以为特定机器学习算法找到每一个超参数指定范围内的最佳值。</p> 
<p class="content">什么是指定范围内的最佳值呢?思路很简单,就是列举出一组组可选超参数值。网格搜索会遍历其中所有的可能组合,并根据指定的评估指标比较每一个超参数组合的性能。这个思路正如刚才在KNN算法中,选择1~15来逐个检查哪一个K值效果最好。当然,通常来说,超参数并不是一个,因此组合起来,可能的情况也多。</p> 
<p class="content">下面用网格搜索功能进一步优化随机森林算法的超参数,看看预测准确率还有没有能进一步提升的空间:</p> 
<div class="content_106"> 
 <p class="content_105">from sklearn.model_selection import Stratified KFold # 导入K折验证工具</p> 
 <p class="content_105">from sklearn.model_selection import Grid Search CV # 导入网格搜索工具</p> 
 <p class="content_105">kfold = Stratified KFold(n_splits=10) # 10折验证</p> 
 <p class="content_105">rf = Random Forest Classifier() # 随机森林模型</p> 
 <p class="content_105"># 对随机森林算法进行参数优化</p> 
 <p class="content_105">rf_param_grid = {"max_depth": [None],</p> 
 <p class="content_119">"max_features": [3, 5, 12],</p> 
 <p class="content_119">"min_samples_split": [2, 5, 10],</p> 
 <p class="content_119">"min_samples_leaf": [3, 5, 10],</p> 
 <p class="content_119">"bootstrap": [False],</p> 
 <p class="content_119">"n_estimators" :[100,300],</p> 
 <p class="content_119">"criterion": ["gini"]}</p> 
 <p class="content_105">rf_gs = Grid Search CV(rf,param_grid = rf_param_grid, cv=kfold,</p> 
 <p class="content_124">scoring="accuracy", n_jobs= 10, verbose = 1)</p> 
 <p class="content_105">rf_gs.fit(X_train, y_train) # 用优化后的参数拟合训练数据集</p> 
</div> 
<p class="content">此处选择了准确率作为各个参数组合的评估指标,并且应用10折验证以提高准确率。程序开始运行之后,10个“后台工作者”开始分批同步对54种参数组合中的每一组参数,用10折验证的方式对训练集进行训练(因为是10折验证,所以共需训练540次)并比较,试图找到最佳参数。</p> 
<p class="content_101"><img alt="" class="h-pic" src="http://csdn-ebook-resources.oss-cn-beijing.aliyuncs.com/images/b88b00f6ad14402ea66695d6809614da/figure-0283-0379.jpg">咖哥发言</p> 
<p class="content">对于随机森林算法中每一个超参数的具体功能,请同学们自行查阅Sklearn文档。</p> 
<p class="content">输出结果如下:</p> 
<div class="content_113"> 
 <p class="content_109">Fitting 10 folds for each of 54 candidates, totalling 540 fits</p> 
 <p class="content_109">[Parallel(n_jobs=10)]: Using backend Loky Backend with 10 concurrent workers.</p> 
 <p class="content_109">[Parallel(n_jobs=10)]: Done 30 tasks   | elapsed:  3.1s</p> 
 <p class="content_109">[Parallel(n_jobs=10)]: Done 180 tasks   | elapsed:  24.3s</p> 
 <p class="content_109">[Parallel(n_jobs=10)]: Done 430 tasks   | elapsed: 1.0min</p> 
 <p class="content_109">[Parallel(n_jobs=10)]: Done 540 out of 540 | elapsed: 1.3min finished</p> 
</div> 
<p class="content">在GPU的加持之下,整个540次拟合只用了1.3分钟(不是每一个训练集的训练速度都这么快,当参数组合数目很多、训练数据集很大时,网格搜索还是挺耗费资源的)。</p> 
<p class="content">下面使用找到的最佳参数进行预测:</p> 
<div class="content_106"> 
 <p class="content_105">from sklearn.metrics import (accuracy_score, confusion_matrix)</p> 
 <p class="content_105">y_hat_rfgs = rf_gs.predict(X_test) # 用随机森林算法的最佳参数进行预测</p> 
 <p class="content_105">print("参数优化后随机森林预测准确率:", accuracy_score(y_test.T, y_hat_rfgs))</p> 
</div> 
<p class="content">在测试集上,对心脏病的预测准确率达到了90%以上,这是之前多种算法都没有达到过的最好成绩:</p> 
<p class="content_112">参数优化后随机森林测试准确率: 0.9016393442622951</p> 
<p class="content">显示一下混淆矩阵,发现 “假正”进一步下降为3人,也就是说测试集中仅有3个健康的人被误判为心脏病患者,同时仅有3个真正的心脏病患者成了漏网之鱼,被误判为健康的人:</p> 
<div class="content_106"> 
 <p class="content_105">cm_rfgs = confusion_matrix(y_test, y_had_rfgs) # 显示混淆矩阵</p> 
 <p class="content_105">plt.figure(figsize=(4, 4))</p> 
 <p class="content_105">plt.title("Random Forest (Best Score) Confusion Matrix")#随机森林(最优参数)混淆矩阵</p> 
 <p class="content_105">sns.heatmap(cm_rfgs, annot=True, cmap="Blues", fmt="d", cbar=False)</p> 
</div> 
<p class="content">参数优化后随机森林算法的混淆矩阵如下图所示。</p> 
<div class="pic"> 
 <img src="http://csdn-ebook-resources.oss-cn-beijing.aliyuncs.com/images/b88b00f6ad14402ea66695d6809614da/figure-0284-0380.jpg"> 
 <p class="imgtitle">参数优化后随机森林算法的混淆矩阵</p> 
</div> 
<p class="content">那么,如果得到了好的结果,能把参数输出来,留着以后重用吗?</p> 
<p class="content">输出最优模型的best_params_属性就行!</p> 
<p class="content">示例代码如下:</p> 
<p class="content_114">print("最佳参数组合:", rf_gs.best_params_)</p> 
<p class="content">输出结果如下:</p> 
<div class="content_113"> 
 <p class="content_109">最佳参数:</p> 
 <p class="content_109">{'bootstrap': False,</p> 
 <p class="content_109">'criterion': 'gini',</p> 
 <p class="content_109">'max_depth': None,</p> 
 <p class="content_109">'max_features': 3,</p> 
 <p class="content_109">'min_samples_leaf': 3,</p> 
 <p class="content_109">'min_samples_split': 2,</p> 
 <p class="content_109">'n_estimators': 100}</p> 
</div> 
<p class="content">这就是网格搜索帮我们找到的随机森林算法的最佳参数组合。</p>