机器学习(12)-集成学习

集成学习

集成学习(Ensemble Learning),归属于机器学习,是一种“训练思路”,并不是某种具体的方法或者算法。 集成学习通过构建并结合多个学习器来完成学习任务,其核心思路就是“人多力量大”,其并没有创造出新的算法,而是把已有的算法进行结合,从而得到更好的效果。

集成学习的一般结构为:先产生一组“个体学习器”,再用某种策略将它们结合起来。集成中只包含同种类型的个体学习器,称为同质,当中的个体学习器亦称为“基学习器”,相应的算法称为“基学习算法”。集成中包含不同类型的个体学习器,称为“异质”,当中的个体学习器称为“组建学习器”。

要获得好的集成,个体学习器应“好而不同”,即个体学习器要有一定的“准确性”,即学习器不能太坏,并且要有多样性,即个体学习器间具有差异。

根据个体学习器的生成方式,目前的集成学习方法大致可以分为两类:

  • 个体学习器间不存在强依赖关系、可同时生成的并行化方法,代表为Bagging(bootstrap aggregating)和随机森林。
  • 个体学习器间存在强依赖关系、必须串行生成的序列化方法,代表为Boosting;

所谓串行生成的序列化方法,就是除了训练第一个之外,其他的学习器学习都需要依赖于前面生成的学习的结果。

Boosting

Boosting是一簇可将弱学习器提升为强学习器的算法。 Boosting由于各基学习器之间存在强依赖关系,因此只能串行处理,也就是Boosting实际上是个迭代学习的过程。

Boosting的工作机制为:先从初始训练集中训练出一个基学习器,再根据基学习器的表现对训练样本分布进行调整(比如增大被误分样本的权重,减小被正确分类样本的权重),使得先前基学习器做错的样本在后续的训练过程中受到更多关注,然后基于调整后的样本分布来训练下一个基学习器,如此重复,直到基学习器数目达到事先自定的值T,然后将这T 个基学习器进行加权结合(比如错误率小的基学习器权重大,错误率大的基学习器权重小,这样做决策时,错误率小的基本学习器影响更大)。Boosting算法的典型代表有AdaBoost和XGBoost。

AdaBoost

AdaBoost(Adaptive Boosting,自适应提升算法),其自适应在于:被前一个基本分类器误分类的样本的权值会增大,而正确分类的样本的权值会减小,并再次用来训练下一个基本分类器。同时,在每一轮迭代中,加入一个新的弱分类器,直到达到某个预定的足够小的错误率或预先指定的最大迭代次数再确定最后的强分类器。

AdaBoost 通过最小化加权指数损失来训练每个弱学习器,并通过调整样本权重来重点关注误差较大的样本。AdaBoost算法的结果函数可表示为

其中ht(x) 是编号为 t 的基分类器给 x 的预测标记,α(x) 是该基分类器的权重。

算法的目标函数采用指数损失函数

f(x) 为真实函数,对于样本 x , f(x) ∈ {+1, −1} ,只能取 +1 和 −1,而 H(x) 是一个实数。

AdaBoost 不直接采用梯度下降法来优化损失函数,但其过程可以视作一种特殊的梯度下降形式。具体来说,在每一轮中选择弱学习器以最小化当前所有样本的加权指数损失总和,这可以被看作是在损失空间中朝着减少总体误差的方向迈出的一步。 AdaBoost 展现出一种顺序训练的级联结构,后续模型的训练基于前一个模型的预测结果,形成依赖关系。这种级联方式使 AdaBoost 更专注于学习之前未能正确预测的样本,逐步优化预测性能。

XGBoost

XGBoost(eXtreme Gradient Boosting,极限梯度提升算法),是由 k 个基模型组成的一个加法模型,每一步迭代只优化当前步中的子模型,假设我们第 t 次迭代要训练的树模型是 ft(xi),则有:

Bagging

自助采样法(Bootstrap sampling)算法原理

给定包含m个样本的数据集,我们先随机取出一个样本放入采样集中,再把该样本放回初始数据集中,使得下次采用时该样本扔有可能被选中,这样经过m次随机采样操作,我们得到含有m个样本的采样集,初始数据集中有的样本多次出现,有的则从未出现。

最终,我们会发现:

初始数据集中约有36.8%的样本未出现在采样数据集中

初始数据集中约有63.2%的样本出现在采样集中

计算过程:样本在m次采样中始终不被采样到的概率为(1-1/m)^m,取极限得:

Bagging(Bootstrap Aggregating,自助集成算法),是并行式集成学习方法的典型代表,它直接基于自助采样法,思想是通过将许多相互独立的学习器的结果进行结合,从而提高整体学习器的泛化能力。

给定包含M个样本的数据集,我们先随机取出一个样本放入采样中,再把该样本放回初始数据集,使得下次采样时该样本仍有可能被选中。这样,经过M次随机采样操作,我们得到含M个样本的采样集,初始训练集中有的样本在采样集里多次出现,有的则从未出现。初始训练集中约有63.2%的样本出现在采样集中。

