文章目录
集成学习的确强大,从普通的决策树、树的聚合,到随机森林,再到各种Boosting 算法,很长见识。然而这些大多是基于同一种机器学习算法的集成,而且基本都是在集成决策树。我的问题是,能不能集成不同类型的机器学习算法,比如随机森林、神经网络、逻辑回归、AdaBoost等,然后优中选优,以进一步提升性能。
集成学习分为两大类
- 同质集成,就是基模型都是通过一个基础算法生成的同类型的学习器。
- 异质集成,就是把不同类型的算法集成在一起。
那么为了集成后的结果有好的表现,异质集成中的基模型要有足够大的差异性。
下面就介绍一些不同类型的模型之间相互集成的算法。
Stacking算法
先说异质集成中的Stacking(可译为堆叠)。这种集成算法还是蛮诡异的,其思路是,使用初始训练集学习若干个基模型之后,用这几个基模型的预测结果作为新的训练集的特征来训练新模型。
Stacking 算法的流程如下图所示。
这些基模型在异质类型中进行选择,比如决策树、KNN、SVM或神经网络等,都可以组合在一起。
下面是Stacking的具体步骤(如下图所示)。
(1)通常把训练集拆成K折(请大家回忆第1课中介绍过的K折验证)。
(2)利用K折验证的方法在K-1折上训练模型,在第K折上进行验证。
(3)这样训练K次之后,用训练好的模型对训练集整体进行最终训练,得到一个基模型。
(4)使用基模型预测训练集,得到对训练集的预测结果。
(5)使用基模型预测测试集,得到对测试集的预测结果。
(6)重复步骤(2)~(5),生成全部基模型和预测结果(比如 CART、KNN、SVM以及神经网络,4组预测结果)。
(7)现在可以忘记训练集和测试集这两个数据集样本了。只需要用训练集预测结果作为新训练集的特征,测试集预测结果作为新测试集的特征去训练新模型。新模型的类型不必与基模型有关联。
import numpy as np # 基础线性代数扩展包
import pandas as pd # 数据处理工具箱
df_bank = pd.read_csv("../数据集/BankCustomer.csv") # 读取文件
# 构建特征和标签集合
y = df_bank['Exited']
X = df_bank.drop(['Name', 'Exited', 'City'], axis=1)
from sklearn.model_selection import train_test_split # 拆分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=0.2, random_state=0)
from sklearn.model_selection import StratifiedKFold # 导入K折验证工具
def Stacking(model,train,y,test,n_fold): # 定义Stacking函数
folds = StratifiedKFold(n_splits=n_fold,random_state=1)
train_pred = np.empty((0,1),float)
test_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,train_pred
from sklearn.tree import DecisionTreeClassifier # 导入决策树模型
model1 = DecisionTreeClassifier(random_state=1) # model1-决策树
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)
from sklearn.neighbors import KNeighborsClassifier # 导入kNN模型
model2 = KNeighborsClassifier() # model2-kNN
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)
from sklearn.metrics import f1_score
# Stacking的实现-用逻辑回归模型预测新特征集
X_train_new = pd.concat([train_pred1, train_pred2], axis=1)
X_test_new = pd.concat([test_pred1, test_pred2], axis=1)
from sklearn.linear_model import LogisticRegression # 导入逻辑回归模型
model = LogisticRegression(random_state=1)
model.fit(X_train_new, y_train) # 拟合模型
# model.score(X_test_new, y_test) # 分数评估
print("Stacking用LR测试准确率: {:.2f}%".format(model.score(X_test_new, y_test)*100))
步骤:
- 首先定义一个函数,用来实现Stacking;
- 然后用刚才定义的Stacking函数训练两个不同类型的模型,一个是决策树模型,另一个是 KNN模型,并用这两个模型分别生成预测结果;
- 把上面的预测结果连接成一个新的特征集,标签保持不变,用回原始的标签集。最后使用逻辑回归模型对新的特征集进行分类预测:
Blending算法
再来说说Blending(可译为混合)。它的思路和Stacking几乎是完全一样的,唯一的不同之处在哪里呢?就是Blending 的过程中不进行K折验证,而是只将原始样本训练集分为训练集和验证集,然后只针对验证集进行预测,生成的新训练集就只是对于验证集的预测结果,而不是对对全部训练集的预测结果。Blending 算法的流程如下图所示。
上述这两种集成算法在机器学习实战中,虽然不是经常见到,但是也有可能会产生意想不到
参考资料:零基础学机器学习