🐰线性回归优化😜

在机器学习的领域中,线性回归作为一种基础且重要的算法,有着广泛的应用。然而,在实际运用过程中,我们常常会遇到欠拟合和过拟合的问题,它们如同拦路虎一般,影响着模型的性能。接下来,就让我们深入了解这两个问题以及如何对线性回归进行优化。

🐱‍🏍一、欠拟合与过拟合的定义

Alt text

🐻(一)过拟合

过拟合指的是一个假设在训练数据上能够获得比其他假设更好的拟合效果,但是在测试数据集上却不能很好地拟合数据。这通常是因为模型过于复杂,它努力去适应训练数据中的每一个细节,包括一些噪声,从而导致在面对新数据时缺乏泛化能力。比如,在一个预测房价的模型中,如果模型把训练数据中某几个特殊房子的独特特征(如房子旁边恰好有个独特的小雕塑)过度学习,而这些特征并非普遍影响房价的因素,那么在遇到没有这个小雕塑的房子时,模型的预测就会出现偏差。

🐼(二)欠拟合

欠拟合则是一个假设在训练数据上不能获得良好的拟合,并且在测试数据集上同样不能很好地拟合数据。原因是模型过于简单,无法捕捉到数据中的足够特征和规律。继续以房价预测为例,如果模型仅仅考虑房子的面积这一个特征,而忽略了诸如房间数量、地段等其他重要因素,那么它对房价的预测结果必然是不准确的,这就是典型的欠拟合现象。

🐥二、欠拟合与过拟合的原因及解决办法

🐶(一)欠拟合

🐹1. 原因

学习到的数据特征过少,无法全面描述数据中的规律和关系。

🐰2. 解决办法

  • 添加其他特征项:有时候模型欠拟合是因为特征项不够丰富。我们可以添加多种类型的特征,例如 “组合” 特征(如将房子的面积和房间数量组合成一个新特征,表示单位房间的平均面积)、“泛化” 特征(从一些具体特征中抽象出更宽泛的特征,如将房子所在街道名称泛化为所在区域)、“相关性” 特征(找出与房价有潜在关联的特征,如附近学校的质量)。此外,“上下文特征”(如房子所在小区的整体环境描述)、“平台特征”(如果数据来源于某个特定平台,平台相关的属性特征)等也可以作为添加的选项。
  • 添加多项式特征:在机器学习算法中,这是一种常用的手段。比如对于线性模型,我们可以通过添加二次项(如面积的平方)或者三次项(如面积的立方),让模型能够学习到更复杂的关系,从而增强模型的泛化能力。

🐱(二)过拟合

🐭1. 原因

原始特征过多,其中存在一些嘈杂的特征,导致模型过于复杂,试图去兼顾各个测试数据点,包括噪声点,从而失去了对整体数据趋势的把握。

🐮2. 解决办法

  • 重新清洗数据:数据不纯可能是导致过拟合的一个原因。如果数据中存在错误标注、异常值或者大量重复数据等杂质,模型在学习过程中可能会受到干扰,从而产生过拟合。此时,重新清洗数据,去除这些杂质,能够让模型学习到更准确的模式。
  • 增大数据的训练量:当用于训练的数据量太小,训练数据占总数据的比例过小时,模型可能无法充分学习到数据的全貌和规律,容易对训练数据中的噪声过度拟合。增加训练数据量,可以让模型看到更多的样本,从而更好地泛化到新的数据上。
  • 正则化:这是一种重要的防止过拟合的方法,通过对模型的参数进行约束,使得模型在拟合数据的同时,尽量保持简单。下面我们会详细介绍正则化的相关内容。
  • 减少特征维度:过多的特征维度可能会引发维灾难,导致模型复杂度增加和过拟合风险上升。我们可以通过一些特征选择的方法,去除那些对模型贡献不大或者相关性过高的特征,降低特征维度,提高模型的性能。

🐷三、正则化:防止过拟合的神奇魔法棒

🐸(一)什么是正则化

在解决回归过拟合问题时,我们常常会选择正则化。实际上,对于其他机器学习算法如分类算法,同样可能出现过拟合问题,除了一些算法本身具有防止过拟合的机制(如决策树通过剪枝、神经网络通过一些结构设计和训练技巧)外,我们更多时候需要自己进行特征选择。

