机器学习之集成学习


活动地址:CSDN21天学习挑战赛

Bagging分类

  • 三个臭皮匠顶一个诸葛亮

步骤:

  1. 选取多个样本集合
  2. 建立多个分类器
  3. 组合投票
  • 如何选择样本集合
  1. 样本非常大,平均分配样本
  2. 样本规模本身很小——Observations有放回的重采样

有放回的重采样

原始数据中,仅仅约63%的样本被采样到
P n o t _ c h o o s e = ( 1 − 1 n ) n = 1 e 一个样本不被采样到的概率是 ( 1 − 1 n ) 因此不被采样到的样本,当 n 趋于正无穷时,约等于 1 e , 约等于 37 % P_{not\_choose}=(1-\frac{1}{n})^n=\frac{1}{e}\\ 一个样本不被采样到的概率是(1-\frac{1}{n})\\ 因此不被采样到的样本,当n趋于正无穷时,约等于\frac{1}{e},约等于37\% Pnot_choose=(1n1)n=e1一个样本不被采样到的概率是(1n1)因此不被采样到的样本,当n趋于正无穷时,约等于e1,约等于37%
也就是说,样本训练集中,约
37%的错误训练集将被忽略掉
,提高训练集的质量

特点

  1. 保证了每个分类器样本的规模
  2. 一定程度上忽略了错误训练集的规模,提高了训练集的质量
  3. 弱分类器有差异性
  4. 弱分类器有相同见解

集成分类器预测错误的概率: p ( e r r o r ) = ∑ i = ( m + 1 ) / 2 m [ m i ] r ′ ( 1 − r ) m − 1 集成分类器预测错误的概率:\\ p(error)=\sum_{i=(m+1)/2}^m \begin{bmatrix} m\\ i \end{bmatrix} r'(1-r)^{m-1} 集成分类器预测错误的概率:p(error)=i=(m+1)/2m[mi]r(1r)m1

单分类器的条件

  • 通过集成学习提高分类器的整体泛化能力是有条件的

    • 分类器之间应该具有差异性

      即相关性很弱

    • 分类器的精度,每个个体分类器的分类精度都必须大于0.5

Bagging算法优点

  • 降低噪音数据的影响
  • 不易过拟合

Bagging编程实践

from sklearn.ensemble import BaggingClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
import pandas as pd

data_url='iris_train.csv'
df=pd.read_csv(data_url)

X=df.iloc[:,1:5]
y=df.iloc[:,5]
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=0)

clf=BaggingClassifier(KNeighborsClassifier(),max_samples=0.5,max_features=0.5)
clf.fit(X_train,y_train)

随机森林分类

理论基础

  • 基本思想

    • 行采样——有放回的重采样数据

    • 列采样——有放回的重采样特征

      并不是所有特征,我都会学习

      而每一个决策树特征的选择随机性和数据随机性,使得每个小分类器都有求同存异的特点

  • 关键因素:每棵树选择特征的数量m

  • 随机森林分类效果(错误率)与两个因素有关

    • 森林中任意两棵树的相关性:相关性越大,错误率越大

      【说明基分类器之间差异性越小】

    • 森林中每棵树的分类能力,每棵树的分类能力越强,整个森林的错误率越低

      【说明基分类器准确率高】

  • 减少特征选择个数m,树的相关性和分类能力也会相应的降低

    增大m,两者也会随之增大,所以关键问题时如何选择最优的m

特征数量m的选择

  1. 经验法(Square Root):根据特征的数目开根号
  2. 网格搜索法调参GridSearch
  3. 决策树的数目——500 or more

算法特点

优点

  • 两个随机性的引入,使得随机森林不容易陷入过拟合
  • 两个随机性的引入,使得随机森林具有很好的抗噪声能力
  • 对数据集的适应能力强:既能处理离散型数据,也能处理连续性数据,数据集无需规范化且能够有效地运行在大数据集上
  • 能够处理具有高维特征的输入样本,而且不需要降维
  • 对于缺失值问题也能够获得很好的结果

编程实践

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import pandas as pd

data_url='iris_train.csv'
df=pd.read_csv(data_url)

X=df.iloc[:,1:5]
y=df.iloc[:,5]

X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=0)

clf=RandomForestClassifier(n_estimators=100)

clf.fit(X_train,y_train)

Boosting分类

提升分类器

——Bagging各个分类器的权重时一样的

——Boosting对于分类能力强的分类器给予更高的权重

理论基础

  • 提升方法是一个迭代的过程——因此并行能力不一定太好
    • 通过改变样本分布,使得分类器聚集在那些很难分的样本上,对于那些容易错分的数据加强学习,增加错分数据的权重
    • 这样错分的数据再下一轮的迭代就有更大的作用(对错分数据进行提升)

