【2 - 随机森林 - 案例部分:随机森林在乳腺癌数据上的调参】菜菜sklearn机器学习

news2024/9/20 10:29:45

课程地址:《菜菜的机器学习sklearn课堂》_哔哩哔哩_bilibili

  • 第一期:sklearn入门 & 决策树在sklearn中的实现
  • 第二期:随机森林在sklearn中的实现
  • 第三期:sklearn中的数据预处理和特征工程
  • 第四期:sklearn中的降维算法PCA和SVD
  • 第五期:sklearn中的逻辑回归
  • 第六期:sklearn中的聚类算法K-Means
  • 第七期:sklearn中的支持向量机SVM(上)
  • 第八期:sklearn中的支持向量机SVM(下)
  • 第九期:sklearn中的线性回归大家族
  • 第十期:sklearn中的朴素贝叶斯
  • 第十一期:sklearn与XGBoost
  • 第十二期:sklearn中的神经网络

目录

机器学习中调参的基本思想 

(一)泛化误差

(二)偏差(bias)-方差(variance)困境

案例:随机森林在乳腺癌数据上的调参 

(一)导入需要的库

(二)导入数据集,探索数据

(三)进行一次简单的建模,看看模型本身在数据集上的效果

(四)随机森林调整的第一步:无论如何先来调n_estimators

(五)在确定好的范围内,进一步细化学习曲线 

(六)为网格搜索做准备,书写网格搜索的参数

(七)开始按照参数对模型整体准确率的影响程度进行调参,首先调整max_depth

(八)调整max_features

(九)调整min_samples_leaf

(十)调整min_samples_split

(十一)尝试一下criterion

(十二)调整完毕,总结出模型的最佳参数

Bagging vs Boosting


机器学习中调参的基本思想 

通过画学习曲线,或者网格搜索,我们能够探索到调参边缘

正确的模型调参思路:

  1. 目标是提升某个模型评估指标,比如对于随机森林来说,想要提升的是模型在未知数据上的准确率(由 score 或 oob_score_ 来衡量)
  2. 模型在未知数据上的准确率受什么因素影响?在机器学习中,用来衡量模型在未知数据上的准确率的指标,叫泛化误差(genelization error)

(一)泛化误差

当模型在未知数据(测试集或袋外数据)上表现糟糕时,即模型的泛化程度不够,泛化误差大,模型效果不好

泛化误差受到模型的结构(复杂度)影响:

  • 当模型太复杂,模型就会过拟合,泛化能力就不够,所以泛化误差大
  • 当模型太简单,模型就会欠拟合,拟合能力就不够,所以泛化误差大
  • 只有当模型的复杂度刚刚好,才能够达到泛化误差最小的目标

  • 对树模型来说,树越茂盛,深度越深,枝叶越多,模型就越复杂,所以树模型是天生位于图的右上角的模型
  • 随机森林以树模型为基础,所以随机森林也是天生复杂度高的模型。随机森林的参数都是向着一个目标去:减少模型的复杂度,把模型往图像的左边移动,防止过拟合
  • 但是也有天生处于图像左边的随机森林,所以在调参之前,要先判断模型现在究竟处于图像的哪一边 

(二)偏差(bias)-方差(variance)困境

四点结论:

  1. 模型太复杂或太简单,都会让泛化误差高,追求的是位于中间的平衡点
  2. 模型太复杂就会过拟合,太简单就会欠拟合
  3. 对树模型和树的集成模型来说,树的深度越深,枝叶越多,模型越复杂(剪枝是降低模型的复杂度)
  4. 树模型和树的集成模型的目标,都是减少模型复杂度,把模型往图像的左边移动

随机森林的调参方向是降低复杂度,故将那些对复杂度影响巨大的参数挑选出来,研究它们的单调性,调整那些能最大限度降低复杂度的参数;对于那些不单调的参数,或者反而会让复杂度升高的参数,视情况使用 

 

一个好的模型,要对大多数未知数据都预测的准又稳,即当偏差和方差都很低的时候,模型的泛化误差就小,在未知数据上的准确率就高。然而,方差和偏差是此消彼长的,不可能同时达到最小值,调参的目标是达到方差和偏差的平衡 

  1. 偏差:模型的预测值与真实值之间的差异,模型越精确,偏差越低
  2. 方差:模型每一次输出结果与模型预测值的平均水平之间的误差,模型越稳定,方差越低 