Alt text

如何解决?

Alt text

正则化的核心思想是,在学习过程中,当数据提供的某些特征对模型复杂度有较大影响或者这些特征的数据点异常较多时,算法会尽量减少这些特征的影响,甚至删除某个特征的影响。不过需要注意的是,算法在调整时并不知道具体是哪个特征产生影响,而是通过调整参数来达到优化的结果。

🐯(二)正则化类别

🐴1. L2 正则化

  • 作用:可以使得模型中的一些权重系数 W 都变得很小,接近于 0,从而削弱某个特征的影响。例如在房价预测中,如果某个特征(如房子旁边树木的数量)对房价的影响较小,通过 L2 正则化,该特征对应的权重系数就会被调整得很小。
  • 优点:越小的参数说明模型越简单,而越简单的模型则越不容易产生过拟合现象。这是因为简单模型不会过于复杂地去拟合训练数据中的噪声和特殊情况,能够更好地捕捉数据的整体趋势,从而在新数据上有更好的泛化能力。以岭回归(Ridge Regression)为代表的模型应用了 L2 正则化。

🐵2. L1 正则化

  • 作用:可以使得其中一些权重系数 W 的值直接变为 0,相当于删除了这个特征的影响。比如在众多影响房价的特征中,如果某个特征(如房子窗户的颜色)实际上与房价并无关联,L1 正则化可能会将其对应的权重系数置为 0,从而在模型中去除这个无关特征。
  • 代表模型:LASSO 回归(Least Absolute Shrinkage and Selection Operator Regression)是应用 L1 正则化的典型模型。LASSO 回归有一个重要性质,它倾向于完全消除不重要的权重。当正则化参数 α 取值相对较大时,高阶多项式退化为二次甚至线性,即高阶多项式特征的权重被置为 0,能够自动进行特征选择,并输出一个稀疏模型(只有少数特征的权重是非零的)。

🐝四、正则化线性模型

🐛(一)岭回归(Ridge Regression,又名 Tikhonov regularization)

岭回归是线性回归的正则化版本,它在原来线性回归的代价函数中添加了正则项(regularization term)。其代价函数为:

,其中 $ MSE(\theta)$ 是均方误差,α 是正则化参数,$ \theta_{i}$是模型的权重系数。当 α = 0 时,岭回归退化为线性回归。岭回归的目的是在拟合数据的同时,使模型权重尽可能小,从而防止过拟合。在 Python 的 scikit - learn 库中,可以使用Ridge类来实现岭回归:

1
2
from sklearn.linear_model import Ridge
estimator = Ridge(alpha = 1.0, fit_intercept = True, solver = "auto", normalize = False)
  • alpha:正则化力度,也叫 λ,取值范围一般为 0~1 或 1~10 等,值越大,正则化力度越强,权重系数会越小;值越小,正则化力度越弱,权重系数会越大。
  • solver:会根据数据自动选择优化方法,例如当数据集和特征都比较大时,可以选择sag随机梯度下降优化方法。
  • normalize:数据是否进行标准化,normalize = False时,可以在fit之前调用preprocessing.StandardScaler对数据进行标准化处理。
  • Ridge.coef_:可以获取回归权重。
  • Ridge.intercept_:可以获取回归偏置。

Ridge 方法相当于 SGDRegressor (penalty=’l2’, loss=”squared_loss”),只不过 SGDRegressor 实现了一个普通的随机梯度下降学习,推荐使用 Ridge (实现了 SAG)。

另外,sklearn.linear_model.RidgeCV(_BaseRidgeCV, RegressorMixin)是具有 l2 正则化且可以进行交叉验证的线性回归。其中:

  • coef_可获取回归系数。
  • class _BaseRidgeCV(LinearModel)的初始化参数有alphas=(0.1, 1.0, 10.0)(用于指定交叉验证时尝试的不同正则化参数值),fit_intercept=True(是否计算截距),normalize=False(数据是否标准化),scoring=None(用于指定评估指标),cv=None(交叉验证折数),gcv_mode=Nonestore_cv_values=False(是否存储交叉验证的详细结果) 。
1
2
3
4
5
class _BaseRidgeCV(LinearModel):
def __init__(self, alphas=(0.1, 1.0, 10.0),
fit_intercept=True, normalize=False,scoring=None,
cv=None, gcv_mode=None,
store_cv_values=False):

