机器学习2 线性模型

本文深入探讨线性模型,包括线性回归、多项式回归、岭回归及Lasso回归,解析模型原理,展示实战应用,揭示如何应对过拟合与欠拟合问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引言

线性模型形式简单、易于建模,就好像“hello world”。但许多功能强大的非线性模型都是在线性模型上的延伸。我们主要介绍几种经典的线性模型:线性回归,多项式回归,岭回归,lasso回归,逻辑斯提回归。

线性回归

以西瓜问题为例,它有三个属性(也就做特征),{色泽,根蒂,敲声},根据这些属性判断是不是好瓜,我们自然而然想到的是:是不是可以通过属性的线性组合来预测。即:

f(x)=w_{1}x_{1}+w_{2}x_{2}+w_{3}x_{3}+b

写成向量形式:

f(x)=w^{T}x+b

其中w叫做权重系数,b叫做偏置项。

那么如何确定w,b呢。关键在于我们的预测值和实际值间的差距。在回归任务中,均方误差是最常用的性能度量。

其中f为我们的预测函数,D为包含m个样本的数据集。

你可能会想也可以这样度量差距啊:

当然这样也可以,这叫做曼哈顿距离,但函数性质不好,不连续,在后续处理会很麻烦。

我们的目标是求得使均方误差最小化的w和b:

接下来就是数学推导了;

对于包含m个样本的数据集D,每个样本有d个属性描述的一般情况。我们试图学得的模型为:

我们把w,b两个未知的参数写在一起:

其中:

X为(m,d+1)维,W为(d+1,1)维

这样我们的目标函数就是:

目标函数为连续的凸函数,令其偏导数为零,不就解出需要的参数了吗?

解得:

可以看出一下子就解出我们需要的参数了,这是求解模型的方法之一:存在闭式解。另一种情况:很难求得闭式方程,需要使用迭代优化的方法,一步步走直到参数最优。这种方法,我们会在逻辑斯提回归中介绍。

回来看,这有一个问题:XTX这个矩阵需要可逆,在练习情况下该矩阵通常是可逆的,因为样本数远远大于属性数。而在实际情况中该矩阵往往不可逆,属性数远远大于样本数,这样该矩阵不可逆,存在多个解。这时需要引入正则化,如岭回归,lasso回归。我会在线性回归之后进行介绍。

还有一个问题:线性回归往往出现欠拟合,在已知数据集上很难达到很好的性能,局部加权回归可以缓解这种情况。

实战演练

线性回归模型很简单,可以自己试着去实现。这里不再介绍,直接使用sklearn。

超参数:fit_intercept:是否需要偏置项b,默认true

              normalize:是否需要归一化。当 fit_intercept False,忽略该参数 。归一化方法为:减去均值,除以l2范数。如果需要 标准化, 使用 sklearn.preprocessing.StandardScaler 并设置 normalize=False.

             copy_X:是否需要复制X

             n_jobs:cpu使用数,-1代表全部使用。

属性:coef_:权重系数w

           intercept_:偏置项b

代码走起:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

'''
创建数据集
'''
#rand(100,1)产生100*1的矩阵,数为0到1的随机数
X = 2 * np.random.rand(100,1)
#randn(100,1)产生100*1的矩阵,数为正态分布随机数
y = 4 + 3*X + np.random.randn(100,1)

plt.figure()
plt.xlim(0,2)
plt.ylim(0,14)
plt.xlabel('x')
plt.ylabel('y')
plt.scatter(X,y)
plt.show()

结果:

 

lin_reg = LinearRegression()
lin_reg.fit(X,y)
print(lin_reg.coef_,lin_reg.intercept_)

结果:

在数据集上可视化:

'''
可视化
'''
plt.figure()
plt.xlim(0,2)
plt.ylim(0,14)
plt.xlabel('x')
plt.ylabel('y')
plt.plot([0,2],
         [lin_reg.intercept_[0],2*lin_reg.coef_[0][0]+lin_reg.intercept_[0]],
         c='black')
plt.scatter(X,y)
plt.title('LinearRegression')
plt.show()

