【自学笔记】过拟合与正则化

过拟合

  分类任务的本质其实是找到边界,将不同类型的数据区分开,之前我们做的是尽量让这个边界更贴近每一个数据点,达到拟合的作用。
  然而,极端数据的存在或要求模型的特征数过多,会导致过拟合现象的出现。它会导致模型在训练集表现优异,但是在测试集准确率不高,这显然不是我们想要的。

在这里插入图片描述

术语“偏置(Bias)”和“方差(Variance)”

  偏置描述了学习算法的期望预测与真实结果之间的偏差。高偏置欠拟合成正比。
  方差表示模型预测结果的波动程度,即模型在不同训练集上的预测值的变化程度。高方差过拟合成正比。

偏置-方差权衡(Bias-Variance Tradeoff)

  要控制模型的偏置和方差,避免欠拟合和过拟合的出现。

正则化

  正则化的本质是引入额外信息(偏置)来惩罚极端的参数值。
  常见的L1,L2正则化就是在代价函数末尾加上关于w的式子,使w过大时代价函数也会过大。

L1正则化

J ( w ⃗ ) = J 0 ( w ⃗ ) + λ ∑ j = 1 m ∣ w j ∣ J(\vec{w}) = J_{0}(\vec{w}) + \lambda\sum_{j=1}^{m}|w_{j}| J(w )=J0(w )+λj=1mwj
其中 J 0 J_{0} J0是原代价函数, λ \lambda λ为正则化参数
一般将 ∑ j = 1 m ∣ w j ∣ \sum_{j=1}^{m}|w_{j}| j=1mwj记作 ∣ ∣ w ⃗ ∣ ∣ 1 ||\vec{w}||^{1} ∣∣w 1

L2正则化

J ( w ⃗ ) = J 0 ( w ⃗ ) + λ ∑ j = 1 m w j 2 J(\vec{w}) = J_{0}(\vec{w}) + \lambda\sum_{j=1}^{m}w_{j}^{2} J(w )=J0(w )+λj=1mwj2
一般将 ∑ j = 1 m w j 2 \sum_{j=1}^{m}w_{j}^{2} j=1mwj2记作 ∣ ∣ w ⃗ ∣ ∣ 2 ||\vec{w}||^{2} ∣∣w 2

L1和L2的区别

  L2正则化会让高次项系数趋于0,而L1正则化则会让其变成0,减少空间消耗和特征数。故在对模型稀疏度要求较高的情况下选择L1。

  L1正则化函数不平滑,可能会导致优化更复杂;当特征有高度相关性时,L1正则化可能会使选择的特征不唯一。
  举个例子:假设我们有两个特征 X 1 X_{1} X1 X 2 X_{2} X2,它们之间的相关系数接近1,即它们几乎完全线性相关。
  假设模型的目标函数(包括L1正则化项)为:

L = ∑ ( y − z ) 2 + λ ( ∣ w 1 ∣ + ∣ w 2 ∣ ) L = \sum(y-z)^{2} + \lambda(|w_{1}| + |w_{2}|) L=(yz)2+λ(w1+w2)

  由于 X 1 X_{1} X1 X 2 X_{2} X2相关,模型可以通过调整 w 1 w_{1} w1 w 2 w_{2} w2来同时减小 L 的前半部分(预测误差),并且由于L1正则化项的存在,模型可能倾向于将其中一个权重设置为零。然而,由于 X 1 X_{1} X1 X 2 X_{2} X2的高度相关性,选择 w 1 w_{1} w1 w 2 w_{2} w2的非零值可能不会对模型的整体性能产生显著影响,从而导致特征的选择不唯一。

代码实现改变权重系数来控制模型正则化

  前置代码略,以下代码通过改变 λ \lambda λ直观展示正则化对模型系数的影响。

# 数据读入略
from sklearn.linear_model import LogisticRegression  # 逻辑回归分类器

# 初始化权重和参数列表
weights, params = [], []

# 遍历对数尺度上的C参数范围 (10^-5 到 10^5)

for c in np.arange(-5, 5):
    # 创建逻辑回归模型实例,设置C参数(正则化强度的倒数)
    # C越大,正则化强度越低;C越小,正则化强度越高
    lr = LogisticRegression(C=10.**c, random_state=1,
                            solver='lbfgs',  # 使用L-BFGS-B算法求解
                            multi_class='ovr')  # 多分类问题采用one-vs-rest策略

    # 使用标准化后的训练数据和标签训练模型
    lr.fit(X_train_std, y_train)
    # 将模型的权重系数保存到列表中

    weights.append(lr.coef_[1])
    # 将C参数的值保存到列表中
    params.append(10.**c)

# 将权重列表转换成numpy数组,便于后续操作
weights = np.array(weights)

# 使用matplotlib绘制权重系数随C参数变化的图像
plt.plot(params, weights[:, 0],
         label='petal length')  # 绘制花瓣长度的权重变化
plt.plot(params, weights[:, 1], linestyle='--',
         label='petal width')  # 绘制花瓣宽度的权重变化,使用虚线表示

# 设置图表的y轴标签为权重系数
plt.ylabel('weight coefficient')
# 设置图表的x轴标签为C参数
plt.xlabel('C')
# 设置图例位置在左上角
plt.legend(loc='upper left')
# 设置x轴为对数尺度,以清晰展示C参数的范围
plt.xscale('log')

# 展示图表

plt.show()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值