🐙(二)Lasso 回归(Lasso Regression)

Lasso 回归是线性回归的另一种正则化版本,其正则项为权值向量的ℓ1 范数,代价函数为:

需要注意的是,Lasso 回归的代价函数在$\theta{i} = 0$处是不可导的。解决方法是在$ \theta{i} = 0$处用一个次梯度向量(subgradient vector)代替梯度。

Alt text

Lasso 回归具有能够自动进行特征选择的重要性质,当 α 取值相对较大时,高阶多项式退化为二次甚至线性,高阶多项式特征的权重被置为 0,输出一个稀疏模型。在 scikit - learn 库中,可以使用Lasso类来实现 Lasso 回归:

1
2
from sklearn.linear_model import Lasso
estimator = Lasso(alpha = 1.0, fit_intercept = True, normalize = False)

🐚(三)弹性网络(Elastic Net)

弹性网络是在岭回归和 Lasso 回归之间进行了折中,通过混合比(mix ratio)r 进行控制。

弹性网络的代价函数为:

  • 其中 r 是混合比。
  • 当 r = 0 时,弹性网络变为岭回归,主要通过 L2 正则化来约束权重。
  • 当 r = 1 时,弹性网络变为 Lasso 回归,主要利用 L1 正则化来筛选特征。
    弹性网络结合了岭回归和 Lasso 回归的优点,在一些情况下能够表现得更加稳定和优秀。例如在特征维度高于训练样本数,或者特征是强相关的情况下,Lasso 回归的表现可能不太稳定,此时弹性网络可能是更好的选择。

在 scikit - learn 库中,可以使用ElasticNet类来实现弹性网络:

1
2
from sklearn.linear_model import ElasticNet
estimator = ElasticNet(alpha = 1.0, l1_ratio = 0.5, fit_intercept = True, normalize = False)
  • l1_ratio:对应混合比 r,取值范围为 0~1。

一般来说,在实际应用中,我们应避免使用朴素线性回归,而应对模型进行一定的正则化处理。通常情况下,岭回归较为常用;如果假设只有少部分特征是有用的,弹性网络和 Lasso 回归是不错的选择,不过一般弹性网络的使用更为广泛,因为在一些复杂的数据情况下(如特征维度高于训练样本数,或者特征是强相关的情况),Lasso 回归的表现不太稳定。

🐠(四)Early Stopping(了解)

Early Stopping 也是正则化迭代学习的方法之一。其做法是在验证错误率达到最小值的时候停止训练。在训练模型时,随着训练的进行,模型在训练集上的误差通常会不断下降,但在验证集上的误差可能会先下降后上升,这是过拟合的一个信号。Early Stopping 通过监控验证集上的误差,当误差不再下降(或开始上升)时,就停止训练,防止模型过度拟合训练数据。虽然 scikit - learn 库中没有专门的 Early Stopping 类用于线性回归的直接实现,但在一些深度学习框架(如 TensorFlow、PyTorch)中,很容易实现 Early Stopping 机制来优化模型训练过程。

🧐观察正则化程度的变化,对结果的影响?

Alt text

  • 正则化力度越大,权重系数会越小
  • 正则化力度越小,权重系数会越大

🐣五、线性回归的改进 - 岭回归案例

下面我们通过一个具体的案例来展示岭回归在波士顿房价预测中的应用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import Ridge
from sklearn.metrics import mean_squared_error


def linear_ridgeModel():
"""
线性回归:岭回归
:return:
"""
# 1.获取数据
data = load_boston()

# 2.数据集划分
x_train, x_test, y_train, y_test = train_test_split(data.data, data.target, random_state = 22)

# 3.特征工程-标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)

# 4.机器学习-线性回归(岭回归)
estimator = Ridge(alpha = 1)
# estimator = RidgeCV(alphas=(0.1, 1, 10))
estimator.fit(x_train, y_train)

# 5.模型评估
# 5.1 获取系数等值
y_predict = estimator.predict(x_test)
print("预测值为:\n", y_predict)
print("模型中的系数为:\n", estimator.coef_)
print("模型中的偏置为:\n", estimator.intercept_)

# 5.2 评价
# 均方误差
error = mean_squared_error(y_test, y_predict)
print("误差为:\n", error)