随机森林的基评估器都拥有较低的偏差和较高的方差,因为决策树本身是预测比较准、比较容易过拟合的模型,装袋法本身也要求基分类器的准确率必须要有50%以上。所以以随机森林为代表的装袋法的训练过程,旨在降低方差(即降低模型复杂度),故随机森林参数的默认设定都是假设模型本身在泛化误差最低点的右边 


案例:随机森林在乳腺癌数据上的调参 

  • 基于方差和偏差的调参方法
  • 乳腺癌数据是sklearn自带的分类数据之一

(一)导入需要的库

from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

(二)导入数据集,探索数据

data = load_breast_cancer()

data.data.shape   # (569, 30)

data.target   # 二分类数据0/1
 
# 可以看到,乳腺癌数据集有569条记录,30个特征,单看维度虽然不算太高,但是样本量非常少,过拟合的情况可能存在

(三)进行一次简单的建模,看看模型本身在数据集上的效果

rfc = RandomForestClassifier(n_estimators=100,random_state=90)
score_pre = cross_val_score(rfc,data.data,data.target,cv=10).mean()  #交叉验证的分类默认scoring='accuracy'
 
score_pre
 
#这里可以看到,随机森林在乳腺癌数据上的表现本就还不错,在现实数据集上,基本上不可能什么都不调就看到95%以上的准确率

调参顺序:n_estimators —> max_depth —> min_samples_leaf —> min_samples_split —> max_features —> criterion 

(四)随机森林调整的第一步:无论如何先来调n_estimators

"""
在这里我们选择学习曲线,可以使用网格搜索吗?可以,但是只有学习曲线,才能看见趋势
我个人的倾向是,要看见n_estimators在什么取值开始变得平稳,是否一直推动模型整体准确率的上升等信息
第一次的学习曲线,可以先用来帮助我们划定范围,我们取每十个数作为一个阶段,来观察n_estimators的变化如何引起模型整体准确率的变化
"""
 
scorel = []
for i in range(0,200,10):   # 0 10 20 30 ... 200
    rfc = RandomForestClassifier(n_estimators=i+1,
                                 n_jobs=-1,   # 使用CPU里的所有core
                                 random_state=90)
    score = cross_val_score(rfc,data.data,data.target,cv=10).mean()
    scorel.append(score)

# list.index([object])  返回这个object在列表list中的索引
print(max(scorel),(scorel.index(max(scorel))*10)+1)   
# scorel.index(max(scorel))返回scorel列表中最大值的索引
# scorel.index(max(scorel))*10)+1对应n_estimators的取值

plt.figure(figsize=[20,5])
plt.plot(range(1,201,10),scorel)
plt.show()

(五)在确定好的范围内,进一步细化学习曲线 

scorel = []
for i in range(65,75):   # 在上一步得出的71结果附近再细化探索
    rfc = RandomForestClassifier(n_estimators=i,
                                 n_jobs=-1,
                                 random_state=90)
    score = cross_val_score(rfc,data.data,data.target,cv=10).mean()
    scorel.append(score)

print(max(scorel),([*range(65,75)][scorel.index(max(scorel))]))

plt.figure(figsize=[20,5])
plt.plot(range(65,75),scorel)
plt.show()

调整 n_estimators 的效果显著,模型的准确率立刻上升了0.003

接下来就使用复杂度-泛化误差方法(方差-偏差方法)网格搜索对参数一个个进行调整(同时调整多个参数,会让我们无法理解参数的组合是怎么得来的,所以即便网格搜索调出来的结果不好,也不知道从哪里去改) 

(六)为网格搜索做准备,书写网格搜索的参数

有一些参数是没有参照的,很难说清一个范围,这种情况下我们使用学习曲线,看趋势。从曲线跑出的结果中选取一个更小的区间,再跑曲线

param_grid = {'n_estimators':np.arange(0, 200, 10)}
 
param_grid = {'max_depth':np.arange(1, 20, 1)}
    
param_grid = {'max_leaf_nodes':np.arange(25,50,1)}
# 对于大型数据集,可以尝试从1000来构建,先输入1000,每100个叶子一个区间,再逐渐缩小范围