结果:

还不错吧。

多项式回归

如果数据比简单的直线复杂,我们也可以用线性模型来进行拟合。一个简单的方法就是将每个特征的幂次方添加为一个新的特征,然后在这个拓展过的训练集上训练线性模型,这种方法称为多项式回归。

'''
创建数据集
'''
np.random.seed(42)
#rand(100,1)产生100*1的矩阵,数为0到1的随机数
X = 6 * np.random.rand(100,1) - 3
#randn(100,1)产生100*1的矩阵,数为正态分布随机数
y = 0.5 * X**2 + X + 2 + np.random.randn(100,1)

'''
可视化
'''
plt.figure()
plt.xlim(-3,3)
plt.ylim(0,10)
plt.xlabel('x')
plt.ylabel('y')
plt.scatter(X,y)
plt.show()

结果:

显然,直线不可能很好的拟合它。

'''
训练
'''
#利用PolynomialFeatures对数据进行转换,将每个属性的平方作为新特征加入数据集
poly_features = PolynomialFeatures(degree=2,include_bias=False)
X_poly = poly_features.fit_transform(X)
lin_reg = LinearRegression()
lin_reg.fit(X_poly,y)
'''
可视化
'''
plt.figure()
plt.xlim(-3,3)
plt.ylim(0,10)
plt.xlabel('x')
plt.ylabel('y')
x = np.arange(-3,3,0.1)
Y = lin_reg.coef_[0][1]*x**2 + lin_reg.coef_[0][0]*x + lin_reg.intercept_
plt.plot(x,Y,c='black')
plt.scatter(X,y)
plt.show()

结果:

岭回归

前面我们提到过,有时XTX矩阵不可逆时可以使用岭回归。简单来说,岭回归就是在XTX上加上一个lamda*I使得矩阵非奇异。

矩阵I是m*m的单位矩阵(单位矩阵,值1贯穿对角线,其余全是0,像不像一条‘岭’)。这样闭式解变成:

岭回归最初就是为了解决矩阵奇异的情况,现在也用于在估计中加入偏差,引入惩罚项相当于l2范数,降低过拟合。

这里引入了方差和偏差的概念:在机器学习领域,一个模型的泛化误差可以表示成三种误差的和

1)偏差 该误差的原因在于模型欠拟合

2)方差 该误差的原因在于使用的模型复杂,导致过拟合

3)不可避免的误差:数据本身的噪声

我们经常回去权衡偏差和方差,增加模型的复杂度就会提升方差,减小偏差。反过来,降低模型的复杂度就会降低方差,增大偏差。

参数:

alpha:正则化强度; 必须是正浮点数。 较大的值指定较强的正则化。

copy_X:与线性回归相同

fit_intercept:与线性回归相同

max_iter:int,可选,共轭梯度求解器的最大迭代次数。 对于’sparse_cg’和’lsqr’求解器,默认值由scipy.sparse.linalg确定。 对于’sag’求解器,默认值为1000。

normalize:与线性回归相同

solver:{‘auto’,’svd’,’cholesky’,’lsqr’,’sparse_cg’,’sag’,‘saga’}
用于计算的求解方法:
‘auto’根据数据类型自动选择求解器。
‘svd’使用X的奇异值分解来计算Ridge系数。对于奇异矩阵比’cholesky’更稳定。
‘cholesky’使用标准的scipy.linalg.solve函数来获得闭合形式的解,即上述的闭式解的一种变体
‘sparse_cg’使用在scipy.sparse.linalg.cg中找到的共轭梯度求解器。作为迭代算法,这个求解器比大规模数据的“cholesky”更合适。
‘lsqr’使用专用的正则化最小二乘常数scipy.sparse.linalg.lsqr。它是最快的,使用迭代过程。
‘sag’使用随机平均梯度下降。‘saga’是它的改进。都使用迭代过程,并且当n_samples和n_feature都很大时,通常比其他求解器更快。注意,“sag”快速收敛仅在具有近似相同尺度的特征上被保证。您可以使用sklearn.preprocessing的缩放器预处理数据。
所有最后五个求解器支持密集和稀疏数据。但是,当fit_intercept为True时,只有’sag’,‘saga’支持稀疏输入。
新版本0.17支持:sag。

