集成学习是机器学习中一个非常重要且热门的分支,是用多个弱分类器构成一个强分类器,其哲学思想是“三个臭皮匠赛过诸葛亮”。一般的弱分类器可以由决策树,神经网络,贝叶斯分类器,K-近邻等构成。
常见的集成学习框架有三种:Bagging,Boosting 和 Stacking
集成学习的算法理论总的来说是比较成熟了,我们在这里就不当搬运工,对于集成学习算法感兴趣的读者可以移步:https://blog.csdn.net/perfect1t/article/details/83684995
集成学习的推导可以说是写的比较详细了
公式推导其实是一个复杂而且难受的过程,因此我们想用简单的语言对其进行描述,同时附上代码部分。
通过资料查询,我们集成学习主要包括如下几个方面。
基础集成技术
-最大投票(Max Voting)法
-平均(Averaging)法
-加权平均(Weighted Average)法
高级集成技术
-堆叠(Stacking)
-混合(Blending)
-Bagging
-提升(Boosting)
-基于Bagging和Boosting的算法
-Bagging meta-estimator
-随机森林
-AdaBoost
-GBM
-XGB
-Light GBM
-CatBoost
一、简单集成技术
1.1 最大投票法
最大投票方法通常用于分类问题。这种技术中使用多个模型来预测每个数据点。每个模型的预测都被视为一次“投票”。大多数模型得到的预测被用作最终预测结果。
例如,当你让5位同事评价你的电影时(最高5分); 我们假设其中三位将它评为4,而另外两位给它一个5。由于多数人评分为4,所以最终评分为4。你可以将此视为采用了所有预测的众数(mode)。
最大投票的结果有点像这样:
这里x_train由训练数据中的自变量组成,y_train是训练数据的目标变量。验证集是x_test(自变量)和y_test(目标变量)
model1 = tree.DecisionTreeClassifier()
model2 = KNeighborsClassifier()
model3= LogisticRegression()
model1.fit(x_train,y_train)
model2.fit(x_train,y_train)
model3.fit(x_train,y_train)
#使用3个模型训练数据
pred1=model1.predict(x_test)
pred2=model2.predict(x_test)
pred3=model3.predict(x_test)
final_pred = np.array([])
for i in range(0,len(x_test)):
final_pred =np.append(final_pred, mode([pred1[i], pred2[i], pred3[i]]))
当然上面演示的过程相当的通俗易懂
正常我们也不会这么用...一般会用sklearn中使用“VotingClassifier”模块
from sklearn.ensemble import VotingClassifier
model1 = LogisticRegression(random_state=1)
model2 = tree.DecisionTreeClassifier(random_state=1)
model = VotingClassifier(estimators=[('lr', model1), ('dt', model2)], voting='hard')
model.fit(x_train,y_train)
model.score(x_test,y_test)
2.1 平均数法
类似于最大投票技术,这里对每个数据点的多次预测进行平均。在这种方法中,我们从所有模型中取平均值作为最终预测。这种方法相当于就是取平均值
例如,在下面的情况中,平均法将取所有值的平均值。
即(5 + 4 + 5 + 4 + 4)/ 5 = 4.4
model1 = tree.DecisionTreeClassifier()
model2 = KNeighborsClassifier()
model3= LogisticRegression()
model1.fit(x_train,y_train)
model2.fit(x_train,y_train)
model3.fit(x_train,y_train)
pred1=model1.predict_proba(x_test)
pred2=model2.predict_proba(x_test)
pred3=model3.predict_proba(x_test)
finalpred=(pred1+pred2+pred3)/3 #取平均值
2.3 加权平均法
这是平均法的扩展。为所有模型分配不同的权重,定义每个模型的预测重要性。例如,如果你的两个同事是评论员,而其他人在这方面没有任何经验,那么与其他人相比,这两个朋友的答案就更加重要。
计算结果为[(5 * 0.23)+(4 * 0.23)+(5 * 0.18)+(4 * 0.18)+(4 * 0.18)] = 4.41。
model1 = tree.DecisionTreeClassifier()
model2 = KNeighborsClassifier()
model3= LogisticRegression()
model1.fit(x_train,y_train)
model2.fit(x_train,y_train)
model3.fit(x_train,y_train)
pred1=model1.predict_proba(x_test)
pred2=model2.predict_proba(x_test)
pred3=model3.predict_proba(x_test)
finalpred=(pred1*0.3+pred2*0.3+pred3*0.4)
二、高级集成技术
简单集成技术只是将多个模型数据进行简单的求平均值等操作,并没有将数据的特性全部进行利用,因此就引进了高级集成技术,通过不同的手段对数据集进行处理。
2.1 Stacking
我们来看看堆叠的官方解释:
堆叠泛化是一种用于最小化一个或多个泛化器的泛化误差率的方法。它通过推导泛化器相对于所提供的学习集的偏差来发挥其作用。这个推导的过程包括:在第二层中将第一层的原始泛化器对部分学习集的猜测进行泛化,以及尝试对学习集的剩余部分进行猜测,并且输出正确的结果。当与多个泛化器一起使用时,堆叠泛化可以被看作是一个交叉验证的复杂版本,利用比交叉验证更为复杂的策略来组合各个泛化器。当与单个泛化器一起使用时,堆叠泛化是一种用于估计(然后纠正)泛化器的错误的方法,该泛化器已经在特定学习集上进行了训练并被询问了特定问题。
通俗一点讲就是:
第一步:把训练集分成10份
第二步:基础模型(假设是决策树)在其中9份上拟合,并对第10份进行预测。
第三步:对训练集上的每一份如此做一遍。
第四步:然后将基础模型(此处是决策树)拟合到整个训练集上。
第五步:使用此模型,在测试集上进行预测。
第六步:对另一个基本模型(比如knn)重复步骤2到4,产生对训练集和测试集的另一组预测。
第七步:训练集预测被用作构建新模型的特征。
第八步:该新模型用于对测试预测集进行最终预测。
def Stacking(model,train,y,test,n_fold):
folds=StratifiedKFold(n_splits=n_fold,random_state=1)
test_pred=np.empty((test.shape[0],1),float)
train_pred=np.empty((0,1),float)
for train_indices,val_indices in folds.split(train,y.values):
x_train,x_val=train.iloc[train_indices],train.iloc[val_indices]
y_train,y_val=y.iloc[train_indices],y.iloc[val_indices]
model.fit(X=x_train,y=y_train)
train_pred=np.append(train_pred,model.predict(x_val))
test_pred=np.append(test_pred,model.predict(test))
return test_pred.reshape(-1,1),train_pred
model1 = tree.DecisionTreeClassifier(random_state=1) #决策树
test_pred1 ,train_pred1=Stacking(model=model1,n_fold=10, train=x_train,test=x_test,y=y_train)
train_pred1=pd.DataFrame(train_pred1)
test_pred1=pd.DataFrame(test_pred1)
model2 = KNeighborsClassifier()
test_pred2 ,train_pred2=Stacking(model=model2,n_fold=10,train=x_train,test=x_test,y=y_train)
train_pred2=pd.DataFrame(train_pred2)
test_pred2=pd.DataFrame(test_pred2)
df = pd.concat([train_pred1, train_pred2], axis=1)
df_test = pd.concat([test_pred1, test_pred2], axis=1)
model = LogisticRegression(random_state=1)
model.fit(df,y_train)
model.score(df_test, y_test)
我们通过下图就可以将这个过程看的的很清楚,将2个模型所预测的结果进行逻辑回归输出为最终结果
2.2 Bagging
Bagging算法 (英语:Bootstrap aggregating,引导聚集算法),又称装袋算法,是机器学习领域的一种团体学习算法。Bagging算法可与其他分类、回归算法结合,提高其准确率、稳定性的同时,通过降低结果的方差,避免过拟合的发生。 给定一个大小为n的训练集 D,Bagging算法从中均匀、有放回地(即使用自助抽样法)选出m个大小为 n'的子集 D_{i},作为新的训练集。在这 m个训练集上使用分类、回归等算法,则可得到 m个模型,再通过取平均值、取多数票等方法,即可得到Bagging的结果
Bagging背后的想法是结合多个模型的结果(例如,所有决策树)来获得泛化的结果。
接下来看看代码部分
2.2.1Bagging meta-estimator
from sklearn.ensemble import BaggingClassifier
from sklearn import tree
model = BaggingClassifier(tree.DecisionTreeClassifier(random_state=1))
model.fit(x_train, y_train)
model.score(x_test,y_test)
#这里选择的是默认参数,里面还有很多部分可以调动
2.2.2random decision forests
from sklearn.ensemble import RandomForestClassifier
model= RandomForestClassifier(random_state=1)
model.fit(x_train, y_train)
model.score(x_test,y_test)
参数:
n_estimators
- 定义随机森林中要创建的决策树数量
criterion - 定义了分割用的函数
max_features - 定义了每个决策树中可用于分割的最大特征数量
max_depth - 随机森林有多个决策树,此参数定义树的最大深度
min_samples_split - 用于在尝试拆分之前定义叶节点中所需的最小样本数
- 如果样本数小于所需数量,则不分割节点
min_samples_leaf - 定义了叶子节点所需的最小样本数
max_leaf_nodes - 此参数指定每个树的最大叶子节点数
n_jobs - 这表示并行运行的作业数
random_state - 此参数用于定义随机选择
2.3Boosting
Boosting是一种主要用于减少偏差的机器学习集成元算法,也是监督学习的一个变化,是一种将弱学习器转换为强学习器的机器学习算法家族。
Boosting算法的工作机制是首先从训练集用初始权重训练出一个弱学习器1,根据弱学习的学习误差率表现来更新训练样本的权重,使得之前弱学习器1学习误差率高的训练样本点的权重变高,使得这些误差率高的点在后面的弱学习器2中得到更多的重视。然后基于调整权重后的训练集来训练弱学习器2.,如此重复进行,直到弱学习器数达到事先指定的数目T,最终将这T个弱学习器通过集合策略进行整合,得到最终的强学习器。
简单理解即为:
Boosting是一个顺序过程,每个后续模型都会尝试纠正先前模型的错误。后续的模型依赖于之前的模型。接下来一起看看boosting的工作方式:
第一步:从原始数据集创建一个子集。
第二步:最初,所有数据点都具有相同的权重。
第三步:在此子集上创建基础模型。
第四步:该模型用于对整个数据集进行预测
第五步:使用实际值和预测值计算误差。
第六步:预测错误的点获得更高的权重。(这里,三个错误分类的蓝色加号点将被赋予更高的权重)
第七步:创建另一个模型并对数据集进行预测(此模型尝试更正先前模型中的错误)。
第八步:类似地,创建多个模型,每个模型校正先前模型的错误。
第九步:最终模型(强学习器)是所有模型(弱学习器)的加权平均值。
接下来看看代码部分
2.3.1AdaBoost
from sklearn.ensemble import AdaBoostClassifier
model = AdaBoostClassifier(random_state=1)
model.fit(x_train, y_train)
model.score(x_test,y_test)
2.3.2GBDT
from sklearn.ensemble import GradientBoostingClassifier
gbr = GradientBoostingClassifier(n_estimators=3000, max_depth=2, min_samples_split=2, learning_rate=0.1)
gbr.fit(x_train, y_train)
gbr.score(x_test,y_test)
2.3.3Light GBM
import lightgbm as lgb
train_data=lgb.Dataset(x_train,label=y_train)
params = {'learning_rate':0.001}
model= lgb.train(params, train_data, 100)
from sklearn.metrics import mean_squared_error
rmse=mean_squared_error(y_pred,y_test)**0.5
2.3.4XGBoost
import xgboost as xgb
model=xgb.XGBClassifier(random_state=1,learning_rate=0.01)
model.fit(x_train, y_train)
model.score(x_test,y_test)
参考:
https://www.jiqizhixin.com/articles/2018-07-28-3