if __name__ == "__main__":
linear_ridgeModel()

在这个案例中,我们首先加载了波士顿房价数据集,然后将其划分为训练集和测试集。接着对数据进行标准化处理,这有助于提高模型的训练效果和收敛速度。之后使用岭回归模型进行训练,并对模型进行评估,通过均方误差来衡量模型的预测准确性。

🐤六、模型的保存和加载

在机器学习中,我们常常需要保存训练好的模型,以便在后续的应用中直接加载使用,而无需重新训练。在 scikit - learn 库中,可以使用joblib工具来实现模型的保存和加载。

🐧(一)API

1
from sklearn.externals import joblib
  • 保存joblib.dump(estimator, 'test.pkl'),其中estimator是训练好的模型对象,'test.pkl'是保存模型的文件名,注意保存文件的后缀名一般是.pkl
  • 加载estimator = joblib.load('test.pkl'),通过joblib.load方法将保存的模型加载到内存中,并赋值给一个变量estimator,后续就可以使用这个模型进行预测等操作。

🐳(二)线性回归的模型保存加载案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
def load_dump_demo():
"""
模型保存和加载
:return:
"""
# 1.获取数据
data = load_boston()

# 2.数据集划分
x_train, x_test, y_train, y_test = train_test_split(data.data, data.target, random_state=22)

# 3.特征工程-标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)

# 4.机器学习-线性回归(岭回归)
# # 4.1 模型训练
# estimator = Ridge(alpha=1)
# estimator.fit(x_train, y_train)
#
# # 4.2 模型保存
# joblib.dump(estimator, "./data/test.pkl")

# 4.3 模型加载
estimator = joblib.load("./data/test.pkl")

# 5.模型评估
# 5.1 获取系数等值
y_predict = estimator.predict(x_test)
print("预测值为:\n", y_predict)
print("模型中的系数为:\n", estimator.coef_)
print("模型中的偏置为:\n", estimator.intercept_)

# 5.2 评价
# 均方误差
error = mean_squared_error(y_test, y_predict)
print("误差为:\n", error)

在这个案例中,我们可以选择先训练模型并保存,也可以直接加载已经保存好的模型进行评估。模型保存和加载功能在实际应用中非常实用,比如在生产环境中,我们可以将训练好的稳定模型保存下来,随时加载用于对新数据的预测;或者在不同的项目中复用已经训练好的模型,节省训练时间和计算资源。

🐾总结

在本次关于线性回归优化的学习中,我们深入探讨了多个关键要点:

  1. 欠拟合与过拟合:欠拟合是由于模型过于简单,对数据特征挖掘不充分,导致在训练集和测试集上都表现不佳。而过拟合则是模型过度复杂,把噪声也当作有效信息学习,在训练集上表现良好,但在测试集上效果差。针对欠拟合,可通过添加特征项(如组合、泛化、相关性等特征)或多项式特征来解决;对于过拟合,可采取清洗数据、增大训练量、运用正则化方法以及减少特征维度等措施。
  2. 正则化方法:正则化是防止过拟合的核心手段,主要有 L2 正则化、L1 正则化和弹性网络等形式。L2 正则化(如岭回归)能使模型的权重系数变小,让模型更简单,减少过拟合风险;L1 正则化(如 Lasso 回归)可使部分权重直接为 0,实现自动的特征选择,输出稀疏模型;弹性网络则综合了岭回归和 Lasso 回归的优势,通过混合比进行控制,在一些复杂数据情况下表现更稳定。
  3. 岭回归的应用:我们学习了岭回归在 scikit-learn 库中的 API 使用,包括Ridge类和RidgeCV类,并了解了各参数的含义和作用。同时,通过波士顿房价预测的具体案例,展示了岭回归模型的训练、评估过程,以及正则化力度的变化对权重系数和模型结果的影响。
  4. 模型的保存与加载:掌握了在 scikit-learn 库中使用joblib工具进行模型保存和加载的方法,这在实际应用中能够节省训练时间和计算资源,方便模型在不同场景下的复用。

这些知识和技能为我们在处理线性回归问题,优化模型性能,以及实际项目中的应用提供了坚实的基础,有助于我们更好地应对各种数据和业务需求,提升模型的准确性和泛化能力。