照这样,我们可采样出T个含M个训练样本的采样集,然后基于每个采样集训练出一个基学习器,再将这些基学习器进行结合。这就是Bagging的基本流程。在对预测输出进行结合时,Bagging通常对分类任务使用简单投票法,对回归任务使用简单平均法。若分类预测时出现两个收到同样票数的情形,则最简单的做法是随机选择一个,也可进一步考察学习器投票的置信度来确定最终胜者。

  1. 采样 设大小为 N 的样本 X。我们可以通过随机均匀的从训练集中抽取 N 个元素,作为采集池,每个元素被抽取到的概率都是1/N。假设我们一个人从一个袋子里面拿球。在每个步骤中,将所选择的球放回到袋子中,以便相应的进行下一次选择,即从相同数量的球 N 开始。请注意,因为我们将球是放回的,所以新样本中可能存在重复。我们称这个新样本为 。通过重复该过程 M 次,我们创建 M 个采集样本 。重复以上采样步骤T次,最后,我们有T个足够数量的训练集,可以计算原始分布的各种统计数据。
  2. 训练 为每一个生成的样本 ,我们都去训练一个专属于它的分类器 。这个分类器可根据具体的情况而定,可以是决策树,KNN等。
  3. 分类和回归 对于分类问题:由投票表决产生的分类结果;对于回归问题,由T个模型预测结果的均值作为最后预测的结果。

随机森林

随机森林(Random Forest, RF)是bagging的扩展体。RF在以决策树为基学习器构建Bagging集成的基础上,进一步在决策树的训练过程中引入了随机属性选择。具体地,传统决策树在选择划分属性时是在当前结点的属性集合(假定有d个属性)中选择一个最优属性,而在RF上,对基决策树的每个结点,先从该结点的属性集中随机选择其中的k个属性组成属性集,然后从该属性集中选择最优的划分属性,一般情况下,推荐k=log2 d。

Python实践-集成学习

Boosting

使用xgboost和sklearn库

import xgboost as xgb
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 加载数据集
data = load_iris()
X = data.data
y = data.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建XGBoost DMatrix
dtrain = xgb.DMatrix(X_train, label=y_train)
dtest = xgb.DMatrix(X_test, label=y_test)

# 设置参数
param = {
    'max_depth': 3,  # 树的最大深度
    'eta': 0.3,      # 学习率
    'objective': 'multi:softmax',  # 多分类任务
    'num_class': 3  # 类别数
}
num_round = 20  # 迭代次数

# 训练模型
bst = xgb.train(param, dtrain, num_round)

# 预测
preds = bst.predict(dtest)

# 计算准确率
accuracy = accuracy_score(y_test, preds)
print(f"Accuracy: {accuracy:.2f}")

# 保存模型
bst.save_model('xgboost_model.model')

# 加载模型
loaded_model = xgb.Booster()
loaded_model.load_model('xgboost_model.model')

# 使用加载的模型进行预测
loaded_preds = loaded_model.predict(dtest)
loaded_accuracy = accuracy_score(y_test, loaded_preds)
print(f"Loaded Model Accuracy: {loaded_accuracy:.2f}")

Bagging

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score

# 加载数据集
data = load_iris()
X = data.data
y = data.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建基学习器
base_estimator = DecisionTreeClassifier()

# 创建BaggingClassifier
bagging_clf = BaggingClassifier(estimator=base_estimator, n_estimators=50, random_state=42)

# 训练模型
bagging_clf.fit(X_train, y_train)

# 预测
y_pred = bagging_clf.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.2f}")

# 保存模型
import joblib
joblib.dump(bagging_clf, 'bagging_model.pkl')

# 加载模型
loaded_model = joblib.load('bagging_model.pkl')

# 使用加载的模型进行预测
loaded_preds = loaded_model.predict(X_test)
loaded_accuracy = accuracy_score(y_test, loaded_preds)
print(f"Loaded Model Accuracy: {loaded_accuracy:.2f}")

随机森林

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import pandas as pd

# 加载数据集
data = load_iris()
X = data.data
y = data.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建随机森林分类器
rf_clf = RandomForestClassifier(n_estimators=100, random_state=42)

# 训练模型
rf_clf.fit(X_train, y_train)

# 预测
y_pred = rf_clf.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.2f}")

# 输出分类报告
print("\nClassification Report:")
print(classification_report(y_test, y_pred, target_names=data.target_names))

# 输出混淆矩阵
print("\nConfusion Matrix:")
print(confusion_matrix(y_test, y_pred))

# 保存模型
import joblib
joblib.dump(rf_clf, 'random_forest_model.pkl')

# 加载模型
loaded_model = joblib.load('random_forest_model.pkl')

# 使用加载的模型进行预测
loaded_preds = loaded_model.predict(X_test)
loaded_accuracy = accuracy_score(y_test, loaded_preds)
print(f"Loaded Model Accuracy: {loaded_accuracy:.2f}")

# 输出分类结果
results = pd.DataFrame({'Actual': y_test, 'Predicted': y_pred})
results['Actual'] = results['Actual'].apply(lambda x: data.target_names[x])
results['Predicted'] = results['Predicted'].apply(lambda x: data.target_names[x])
print("\nClassification Results:")
print(results)

Reference

机器学习(西瓜书)

机器学习公式详解(南瓜书)

一文看懂集成学习(详解 bagging、boosting 以及他们的 4 点区别) (easyai.tech)

机器学习之集成学习(ensemble learning)-CSDN博客

集成学习(Ensemble Learning)简单入门_集成学习(ensemble learning)简单入门-CSDN博客

一文让你彻底理解 AdaBoost 自适应提升算法 | AdaBoost 的关键要点、基本原理、优缺点和实际应用-腾讯云开发者社区-腾讯云 (tencent.com)

Bagging算法最全解析-机器学习_bagging算法有哪些-CSDN博客

图解机器学习算法(10) | XGBoost模型最全解析(机器学习通关指南·完结)_xgboost 6 logistic regression-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值