有一些参数是可以找到一个范围的,或者说我们知道它们的取值和随着它们的取值,模型的整体准确率会如何变化,这样的参数我们就可以直接跑网格搜索

param_grid = {'criterion':['gini', 'entropy']}
 
param_grid = {'min_samples_split':np.arange(2, 2+20, 1)}   # 默认值2
 
param_grid = {'min_samples_leaf':np.arange(1, 1+10, 1)}   # 默认值1

# 默认值是特征数量开平方,该值要么是设置的最大值,要么是最小值
# 即范围是从0-该值,或从该值-最大特征量    
param_grid = {'max_features':np.arange(5,30,1)}

(七)开始按照参数对模型整体准确率的影响程度进行调参,首先调整max_depth

#调整max_depth
param_grid = {'max_depth':np.arange(1, 20, 1)}
 
#   一般根据数据的大小来进行一个试探,乳腺癌数据很小,所以可以采用1~10,或者1~20这样的试探
#   但对于像digit recognition那样的大型数据来说,我们应该尝试30~50层深度(或许还不足够
#   更应该画出学习曲线,来观察深度对模型的影响
 
rfc = RandomForestClassifier(n_estimators=73
                             ,random_state=90
                            )

GS = GridSearchCV(rfc,param_grid,cv=10)  #网格搜索
GS.fit(data.data,data.target)

GS.best_params_   #显示调整出来的最佳参数

 

GS.best_score_   #返回调整好的最佳参数对应的准确率

 

  • 将max_depth设置为有限之后,模型的准确率不变 
  • 限制max_depth,是让模型变得简单,把模型向左推
  • 通常来说,随机森林应该在泛化误差最低点的右边,树模型应该倾向于过拟合,而不是拟合不足。这和数据集本身有关,也有可能是我们调整的n_estimators对于数据集来说太大,因此将模型拉到泛化误差最低点了

当模型位于图像左边时,需要增加模型复杂度(增加方差,减少偏差),因此max_depth应尽量大,min_samples_leaf和min_samples_split应尽量小,这三个参数是剪枝参数(减小复杂度的参数)

(八)调整max_features

max_features是唯一一个既能够将模型往左(低方差高偏差)推,也能够将模型往右(高方差低偏差)推的参数。我们需要根据调参前模型所在的位置(在泛化误差最低点的左边还是右边)来决定我们要将max_features往哪边调

max_features的默认最小值是sqrt(n_features)

# 调整max_features,总共有30个特征,默认值为根号30≈5.
param_grid = {'max_features':np.arange(5,30,1)}    # 往复杂度高的方向调

rfc = RandomForestClassifier(n_estimators=73
                             ,random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)
 
GS.best_params_
 
GS.best_score_

  

提升了

max_features降低之后,模型的准确率提升了。这说明,我们把模型往左推,模型的泛化误差降低了,说明模型在曲线的右边 

(九)调整min_samples_leaf

#调整min_samples_leaf
param_grid={'min_samples_leaf':np.arange(1, 1+10, 1)}   # 默认为1(最大复杂度)
 
#对于min_samples_split和min_samples_leaf,一般是从他们的最小值开始向上增加10或20
#面对高维度高样本量数据,如果不放心,也可以直接+50,对于大型数据,可能需要200~300的范围
#如果调整的时候发现准确率无论如何都上不来,那可以放心大胆调一个很大的数据,大力限制模型的复杂度
 
rfc = RandomForestClassifier(n_estimators=73
                             ,random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)

GS.best_params_
GS.best_score_

下降了

可以看见,网格搜索返回了min_samples_leaf的最小值,且模型整体的准确率还降低了,即参数把模型向左推,但是模型的泛化误差上升了。在这种情况下,不要把这个参数设置起来,默认即可

(十)调整min_samples_split

#调整min_samples_split
param_grid={'min_samples_split':np.arange(2, 2+20, 1)}   # 默认为2(最大复杂度)
 
rfc = RandomForestClassifier(n_estimators=73
                             ,random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)

GS.best_params_
GS.best_score_

和min_samples_leaf一样的结果,返回最小值并且模型整体的准确率降低了 

(十一)尝试一下criterion

#调整Criterion
param_grid = {'criterion':['gini', 'entropy']}
 
rfc = RandomForestClassifier(n_estimators=73
                             ,random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)

GS.best_params_
GS.best_score_