AdaBoost算法

f o r     k = 1     t o     i t e r a t i o n s : −     c l a s s i f i e r k = l e a r n     a     w e a k     c l a s s i f i e r     b a s e d     o n     w e i g h t s −     c a l c u l a t e     w e i g h t e d     e r r o r     f o r     t h i s     c l a s s i f i e r ( 加权分类误差 ) ε k = ∑ i = 1 n ω i ∗ 1 [ l a b e l i ≠ c l a s s i f i e r k ( x i ) ] −     c a l c u l a t e     “ s c o r e ”     f o r     t h i s     c l a s s i f i e r ( 分类器的系数 ) α k = 1 2 l o g ( 1 − ε i ε i ) −     c h a n g e     t h e     e x a m p l e     w e i g h t s ( 权值的更新 ) w i = 1 Z w i e x p ( − α k ∗ l a b e l i ∗ c l a s s i f i e r k ( x i ) ) for \,\,\, k=1\,\,\,to\,\,\,iterations:\\ -\,\,\,classifier_k=learn\,\,\,a\,\,\,weak\,\,\,classifier\,\,\,based\,\,\,on\,\,\,weights\\ -\,\,\,calculate\,\,\,weighted\,\,\,error\,\,\,for\,\,\,this\,\,\,classifier(加权分类误差)\\ \varepsilon_k=\sum_{i=1}^n\omega_i*1[label_i\neq classifier_k(x_i)]\\ -\,\,\,calculate\,\,\,“score”\,\,\,for \,\,\,this\,\,\,classifier(分类器的系数)\\ \alpha_k=\frac{1}{2}log(\frac{1-\varepsilon_i}{\varepsilon_i})\\ -\,\,\,change\,\,\,the\,\,\,example\,\,\,weights(权值的更新)\\ w_i=\frac{1}{Z}w_iexp(-\alpha_k*label_i*classifier_k(x_i)) fork=1toiterations:classifierk=learnaweakclassifierbasedonweightscalculateweightederrorforthisclassifier(加权分类误差)εk=i=1nωi1[labeli=classifierk(xi)]calculatescoreforthisclassifier(分类器的系数)αk=21log(εi1εi)changetheexampleweights(权值的更新)wi=Z1wiexp(αklabeliclassifierk(xi))

算法流程

  • 训练样本,初始时样本权重相同
  • 计算误差值,得到 ε \varepsilon ε
  • 调整权值,再次迭代

确定 α \alpha α

∙ 集成学习模型: f ( x ) = ∑ m = 1 M α m G m ( x ) ∙ 指数损失函数: L ( y , f ( x ) ) = e x p [ − y f ( x ) ] ∙ 公式推导: 1. 已知 f m ( x ) = f m − 1 ( x ) + α m G m ( x ) 2. 公式代入:将 f m ( x ) = f m − 1 ( x ) + α m G m ( x ) 代入损失函数得 L ( y , f ( x ) ) = ∑ i = 1 N e x p ( − y i ( f m − 1 ( x ) + α m G m ( x ) ) ) 3. 求导得: α k = 1 2 l o g ( 1 − ε i ε i ) \bullet 集成学习模型:f(x)=\sum_{m=1}^M\alpha_mG_m(x)\\ \bullet 指数损失函数:L(y,f(x))=exp[-yf(x)]\\ \bullet 公式推导:\\ 1.已知 f_m(x)=f_{m-1}(x)+\alpha_mG_m(x)\\ 2.公式代入:将f_m(x)=f_{m-1}(x)+\alpha_mG_m(x)代入损失函数得\\ L(y,f(x))=\sum_{i=1}^Nexp(-y_i(f_{m-1}(x)+\alpha_mG_m(x)))\\ 3.求导得:\alpha_k=\frac{1}{2}log(\frac{1-\varepsilon_i}{\varepsilon_i}) 集成学习模型:f(x)=m=1MαmGm(x)指数损失函数:L(y,f(x))=exp[yf(x)]公式推导:1.已知fm(x)=fm1(x)+αmGm(x)2.公式代入:将fm(x)=fm1(x)+αmGm(x)代入损失函数得L(y,f(x))=i=1Nexp(yi(fm1(x)+αmGm(x)))3.求导得:αk=21log(εi1εi)

算法特点

  1. 对数据依赖度很高,容易过拟合
  2. 对噪音数据敏感

编程实践

from sklearn.ensemble import AdaBoostClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import pandas as pd

