数据科学、数据分析、人工智能必备知识汇总-----机器学习-----主目录-----持续更新:https://blog.csdn.net/grd_java/article/details/144257225 |
---|
文章目录
1. 集成学习
下图是随机森林示意图.把一堆小的弱学习器,组合成一个大的强学习器,用强学习器进行预测
假设你有 15 个朋友给你出主意投资股票,你怎么做最终的决定?
1.选择最牛x的一个朋友的意见当作自己的意见(找到最好的单颗决策树)
2.所有朋友的意见投票,少数服从多数(随机森林)
3.还是投票,牛一点的朋友多给几票,弱鸡一点的少给几票(Adaboost)
4.买啥跌啥的朋友意见该怎么办?(使用技巧,例如二分类任务,和他反着买就行了)
2. 聚合模型 Aggregation Model
所有朋友的意见投票,少数服从多数
G ( x ) = s i g n ( ∑ t = 1 T 1 ⋅ g t ( x ) ) , G ( x ) = 1 T ∑ t = 1 T g t ( x ) G(x) = sign\bigg(\displaystyle\sum^{T}_{t=1} \textcolor{red}{1} \cdot g_t(x)\bigg),\textcolor{purple}{G(x)} = \textcolor{blue}{\dfrac{1}{T}\sum_{t=1}^T} \textcolor{red}{g_t(x)} G(x)=sign(t=1∑T1⋅gt(x)),G(x)=T1t=1∑Tgt(x)
1 : \textcolor{red}{1}: 1:每个朋友投票的权重全部当成1
G ( x ) = s i g n ( ∑ t = 1 T 1 ⋅ g t ( x ) ) G(x) = sign\bigg(\displaystyle\sum^{T}_{t=1} \textcolor{red}{1} \cdot g_t(x)\bigg) G(x)=sign(t=1∑T1⋅gt(x)):是分类任务的,sign表示符号函数,每个朋友都会决定买(1)或不买(-1)
G ( x ) = 1 T ∑ t = 1 T g t ( x ) \textcolor{purple}{G(x)} = \textcolor{blue}{\dfrac{1}{T}\sum_{t=1}^T} \textcolor{red}{g_t(x)} G(x)=T1∑t=1Tgt(x):是回归任务的,有的朋友让多买点,有的让少买点,将每个弱学习器 g t ( x ) \textcolor{red}{g_t(x)} gt(x)的结果进行平均,集成为最终结果
还是投票,牛x一点的朋友多给几票,弱鸡一点的少给几票
G ( x ) = s i g n ( ∑ t = 1 T α t ⋅ g t ( x ) ) , α t ≥ 0 G(x) = sign\bigg(\displaystyle\sum^{T}_{t=1} \textcolor{red}{\alpha_t} \cdot g_t(x)\bigg),\alpha_t ≥0 G(x)=sign(t=1∑Tαt⋅gt(x)),αt≥0
明显看出,每个朋友(base model基础模型)的权重是不一样的,权重越高,话语权越高
如果每个人的看法都一模一样,那没有投票的意义。制造出看法迥异,但是多少都有些道理的朋友。每一个朋友好比是一个 base model。
如何生成不一样的 g(x)?
同样的数据,行列都相同,不同的超参数,可以得到不同的模型。
同样的超参数,行相同,列不同,可以得到不同的模型
同样的超参数,列相同,行不同,可以得到不同的模型
同样的超参数,同样的数据,但是数据权重不同,可以得到不同的模型
Bagging装袋,一种聚合方式,也就是那种弱学习器投票,少数服从多数的 |
---|
对训练集进行抽样,将抽样的结果用于训练 g(x)。
bagging里面的抽样一般称为Bootstrap:有放回地对原始数据集进行均匀抽样,抽出来还会放回去,这一次抽有可能会抽到上一次的样本
利用每次抽样生成的数据集训练模型。这样每个模型都可能抽到一部分相同的样本,称为交集。对应于还有差集
最终的模型为每次生成的模型进行投票,而回归任务时,会求平均
并行,独立训练。
相关模型:random forest随机森林
Boosting提升 |
---|
利用训练集训练出模型,根据本次模型的预测结果,调整训练集,然后利用调整后的训练集训练下一个模型
串行,需要第一个模型。每个学习器权重不一,最终需要加权求和
相关模型:adaboost,GBDT,Xgboost
其实 boosting 和 bagging 都不仅局限于对决策树这种基模型适应
如果不是同一种 base model的话(不同算法,例如决策树和逻辑回归),上stacking
基于不同算法的弱学习器,初步学习完成后,可以通过一个模型,例如逻辑回归打上不同权重。
也就是将之前上一层的弱学习器学习的结果,当做当前层次模型的输入
例如第一层不同学习器初步学习,第二层的学习器将其结果整合在一起,再次进行学习输出结果
相当于多层堆叠到一起,堆叠的英文单词就是stacking
但是都需要搞这个了,为什么不直接上神经网络呢?为什么不用深度学习呢?
3. 随机森林
使用Bagging 思想,加上决策树作为 base model,以及投票uniform blending就是每个模型对应的权重都为1
{ f u n c t i o n R a n d o m F o r e s t ( D ) F o r t = 1 , 2 , . . . , T 1 、通过 b o o t s t r a p p i n g 在数据集 D 中采集 N 个数据构成的 D t 2 、采集完成的 D t ,通过 D T r e e ( D t ) 获取弱学习器 g t r e t u r n G = U n i f o r m ( { g t } ) \begin{cases} function \enspace \textcolor{purple}{RandomForest}(D)\\ \enspace\enspace\enspace\enspace For \enspace t=1,2,...,T\\ \enspace\enspace\enspace\enspace\enspace\enspace\enspace\enspace 1、通过\textcolor{blue}{bootstrapping}在数据集D中采集N个数据构成的\textcolor{blue}{D_t}\\ \enspace\enspace\enspace\enspace\enspace\enspace\enspace\enspace 2、采集完成的\textcolor{blue}{D_t},通过\textcolor{orange}{DTree}(\textcolor{blue}{D_t})获取弱学习器\textcolor{blue}{g_t}\\ \enspace\enspace\enspace\enspace return \enspace \textcolor{purple}{G} = Uniform(\{\textcolor{blue}{g_t}\}) \end{cases} ⎩ ⎨ ⎧functionRandomForest(D)Fort=1,2,...,T1、通过bootstrapping在数据集D中采集N个数据构成的Dt2、采集完成的Dt,通过DTree(Dt)获取弱学习器gtreturnG=Uniform({gt})
至于DTree,前面章节介绍决策树时已经介绍过了:
https://blog.csdn.net/grd_java/article/details/144464197
可以高并行的去学习,因为每个模型相互独立
因为使用C&RT,所以会集成CART的优点
限制完全生长树的缺点
都有哪些随机?
bagging 生成小树时随机抽样数据
抽样数据后 对 feature 也进行抽样
翻看sklearn中决策树的DecisionTreeClassifier参数的max_features(最大特征数)
指定当寻找最优分裂时需要考虑的最大特征数量
随机森林的表现会随着决策树的增多,变的越来越好
复杂数据上的表现也不错
对于有噪声数据的表现,也会随着决策树的增多,效果变的越来越好
总结 |
---|
随机森林
随机选择样本(放回抽样);
随机选择特征;
构建决策树;
随机森林投票(平均)
优点:
表现良好
可以处理高维度数据(维度随机选择)
辅助进行特征选择
得益于 bagging 可以进行并行训练
缺点:
对于噪声过大的数据容易过拟合
4. 鸢尾花案例
4.1 随机森林
sklearn中提供了集成模型,放在了sklearn.ensemble模块中,其中就包含处理分类问题的随机森林RandomForestClassifier
引入第三方包
from sklearn.ensemble import RandomForestClassifier # 引入随机森林处理分类问题
from sklearn.datasets import load_iris # 鸢尾花数据集
from sklearn.metrics import accuracy_score # 评判预测的准不准
from sklearn.model_selection import train_test_split # 拆分训练集和测试集
获取鸢尾花数据集并拆分数据集
iris = load_iris()
X = iris.data[:,:] # 花瓣长度和宽度
y = iris.target
# 拆分训练集和测试集
xTrain,xTest,yTrain,yTest = train_test_split(X,y,test_size=0.2,random_state=42)
随机森林分类学习器
# n_estimators 用多少颗小树构成森林
# max_leaf_nodes防止过拟合的前剪枝超参数,最大叶子结点数设置为16
# n_jobs并行度,小树多了开多线程训练自然效率更高,但是树少的时候没必要。设置为1即可
rnd_clf = RandomForestClassifier(n_estimators=15,max_leaf_nodes=16,n_jobs=1,oob_score=True)
rnd_clf.fit(xTrain,yTrain)
rnd_clf.oob_score_
使用测试集进行预测,并获取acc准确率
y_pred_rf = rnd_clf.predict(xTest) # 用测试集预测
accuracy = accuracy_score(yTest,y_pred_rf)# 获取预测准确度
accuracy
输出特征重要程度
# Feature Importance,每个维度(特征)的重要程度
iris = load_iris()
rnd_clf = RandomForestClassifier(n_estimators=500, n_jobs=-1)
rnd_clf.fit(iris["data"], iris['target'])
for name, score in zip(iris['feature_names'], rnd_clf.feature_importances_):
print(name, score)
4.2 bagging其它弱学习器
既然随机森林是bagging思想用决策树作为弱学习器。那也可以直接用bagging,搭配其它弱学习器
引入第三方包
from sklearn.ensemble import BaggingClassifier # 引入基于Bagging的分类学习器
from sklearn.linear_model import LogisticRegression #逻辑回归作为弱学习器
from sklearn.datasets import load_iris # 鸢尾花数据集
from sklearn.metrics import accuracy_score # 评判预测的准不准
from sklearn.model_selection import train_test_split # 拆分训练集和测试集
获取鸢尾花数据集并拆分数据集
iris = load_iris()
X = iris.data[:,:] # 花瓣长度和宽度
y = iris.target
# 拆分训练集和测试集
xTrain,xTest,yTrain,yTest = train_test_split(X,y,test_size=0.2,random_state=42)
构建逻辑回归为弱学习器,使用bagging集成训练
log_clf = LogisticRegression() # 逻辑回归弱学习器
bag_clf = BaggingClassifier(log_clf,n_estimators=10,n_jobs=1,bootstrap=True) # bagging集成
bag_clf.fit(xTrain,yTrain)
使用测试集进行预测,并获取acc准确率
y_pred_rf = bag_clf.predict(xTest)
accuracy = accuracy_score(yTest,y_pred_rf)# 获取预测准确度
accuracy
4.3 bagging不同种类弱学习器
第三方库
from sklearn.linear_model import LogisticRegression #逻辑回归作为弱学习器
from sklearn.svm import SVC # 支持向量机
from sklearn.tree import DecisionTreeClassifier # 决策树
from sklearn.ensemble import VotingClassifier # 投票分类问题集成
from sklearn.datasets import load_iris # 鸢尾花数据集
from sklearn.metrics import accuracy_score # 评判预测的准不准
from sklearn.model_selection import train_test_split # 拆分训练集和测试集
鸢尾花数据集和拆分
iris = load_iris()
X = iris.data[:,:] # 花瓣长度和宽度
y = iris.target
# 拆分训练集和测试集
xTrain,xTest,yTrain,yTest = train_test_split(X,y,test_size=0.2,random_state=42)
将3种不同类型弱学习器进行集成
log_clf = LogisticRegression() # 逻辑回归弱学习器
decisionTreeClassifier = DecisionTreeClassifier() # 决策树
SVC_my = SVC() # 支持向量机
votingClassifier = VotingClassifier(estimators=[('lr',log_clf),('dt',decisionTreeClassifier),('svc',SVC_my)], voting='hard')
votingClassifier.fit(xTrain,yTrain)
预测并计算acc
y_pred_rf = votingClassifier.predict(xTest)
accuracy = accuracy_score(yTest,y_pred_rf)# 获取预测准确度
accuracy # 结果为1.0
5. Out of bag data
在进行抽样的时候,有很多条数据并没有被选到
数量:
1 条数据 N 轮没有备选到的概率: ( 1 − 1 N ) N (1-\dfrac{1}{N})^N (1−N1)N
当 N 足够大的时候: ( 1 − 1 N ) N = 1 ( N N − 1 ) N = 1 ( 1 + 1 N − 1 ) N ≈ 1 e (1-\dfrac{1}{N})^N = \dfrac{1}{(\dfrac{N}{N-1})^N}=\dfrac{1}{(1+\dfrac{1}{N-1})^N}≈\dfrac{1}{e} (1−N1)N=(N−1N)N1=(1+N−11)N1≈e1
我们前面代码中都根据比例将数据分为训练集和测试集。那能不能让oob(Out of bag)数据当做测试集数据呢?
前面我们都用acc来计算准确率,其实集成模型有一个oob_score_属性,可以获取使用哦oob数据作为测试集的错误率(注意这个是错误率,不是准确率),1-oob错误率就是准确率
# oob_score=True后才能使用
rnd_clf = RandomForestClassifier(n_estimators=15,max_leaf_nodes=16,n_jobs=1,oob_score=True)
rnd_clf.fit(xTrain,yTrain)
# 直接访问即可
rnd_clf.oob_score_