(十二)调整完毕,总结出模型的最佳参数

rfc = RandomForestClassifier(n_estimators=73,max_features=2,random_state=90)
score = cross_val_score(rfc,data.data,data.target,cv=10).mean()
score
score - score_pre   # 调参前后准确率的变动

 

在整个调参过程中,首先调整n_estimators(无论如何这都是第一步),然后调整max_depth,通过max_depth产生的结果来判断模型位于复杂度-泛化误差图像的哪一边,从而选择我们应该调整的参数和调参的方向 

也可以画学习曲线来观察参数会如何影响准确率,选取学习曲线中单调的部分来放大研究,学习曲线的拐点也许就是我们追求的、最佳复杂度对应的泛化误差最低点(也是方差和偏差的平衡点)


Bagging vs Boosting

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/135229.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue3笔记案例——Suspense使用之骨架屏

文章目录skeleton组件sync组件Suspense使用skeleton组件 示例图 代码 <template><div class"sk"><div class"sk-2"><div class"sk-2-1"></div><div></div></div><hr><div class&qu…

亚马逊云科技 Build On -轻松搭建咖啡点单系统

【前言】 1、什么是Build On&#xff1f; Build On是亚马逊团队基于亚马逊云服务开发&#xff0c;打造的一系列可快速上手的实操性活动。通过通俗易懂的场景案例、简单快捷的开发路径&#xff0c;参与者可快速理解目标任务涉及的相关知识&#xff0c;同时对亚马逊云服务具备一…

【回答问题】ChatGPT上线了!推荐30个以上比较好的意图识别模型

【回答问题】ChatGPT上线了&#xff01;推荐30个以上比较好的意图识别github源码&#xff1f; 好的&#xff0c;这里列出 30 个相对比较优秀的意图识别 GitHub 源码&#xff1a; DeepPavlov Rasa Snips spaCy OpenAI GPT OpenAI DialogFlow ChatterBot Botpress Amazon Lex M…

ArcGIS基础实验操作100例--实验41提取道路面中心线

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验41 提取道路面中心线 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1…

2022,我遭遇的那些小事

前言 2022&#xff0c;总感觉一晃眼就过去了&#xff0c;不知不觉自己坚持更文已经一周年了。回顾这一周年&#xff0c;无论是在技术成长上还是职业发展上&#xff0c;都有了许多新的体会。 裁员风波 还记得是四、五月份的一个上午&#xff0c;原本还在紧张的加班赶项目&…

educoder数据结构与算法 队列 第2关 实现一个链接存储的队列

本文已收录于专栏 &#x1f332;《educoder数据结构与算法_大耳朵宋宋的博客-CSDN博客》&#x1f332; 目录 任务描述 相关知识 编程要求 测试说明 AC_Code 任务描述 本关任务&#xff1a;实现 step2/CLnkQueue.cpp 中的CLQ_IsEmpty、CLQ_Length、CLQ_In和CLQ_Out四个操…

论文阅读和复现:去除PPG运动伪影的IEEE论文

论文阅读和代码复现&#xff1a; 《Combining Nonlinear Adaptive Filtering and Signal Decomposition for Motion Artifact Removal in Wearable Photoplethysmography》 基本介绍&#xff1a; 由于手腕运动造成的噪声&#xff1a;运动伪影&#xff0c;使得PPG方法的心率监…

shell-流程控制之条件判断

1、判断当前磁盘剩余空间是否有20G&#xff0c;如果小于20G&#xff0c;则将报警邮件发送给管理员&#xff0c;每天检查一次磁盘剩余空间。 补充&#xff1a;20G20971520kb [rootcotenos day06]# pwd /root/shell/day06 [rootcotenos day06]# vim free_men.sh #!/bin/bash f…

spring boot启动环境的配置与更改(dev,local,pro)包含单元测试环境

文件类型介绍 properties 该文件是一种key-value的格式&#xff0c;配置文件的特点是&#xff0c;它的Key-Value一般都是String-String类型的&#xff0c;因此我们完全可以用Map<String, String>来表示它。 用Properties读取配置文件非常简单。Java默认配置文件以.pro…

elasticsearch 7.9.3知识归纳整理(二)之es基本原理及使用kibana操作es的常见命令

