活动地址:优快云21天学习挑战赛
Bagging分类
- 三个臭皮匠顶一个诸葛亮
步骤:
- 选取多个样本集合
- 建立多个分类器
- 组合投票
- 如何选择样本集合
- 样本非常大,平均分配样本
- 样本规模本身很小——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=(1−n1)n=e1一个样本不被采样到的概率是(1−n1)因此不被采样到的样本,当n趋于正无穷时,约等于e1,约等于37%
也就是说,样本训练集中,约37%的错误训练集将被忽略掉,提高训练集的质量
特点
- 保证了每个分类器样本的规模
- 一定程度上忽略了错误训练集的规模,提高了训练集的质量
- 弱分类器有差异性
- 弱分类器有相同见解
集成分类器预测错误的概率: 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)/2∑m[mi]r′(1−r)m−1
单分类器的条件
-
通过集成学习提高分类器的整体泛化能力是有条件的
-
分类器之间应该具有差异性
即相关性很弱
-
分类器的精度,每个个体分类器的分类精度都必须大于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的选择
- 经验法(Square Root):根据特征的数目开根号
- 网格搜索法调参GridSearch
- 决策树的数目——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=learnaweakclassifierbasedonweights−calculateweightederrorforthisclassifier(加权分类误差)εk=i=1∑nωi∗1[labeli=classifierk(xi)]−calculate“score”forthisclassifier(分类器的系数)αk=21log(εi1−εi)−changetheexampleweights(权值的更新)wi=Z1wiexp(−αk∗labeli∗classifierk(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=1∑MαmGm(x)∙指数损失函数:L(y,f(x))=exp[−yf(x)]∙公式推导:1.已知fm(x)=fm−1(x)+αmGm(x)2.公式代入:将fm(x)=fm−1(x)+αmGm(x)代入损失函数得L(y,f(x))=i=1∑Nexp(−yi(fm−1(x)+αmGm(x)))3.求导得:αk=21log(εi1−εi)
算法特点
- 对数据依赖度很高,容易过拟合
- 对噪音数据敏感
编程实践
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是把所有树的结论累加起来做最终结论的,所以可以想到每棵树的结论并不是房价本身,而是房价的一个累加值
- 每一棵树学的是之前所有树结论和的残差,这个残差就是一个加预测值后能得到的真实值的累加量
算法特点
- 防止过拟合
- 每一步的残差计算其实变相地增大了分错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^−(1−yi)log(1−y^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))