哈喽,我是小白~
之前,咱们分享了关于集成算法的总结,总共是十大集成算法,这里跳转可以查看~
今天咱们来详细的和大家分享:提升法。
如果需要本文PDF版本的同学,文末获取~
另外,文末有总结性的干货~
一起来看下具体细化内容~
提升法 是什么?
「集成算法」是一种通过组合多个模型来提升整体预测效果的技术,其中「提升法」(Boosting)是一种常见且有效的集成算法。提升法的核心思路是:让一系列简单的模型(通常是弱模型,例如决策树)一个接一个地进行学习,每次学习都重点关注之前模型犯错的地方,从而逐步提升整体模型的表现。
提升法的工作流程
提升法一般分为多个“轮次”,每一轮都会根据前一轮的结果来更新模型。
提升法基本步骤:
1. 初始化权重:最初,每个数据点都赋予相同的权重。
2. 训练弱模型:在当前的权重下训练一个弱模型,得到它的预测结果。
3. 调整权重:根据弱模型的表现来调整数据点的权重。模型预测错误的数据点权重会增加,模型预测正确的数据点权重会减少。
4. 迭代过程:重复步骤 2 和步骤 3,一轮接一轮地训练新的弱模型,每次都在强调“难以预测”的数据点。
5. 组合模型:将所有弱模型的预测结果进行加权组合,得到最终的预测结果。
举例:小学生投篮比赛
假设有一个小学篮球投篮比赛,比赛规则是这样的:
每个学生投篮10次,教练需要预测每个学生的总得分(假设每次投中得1分)。 教练的目的是训练一个模型,可以在下次比赛中预测学生的总得分。 假设教练找到了三名小学员作为「弱模型」,分别由他们给出投篮得分的预测。
第一步:初始预测
假设教练一开始每个学员都随机地预测学生的投篮得分。例如,教练用「学员A、学员B、学员C」分别给出一些分数预测。
真实得分是 [8, 3, 5]
(假设三个学生的实际得分分别是8分、3分和5分)。
初始的预测值假设是:
学员A预测:[6, 4, 5] 学员B预测:[7, 2, 6] 学员C预测:[5, 5, 4]
于是,教练的初始预测值可以通过简单投票取平均得到,比如初始预测为 [6, 4, 5]
。
第二步:计算误差
教练会观察每个学员的预测和实际得分之间的差距,计算每个人的误差。
学员A的误差:[8-6, 3-4, 5-5] = [2, -1, 0]
学员B的误差:[8-7, 3-2, 5-6] = [1, 1, -1]
学员C的误差:[8-5, 3-5, 5-4] = [3, -2, 1]
发现预测得分与真实得分之间有误差。提升法的目标就是根据这些误差来调整权重和重点关注错误较大的部分。
第三步:调整权重并重新训练
在提升法中,误差大的数据点(比如预测误差高的学生)会被赋予更高的权重,在下轮训练中会特别关注这些得分。
例如,对误差大的学员C,下一轮可能会对学员C的预测更重视,比如设定更高的权重,使学员C的预测对总结果的贡献变大。 在第二轮训练中,模型会根据权重重新组合学员A、B、C的预测,尝试更加接近真实得分 [8, 3, 5]
。
第四步:综合每轮模型
每一轮模型的预测结果根据权重累加,例如:
假设第一轮组合结果为 [6, 4, 5]
第二轮组合结果(调整权重后)为 [7, 3, 5]
最后将这几轮的结果按比例累加,得到最终预测 [7.5, 3.2, 5]
,更接近真实值[8, 3, 5]
。
简单总结提升法的特点
提升法的核心是「纠错」,每一轮的预测会根据上一次的错误进行调整。 每次重点关注上轮误差大的数据点,使得模型逐步改善。 通过多轮叠加,最终模型的准确性会比单独一个弱模型要高得多。
公式解析
提升法(Boosting)最经典的形式之一是 AdaBoost(Adaptive Boosting),它利用加权组合的方式,让多个弱模型共同提高整体预测效果。以下是 AdaBoost 算法的详细数学公式推导。
1. 提升法的基本思想
提升法的目标是通过一系列弱分类器 的加权组合来构建一个强分类器 ,使得强分类器的错误率尽可能低。假设我们有一个训练数据集 ,其中 是第 个样本的特征, 是其标签。
提升法的最终模型可以表示为:
其中:
是弱分类器的数量; 是第 轮训练得到的弱分类器; 是第 个弱分类器的权重,代表了该分类器在最终预测中所占的权重。
2. AdaBoost 算法步骤
AdaBoost 算法的主要步骤如下:
1. 初始化样本权重 :将每个样本的权重设为相等,即
2. 迭代训练弱分类器:对于每一轮 :
使用权重分布 训练一个弱分类器 ,使得其在分布 上的错误率最小。 计算弱分类器 的误差率 :
其中 是指示函数,若括号内为真则取1,否则取0。
计算该分类器的权重 :
越大表示该分类器在最终模型中的权重越大。
更新样本权重 :根据弱分类器的误差调整样本的权重,使得被误分类的样本权重增加,被正确分类的样本权重减少,以便下一轮更关注错分的样本。更新公式为:
其中 是归一化因子,确保 是一个概率分布:
这里的 会放大误分类样本的权重,因为当 时, 变大,反之则变小。
3. 最终模型:将所有的弱分类器加权组合,得到最终的强分类器 :
3. 数学推导过程
弱分类器权重 的推导
的定义是通过最小化分类错误概率来确定的。假设 是第 个弱分类器的预测结果,则误分类的概率可以定义为:
我们希望最小化这个误分类概率。AdaBoost 的设计通过最小化指数损失(exponential loss)实现目标。指数损失定义为:
通过对 求导并使其为 0,可以得出:
这表明,误差越小的弱分类器将获得更大的权重,使其在最终决策中起到更重要的作用。
样本权重 的更新推导
在每轮迭代中,误分类的样本权重会增加,因此误分类的样本在下一轮中得到更大的关注。更新样本权重的公式为:
这个更新公式有以下几个特征:
若样本 被正确分类,则 ,使得 较小,从而 也会较小。 若样本 被误分类,则 ,使得 较大,从而 会增大。
4. 算法的直观解释
通过引入权重,AdaBoost 将注意力逐步集中在难以分类的样本上,每轮训练都会重点关注上次分错的样本。最终模型是多个弱模型的加权组合,其中每个弱模型的权重与其分类精度成正比,因此整体模型可以有更好的效果。
优缺点和适用场景
提升法(Boosting)作为一种强大的集成学习方法,在实际应用中具有多种优缺点和特定的适用场景。我们将这些内容以及「自回归积分滑动平均」(ARIMA)模型的典型案例分别进行详细说明。
提升法的优缺点
优点
1. 提高准确性:提升法通过逐步纠错,将多个弱模型组合成一个强模型,因此通常能够取得较高的预测精度,尤其适用于二分类和回归问题。
2. 减少偏差:与其他集成方法(如随机森林)相比,提升法更倾向于减少偏差。这使得它在有监督的学习中表现良好,尤其适用于那些单一模型效果较差的情况。
3. 自动关注难分类样本:提升法在训练时自动给误分类样本分配更高的权重,模型的更新方向更关注难分类样本,能够有效处理非均匀分布的数据。
4. 模型的灵活性:提升法可以与多种弱模型结合使用,且常见的提升算法(如 AdaBoost、Gradient Boosting)都有较成熟的实现和应用。
缺点
1. 容易过拟合:提升法在训练时会反复关注误分类样本,这样的反复迭代有可能导致模型过拟合,特别是在训练数据包含噪声时。
2. 计算成本高:由于提升法是逐轮训练模型,需要多次训练和调整,因此计算开销较大,在大规模数据集上可能会有一定的局限性。
3. 对参数较敏感:提升法的表现依赖于超参数的设置,如迭代次数、学习率等。超参数调整的难度较高,往往需要多次实验或使用自动调参方法。
4. 难以并行化:提升法的每一轮训练依赖于前一轮的结果,这种串行特性使得其在并行计算方面不如随机森林等集成算法友好。
提升法的适用场景
1. 分类任务:提升法在二分类和多分类问题中表现优异,如垃圾邮件分类、信用卡欺诈检测等问题。
2. 回归问题:对于预测连续值的问题,提升法也能取得较好效果。例如在房价预测、股票价格预测等场景中,Gradient Boosting 是常用方法。
3. 处理类别不平衡数据:提升法会自动调整权重,对难分类样本更关注,因此在类别不平衡的问题上具有良好的适应性。
4. 特征噪声较低的情境:在数据质量较高,且无明显噪声的情境下,提升法能够有效减小偏差,提升整体模型性能。
完整案例
我们生成一个带趋势和季节性的虚拟数据集,使用 AdaBoost 回归模型对数据进行预测,并绘制多个图形来展示预测结果和模型表现。
案例背景
假设我们有 5 年的月度销售额数据。我们使用 AdaBoost 回归模型来预测未来的销售趋势。
完整代码
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.ensemble import AdaBoostRegressor
from sklearn.tree import DecisionTreeRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
# 设置随机种子以保证结果可重复
np.random.seed(42)
# 1. 生成虚拟月度销售数据
months = pd.date_range(start='2019-01-01', periods=5 * 12, freq='M')
trend = np.linspace(100, 500, len(months)) # 假设一个线性增长趋势
seasonal = 50 * np.sin(np.linspace(0, 20, len(months))) # 加入季节性波动
noise = 30 * np.random.normal(size=len(months)) # 加入噪声
sales = trend + seasonal + noise # 组合成销售额数据
# 构建 DataFrame
data = pd.DataFrame({'Month': months, 'Sales': sales})
data['Month_num'] = np.arange(len(data)) # 用月度数字代替时间序列
# 2. 数据可视化:绘制销售额的时间序列图
plt.figure(figsize=(14, 6))
sns.lineplot(x='Month', y='Sales', data=data, marker="o", color="dodgerblue", linewidth=2.5)
plt.title('Monthly Sales with Trend and Seasonality', fontsize=16, color="darkblue")
plt.xlabel('Month')
plt.ylabel('Sales')
plt.grid(True)
plt.show()
# 3. 数据拆分:划分训练集和测试集
X = data[['Month_num']]
y = data['Sales']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)
# 4. 使用 AdaBoost 进行提升法回归
base_estimator = DecisionTreeRegressor(max_depth=4) # 使用浅层决策树作为基学习器
model = AdaBoostRegressor(base_estimator=base_estimator, n_estimators=100, learning_rate=0.5, random_state=42)
model.fit(X_train, y_train)
# 预测结果
y_pred_train = model.predict(X_train)
y_pred_test = model.predict(X_test)
# 5. 模型表现:计算均方误差
train_rmse = mean_squared_error(y_train, y_pred_train, squared=False)
test_rmse = mean_squared_error(y_test, y_pred_test, squared=False)
print(f"Train RMSE: {train_rmse:.2f}")
print(f"Test RMSE: {test_rmse:.2f}")
# 6. 预测结果可视化
plt.figure(figsize=(14, 6))
# 原始数据
sns.lineplot(x=data['Month'], y=data['Sales'], label='Actual Sales', color='coral', linewidth=2)
# 训练集预测
sns.lineplot(x=data['Month'][:len(y_pred_train)], y=y_pred_train, label='Train Prediction', linestyle="--", color='lime')
# 测试集预测
sns.lineplot(x=data['Month'][len(y_pred_train):], y=y_pred_test, label='Test Prediction', linestyle="--", color='magenta')
plt.title('Sales Prediction using AdaBoost Regression', fontsize=16, color="darkgreen")
plt.xlabel('Month')
plt.ylabel('Sales')
plt.legend()
plt.grid(True)
plt.show()
# 7. 可视化残差分析
residuals = y_train - y_pred_train
plt.figure(figsize=(14, 6))
sns.histplot(residuals, kde=True, color="purple", bins=20)
plt.title('Residuals of Training Set', fontsize=16, color="purple")
plt.xlabel('Residuals')
plt.ylabel('Frequency')
plt.grid(True)
plt.show()
# 8. 误差趋势图
plt.figure(figsize=(14, 6))
sns.scatterplot(x=data['Month'][:len(y_pred_train)], y=residuals, color="dodgerblue", s=50, label="Residuals")
plt.axhline(0, color='red', linestyle='--')
plt.title('Residuals over Time (Training Set)', fontsize=16, color="blue")
plt.xlabel('Month')
plt.ylabel('Residual')
plt.legend()
plt.grid(True)
plt.show()
1. 数据生成:构造了包含趋势、季节性和噪声的虚拟销售数据,并将数据转化为 DataFrame 格式。
2. 数据可视化:绘制销售额的时间序列图,以展示销售数据的趋势和季节性波动。
3. 数据拆分:将数据分为训练集和测试集,便于模型验证。
4. AdaBoost 回归模型:使用基于浅层决策树的 AdaBoost 回归模型来拟合和预测销售数据。
5. 模型表现评估:通过计算 RMSE 来评估模型在训练集和测试集上的表现。
6. 预测结果图:展示原始数据、训练集预测结果和测试集预测结果的曲线图,用于对比模型效果。
7. 残差分析图:残差分布图帮助了解模型的拟合质量,是否存在偏差。
8. 误差趋势图:绘制残差随时间的分布趋势,观察模型误差是否存在系统性偏差。
数据分析图表
1. 时间序列图:展示销售数据的整体趋势和周期性波动,便于观察数据的变化模式。
2. 预测结果图:对比真实值与预测值的趋势,观察模型对训练集和测试集的拟合效果。
3. 残差分析图:残差的分布集中性和对称性可以反映模型的误差分布情况。
4. 误差趋势图:显示残差在时间维度的分布,帮助检查模型在不同时间点的误差情况。
最后