es基本原理及使用kibana操作es的常见命令 一、es的基本原理与基础概念 1.1 倒排索引 倒排索引源于实际应用中需要根据属性的值来查找记录。这种索引表中的每一项都包括一个属性值和具有该属性值的各记录的地址。由于不是由记录来确定属性值&#xff0c;而是由属性值来确定记录…

【机器学习】机器学习中常用的损失函数一览

问题 机器学习中常用的损失函数总结 前言 我们经常听到损失函数、代价函数和目标函数这三种说法&#xff0c;这三种说法有什么联系和区别呢&#xff1f;这里明确下&#xff1a; 损失函数 Loss Function 通常是针对单个训练样本而言的&#xff0c;给定一个模型输出 y^\hat{y…

设计模式 - UML类图

1. 什么是 UML 统一建模语言(Unified Modeling Language,UML)是用来设计软件的可视化建模语言。它的特点是简单、统图形化、能表达软件设计中的动态与静态信息。L从目标系统的不同角度出发&#xff0c;定义了用例图、类图、对象图、状态图、活动图、时序图、协作图、构件图部署…

8种数据结构

快速介绍8种常用数据结构 数据结构是一种特殊的组织和存储数据的方式&#xff0c;可以使我们可以更高效地对存储的数据执行操作。数据结构在计算机科学和软件工程领域具有广泛而多样的用途。 几乎所有已开发的程序或软件系统都使用数据结构。此外&#xff0c;数据结构属于计算…

【回答问题】ChatGPT上线了!有哪些3D点云算法模型?3D点云算法模型实现代码?

有哪些3D点云算法模型&#xff1f; 3D点云算法的模型有很多种&#xff0c;以下是一些常见的算法模型&#xff1a; 归一化重心法&#xff08;Normalized point-to-point ICP&#xff09;&#xff1a;是一种常用的模型配准方法&#xff0c;用于将两个模型中的点匹配起来。 基于…

跨年晚会前夕,曹云金和前妻复合了

每到跨年晚会的时候&#xff0c;总会有大的新闻事件发生&#xff0c;比如说在今年跨年晚会前夕&#xff0c;主持人何炅的老父亲&#xff0c;就非常不幸地驾鹤西去了。话说主持人何炅&#xff0c;在父亲离开后坚强地主持节目&#xff0c;他泪眼婆娑的表情&#xff0c;也登上了各…

电子游戏销售之回归模型与数据可视化

电子游戏销售之回归模型与数据可视化 文章目录电子游戏销售之回归模型与数据可视化0、写在前面1、回归模型1.1 模型建立准备1.2 建立模型1.3 模型分析2、数据可视化3、参考资料0、写在前面 该篇文章的任务包括以下3个方面 检测与处理缺失值建立回归模型数据可视化 实验环境 Pyt…

我的2022年总结

我的2022年总结 行走于世&#xff0c;风大时要表现逆的风骨&#xff0c;风小时要表现顺的悠然。 我们可以转身&#xff0c;但是不必回头&#xff0c;即使有一天你发现自己走错了&#xff0c;你也应该转身大步朝着对的方向去&#xff0c;而不是回头埋怨自己错了。 一、旧事 …

INT201-Decision, Computation and Language(2)

文章目录5. Turing Machine5.1 TM Configuration5.2 TM Transitions5.3 TM Computation5.4 Language accepted by TM5.5 Decider5.6 Multi-tape TM5.6.1 Multi-tape TM equivalent to 1-tape TM5.7 Nondeterministic TM5.7.1 Address5.7.2 NTM equivalent to TM5.8 Enumerable …

【Linux操作系统】yum三板斧和yum源的配置

文章目录一.Linux下软件的生态二.yum三板斧1.yum简介2.list搜索软件包3.install下载并安装4.remove卸载软件三.windows/Linux下文件互传1.lrzsz的查看和下载安装2.rz上传3.sz下载四.Linux软件生态的本土化1.镜像简介2.Linux软件生态的本土化五.yum源的配置1.找到yum源配置文件并…

Jedis: Java连接redis服务

文章目录一、编程语言与 Redis二、Jedis 连接三、JedisPool 连接池四、可视化客户端提示&#xff1a;以下是本篇文章正文内容&#xff0c;Redis系列学习将会持续更新 一、编程语言与 Redis ● Java 语言连接 redis 服务   Jedis   SpringData Redis   Lettuce ● C 、C …