data_url='iris_train.csv'
df=pd.read_csv(data_url)

X=df.iloc[:,1:5]
y=df.iloc[:,5]

X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=0)
clf=AdaBoostClassifier(n_estimators=100)
clf.fit(X_train,y_train)

Gradient Boost Decision Tree

GBDT=随机森林+AdaBoost

理论基础

  • 由多棵决策树构成,通常都是上百棵树,而且每棵树规模都较小(即每棵树的深度都比较浅
  • 模型预测的时候,对于输入的一个样本实例,然后会遍历每一棵决策树,每棵树都会对预测值进行调整修正,最后得到预测的结果

F ( X ) = F 0 + β 1 T 1 ( X ) + β 2 T 2 ( X ) + . . . + β M T M ( X ) F(X)=F_0+\beta_1T_1(X)+\beta_2T_2(X)+...+\beta_MT_M(X) F(X)=F0+β1T1(X)+β2T2(X)+...+βMTM(X)

学习过程

  • Boosting,迭代,即通过迭代多棵树来共同决策
  • GBDT是把所有树的结论累加起来做最终结论的,所以可以想到每棵树的结论并不是房价本身,而是房价的一个累加值
  • 每一棵树学的是之前所有树结论和的残差,这个残差就是一个加预测值后能得到的真实值的累加量

算法特点

  1. 防止过拟合
  2. 每一步的残差计算其实变相地增大了分错instance的权重,而已经分对的instance则趋向于0
  • GBDT的分类算法从思想上和GBDT的回归算法没有区别,但是由于样本输出不是连续的值,而是离散的类别,导致我们无法直接从输出类别去拟合类别输出的误差

  • 为了解决这个问题,主要由两个方法

    • 一种是用指数损失函数,此时GBDT退化成Adaboost算法;
    • 另一种方法是用类似于逻辑回归的对数似然损失函数的方法,也就是说,我们用的类别的预测概率值和真实概率值的差(数值从0到1的预测)来拟合损失

    L ( y , f ( x ) ) = e x p [ − y f ( X ) ] L ( θ ) = − y i log ⁡ y i ^ − ( 1 − y i ) log ⁡ ( 1 − y ^ i ) L(y,f(x))=exp[-yf(X)]\\ L(\theta)=-y_i\log\hat{y_i}-(1-y_i)\log(1-\hat{y}_i) L(y,f(x))=exp[yf(X)]L(θ)=yilogyi^(1yi)log(1y^i)

编程实践

——GBDT分类

from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import pandas as pd

data_url='iris_train.csv'
df=pd.read_csv(data_url)

X=df.iloc[:,1:5]
y=df.iloc[:,5]

X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=0)
clf=GradientBoostingClassifier(n_estimators=100,learning_rate=1.0,max_depth=1,random_state=0)
clf.fit(X_train,y_train)

——GBDT回归

import imp
from multiprocessing.spawn import import_main_path
import pandas as pd
from sklearn.linear_model import SGDRegressor
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

train_url='trainOX.csv'
train_data=pd.read_csv(train_url)

train_data.drop(['ID','date','hour'],axis=1,inplace=True)

X=train_data.iloc[:,0:10]
y=train_data.iloc[:,10]

X_train,X_val,y_train,y_val=train_test_split(X,y,test_size=0.2,random_state=42)

reg=make_pipeline(StandardScaler(),SGDRegressor(max_iter=1000,tol=1e-3))
reg.fit(X_train,y_train)

y_val_pre=reg.predict(X_val)

print(mean_squared_error(y_val,y_val_pre))

——XGBoost分类

from sklearn.ensemble import XGBClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import pandas as pd

data_url='iris_train.csv'
df=pd.read_csv(data_url)

X=df.iloc[:,1:5]
y=df.iloc[:,5]

X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=0)
clf=XGBClassifier()
clf.fit(X_train,y_train)

——XGBoost回归

from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from xgboost.sklearn import XGBRegressor
import pandas as pd
train_url='trainOX.csv'
train_data=pd.read_csv(train_url)

train_data.drop(['ID','date','hour'],axis=1,inplace=True)

X=train_data.iloc[:,0:10]
y=train_data.iloc[:,10]

X_train,X_val,y_train,y_val=train_test_split(X,y,test_size=0.2,random_state=42)

reg=XGBRegressor(max_depth=5,learning_rate=0.1,n_estimators=160,silent=False,objective='reg:linear')
reg.fit(X_train,X_val)

y_val_pre=reg.predict(X_val)

print(mean_squared_error(y_val,y_val_pre))

你可能感兴趣的:(AIStudy,机器学习,集成学习,python)