新版本0.19支持:saga。

tol:float解的精度。

random_state:随机种子发生器。当为int时,生成固定数据,只适合‘sag’求解器


返回值

coef_:与线性回归相同

intercept_:与线性回归相同

n_iter_:每个目标的实际迭代次数。 仅适用于sag和lsqr求解器。 其他求解器将返回None。在版本0.17中出现。
 


'''
训练
'''
#利用PolynomialFeatures对数据进行转换,将每个属性的平方作为新特征加入数据集
poly_features = PolynomialFeatures(degree=2,include_bias=False)
X_poly = poly_features.fit_transform(X)
lin_reg = LinearRegression()
lin_reg.fit(X_poly,y)

#岭回归
ridge_reg = Ridge(alpha=100,solver='cholesky')
ridge_reg.fit(X_poly,y)
'''
可视化
'''
plt.figure()
plt.xlim(-3,3)
plt.ylim(0,10)
plt.xlabel('x')
plt.ylabel('y')
x = np.arange(-3,3,0.1)
Y1 = lin_reg.coef_[0][1]*x**2 + lin_reg.coef_[0][0]*x + lin_reg.intercept_
plt.plot(x,Y1,c='black',label='lin_reg')
Y2 = ridge_reg.coef_[0][1]*x**2 + ridge_reg.coef_[0][0]*x + ridge_reg.intercept_
plt.plot(x,Y2,c='red',label='ridge_reg')
plt.scatter(X,y)
plt.legend(loc='best')
plt.show()

结果:

alpha越大,越接近线性模型。

lasso回归

与岭回归一样,它也能缓解过拟合,引入惩罚项,相当于L1范数。Lasso回归有一个重要的特点,它会倾向于完全消除掉那些最不重要的权重,我们因此能更好的了解到哪些特征是无用的。

 alpha:正则化程度,较大的值指定较强的正则化。

fit_intercept:与线性回归相同

normalize:与线性回归相同

precompute:是否使用预计算的 Gram 矩阵来加速计算。如果设置为 ‘auto’ 则机器决定。Gram 矩阵也可以 pass。对于 sparse input 这个选项永远为 True。

max_iter:最大循环次数

tol:优化误差率

warm_start:为 True 时, 重复使用上一次学习作为初始化,否则直接清除上次方案

positive:设为 True 时,强制使系数为正。

random_state:随机种子生成器

selection:若设为 ‘random’, 每次循环会随机更新参数,而按照默认设置则会依次更新。设为随机通常会极大地加速交点(convergence)的产生,尤其是 tol 比 1e-4 大的情况下。

返回值

coef_:同线性回归

intercept_:同线性回归

n_iter_:达到误差率的循环次数

sparse_coef_:拟合系数的稀疏表示

 

#Lasso回归

Lasso_reg = Lasso(alpha=2)
Lasso_reg.fit(X_poly,y)
'''
可视化
'''
plt.figure()
plt.xlim(-3,3)
plt.ylim(0,10)
plt.xlabel('x')
plt.ylabel('y')
x = np.arange(-3,3,0.1)
Y1 = lin_reg.coef_[0][1]*x**2 + lin_reg.coef_[0][0]*x + lin_reg.intercept_
plt.plot(x,Y1,c='black',label='lin_reg')
Y2 = Lasso_reg.coef_[1]*x**2 + Lasso_reg.coef_[0]*x + Lasso_reg.intercept_
plt.plot(x,Y2,c='red',label='Lasso_reg')
plt.scatter(X,y)
plt.legend(loc='best')
plt.show()

结果:

小结

本节主要介绍线性模型中的线性回归,并引出了多项式回归来解决非线性数据问题。还介绍了岭回归和Lasso回归来解决过拟合问题。那如何利用线性模型进行分类学习呢?

下节我们将要介绍逻辑斯提回归。虽说它有回归字样,却叛变为分类学习方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值