本次修炼方法请往下查看
🌈 欢迎莅临我的个人主页 👈这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合,智慧小天地!
🎇 免费获取相关内容文档关注:微信公众号,发送 pandas 即可获取
🎇 相关内容视频讲解 B站
🎓 博主简介:AI算法驯化师,混迹多个大厂搜索、推荐、广告、数据分析、数据挖掘岗位 个人申请专利40+,熟练掌握机器、深度学习等各类应用算法原理和项目实战经验。
🔧 技术专长: 在机器学习、搜索、广告、推荐、CV、NLP、多模态、数据分析等算法相关领域有丰富的项目实战经验。已累计为求职、科研、学习等需求提供近千次有偿|无偿定制化服务,助力多位小伙伴在学习、求职、工作上少走弯路、提高效率,近一年好评率100% 。
📝 博客风采: 积极分享关于机器学习、深度学习、数据分析、NLP、PyTorch、Python、Linux、工作、项目总结相关的实用内容。
文章目录
- 🎯 1. 基本介绍
- 💡 2. 理论推导
- 2.1 数学基础知识
- 2.2 极大似然估计(MLE)
- 2.3 极大后验估计(MAP)
- 2.4 岭回归
- 2.5 Lasso回归
- 🔍 3. 代码实践
- 3.1 自己实现
- 3.2 sklearn线性回归使用
- 🔍 4. 注意事项
🎯 1. 基本介绍
线性回归是统计学中最基础的预测模型之一,用于分析一个或多个自变量(解释变量)与一个因变量(响应变量)之间的线性关系。在Python中,scikit-learn库提供了一个简单而强大的线性回归实现,适用于各种回归任务。
线性回归就两个参数,从频率学派去解释就是去最小化均方根误差,而最小化误差的方法就是最小二乘法,而对于最小二乘法可以通过极大似然估计推导出来。对于贝叶斯角度去,通过极大后验来估计线性回归的参数,个人感觉更好理解。
线性回归模型简单,计算速度快,解释性较强,但模型假设较强,如果不符合模型假设拟合效果较差
线性回归就是通过最小二乘方,拟合得出w矩阵,通过调用sklearn实现简单,但是不符合模型假设,噪声较多时,模型训练效果较差。
💡 2. 理论推导
2.1 数学基础知识
- 矩阵的转置:
( a b ) T = b T a T , ( a + b ) T = a T + b T (ab)^T = b^Ta^T, (a+b)^T=a^T+b^T (ab)T=bTaT,(a+b)T=aT+bT
- 矩阵的微分计算:
d(X+Y) = d(X) + d(Y),
d(XY) = d(XY) + Xd(Y),
d( X T X^T XT)= ( d ( X ) ) T (d(X))^T (d(X))T
- 矩阵的求导:
∂ x T A x ∂ x = ( A T + A ) x \frac{\partial x^TAx}{\partial x}=(A^T+A)x ∂x∂xTAx=(AT+A)x
∂ x T x ∂ x = 2 x \frac{\partial x^Tx}{\partial x}=2x ∂x∂xTx=2x
∂ β T x ∂ x = β \frac{\partial \beta^Tx}{\partial x}=\beta ∂x∂βTx=β
∂ x T β ∂ x = β \frac{\partial x^T\beta}{\partial x}=\beta ∂x∂xTβ=β
- 证明上述第一条公式:
d ( x T A x ) = d ( x T ) A x + x T d ( A x ) d(x^TAx)=d(x^T)Ax+x^Td(Ax) d(xTAx)=d(xT)Ax+xTd(Ax)
d ( x T A x ) = ( A x ) T d ( x ) + x T ( A T ) T d x d(x^TAx)=(Ax)^Td(x)+x^T(A^T)^Tdx d(xTAx)=(Ax)Td(x)+xT(AT)Tdx
d ( x T A x ) = ( x T A T + x T A ) d x d(x^TAx)=(x^TA^T+x^TA)dx d(xTAx)=(xTAT+xTA)dx
则: ∂ x T A x ∂ x = ( x T A T + x T A ) T = ( A T + A ) x \frac{\partial x^TAx}{\partial x}=(x^TA^T+x^TA)^T=(A^T+A)x ∂x∂xTAx=(xTAT+xTA)T=(AT+A)x
2.2 极大似然估计(MLE)
对于给定的数据集,我们可以把其中的数据看做是事实,而我们要做的工作就是得到参数为了使我们的模型更加接近事实,也就使得由数据集中的X得到对应的Y这件事发生的可能性最大。也即对于数据集中的数据D (Y, X), p ( D ∣ X , θ ) = ∏ ( P ( y ∣ x , θ ) ) p(D|X, \theta ) = \prod (P(y|x, \theta )) p(D∣X,θ)=∏(P(y∣x,θ))的值最大。显然对于每一组(x,y)他们之间是独立的。因此,对于一组数据(x,y)存在:
P ( y ∣ x , θ ) = p ( y ∣ h θ ( x ) + ε ) = p ( y − h θ ( x ) ∣ ϵ ) P(y|x, \theta ) = p(y|h_{\theta }(x)+\varepsilon ) = p(y-h_{\theta }(x)|\epsilon ) P(y∣x,θ)=p(y∣hθ(x)+ε)=p(y−hθ(x)∣ϵ)
- 假设 ϵ \epsilon ϵ服从(0,1)高斯分布,则似然函数为:
l ( θ ) = l o g p ( D ∣ θ ) ) = ∑ i = 1 n l o g p ( y i ∣ x i , θ ) l(\theta ) = logp(D|\theta )) = \sum_{i=1}^{n}logp(y_{i}|x_{i},\theta ) l(θ)=logp(D∣θ))=∑i=1nlogp(yi∣xi,θ)
P ( y ∣ x , θ ) = p ( y − h θ ( x ) ∣ ϵ ) = 1 2 π σ e − ( x − u ) 2 2 σ 2 = 1 2 π σ e − ( y − h θ ) 2 2 P(y|x, \theta ) = p(y-h_{\theta }(x)|\epsilon ) = \frac{1}{\sqrt{2\pi \sigma }}e^{-\frac{(x-u)^{2}}{2\sigma ^{2}}}= \frac{1}{\sqrt{2\pi \sigma }}e^{-\frac{(y-h_{\theta})^{2}}{2}} P(y∣x,θ)=p(y−hθ(x)∣ϵ)=2πσ1e−2σ2(x−u)2=2πσ1e−2(y−hθ)2
l n ( p ( y ∣ x , θ ) ) = ∑ l n ( 1 2 π σ ) − ( y − h θ ( x ) ) 2 2 = C − 1 2 ∑ ( y − h θ ( x ) ) 2 ln(p(y|x,\theta))= \sum ln(\frac{1}{\sqrt{2\pi \sigma }}) - \frac{(y-h_{\theta}(x))^{2}}{2}=C-\frac{1}{2}\sum (y-h_{\theta }(x))^{2} ln(p(y∣x,θ))=∑ln(2πσ1)−2(y−hθ(x))2=C−21∑(y−hθ(x))2
- 所以要是上面的似然函数值最大化就是要最小化:min: 1 2 ∑ ( y − h θ ( x ) ) 2 \frac{1}{2}\sum (y-h_{\theta }(x))^{2} 21∑(y−hθ(x))2,而由于是二次方,所以也叫做最小二乘方,最小二乘法的推导过程如下所示:
▽ w J ( w ) = ▽ w ( X w − Y ) T ( X w − Y ) \triangledown_wJ(w)=\triangledown_w(Xw-Y)^T(Xw-Y) ▽wJ(w)=▽w(Xw−Y)T(Xw−Y)
▽ w J ( w ) = ▽ w ( w T X T X w − Y T X w − w T X T Y + Y T Y ) \triangledown_wJ(w)=\triangledown_w(w^TX^TXw-Y^TXw-w^TX^TY+Y^TY) ▽wJ(w)=▽w(wTXTXw−YTXw−wTXTY+YTY)
▽ w J ( w ) = ▽ w ( w T X T X w ) − ▽ w ( Y T X w ) − ▽ w ( w T X T Y ) \triangledown_wJ(w)=\triangledown_w(w^TX^TXw)-\triangledown_w(Y^TXw)-\triangledown_w(w^TX^TY) ▽wJ(w)=▽w(wTXTXw)−▽w(YTXw)−▽w(wTXTY)
▽ w J ( w ) = 2 ∗ X T X w − X T Y − X T Y \triangledown_wJ(w)=2*X^TXw-X^TY-X^TY ▽wJ(w)=2∗XTXw−XTY−XTY
▽ w J ( w ) = 2 ∗ X T X w − 2 X T Y \triangledown_wJ(w)=2*X^TXw-2X^TY ▽wJ(w)=2∗XTXw−2XTY
- 最后得出来的w的结果如下所示:
w = ( x T x ) − 1 x T y w =(x^Tx)^{-1}x^Ty w=(xTx)−1xTy
2.3 极大后验估计(MAP)
极大后验估计的方法来估计线性回归中的参数w,具体的公式如下所示:
a r g m a x : p ( θ ∣ D ) = a r g m a x : p ( D ∣ θ ) p ( θ ) p ( D ) = a r g m a x : p ( D ∣ θ ) p ( θ ) argmax:p(\theta |D) = argmax:\frac{p(D|\theta )p(\theta )}{p(D)}= argmax:p(D|\theta )p(\theta ) argmax:p(θ∣D)=argmax:p(D)p(D∣θ)p(θ)=argmax:p(D∣θ)p(θ)
- 从上面的公式可以看出,当 p ( θ ) p(\theta ) p(θ)服从均值分布时,MAP和MLE等同,当服从高斯时,就是岭回归,当服从拉普拉斯时就是lassos回归。
2.4 岭回归
岭回归的loss如下所示:
J ( w ) = ∑ ( y − h θ ( x ) ) ) 2 + λ ∣ ∣ w ∣ ∣ 2 2 J(w) = \sum (y - h_{\theta }(x)))^2 + \lambda ||w||_{2}^{2} J(w)=∑(y−hθ(x)))2+λ∣∣w∣∣22
J ( w ) = 2 X T X w − 2 X T y + λ I J(w) = 2X^TXw-2X^Ty+\lambda I J(w)=2XTXw−2XTy+λI
- 令上述为0,则可以求解得出w的值如下所示:
w = ( λ I D + X T X ) − 1 X T y w = (\lambda I_{D} + X^{T}X)^{-1}X^{T}y w=(λID+XTX)−1XTy
- 关于岭回归为啥是防止过拟合降维的作用,当矩阵 A − 1 = 1 ∣ A ∣ A ∗ A^{-1}=\frac{1}{|A|}A^{*} A−1=∣A∣1A∗,当x中很多的行相关时,则|A|可能为零,从而导致 A − 1 A^{-1} A−1的值很大,但是岭回归中添加了$\lambda I_{D} $防止其值不过大,当x中行向量相关时。
- 当然从最优化的角度更好理解的是,最小化上面的公式,第一项要最小化,那么第二项是个大于0的值,所有限制了w的值比较大,从而增加了模型的鲁棒性。
- 还有一种解释的方法就是对参数进行梯度下降法,第一步导数的求取:
$ J(w) = \frac{1}{2m} \sum_{i=1}{m}(h_{w}(x{i})-y{i}){2} + \frac{1}{2m} \lambda ||w||_{2}^{2}$
∂ ( J ( w ) ) ∂ ( w ) = 1 m ( h w ( x i ) − y i ) ∗ ∂ ( h w ( x i ) ) x i + λ m w \frac{\partial(J(w))}{\partial(w)} = \frac{1}{m}(h_{w}(x^{i})-y^{i})*\frac{\partial(h_{w}(x^{i}))}{x^{i}} + \frac{\lambda}{m}w ∂(w)∂(J(w))=m1(hw(xi)−yi)∗xi∂(hw(xi))+mλw
∂ ( J ( w ) ) ∂ ( w ) = 1 m ( h w ( x i ) − y i ) ∗ x j i + λ m w \frac{\partial(J(w))}{\partial(w)} = \frac{1}{m}(h_{w}(x^{i})-y^{i})*x_{j}^{i}+ \frac{\lambda}{m}w ∂(w)∂(J(w))=m1(hw(xi)−yi)∗xji+mλw
- 第二步,梯度更新的过程:
w j : w j ( 1 − λ m ) − ∂ ( J ( w ) ) ∂ ( w ) w_{j}: w_{j}(1-\frac{\lambda}{m}) - \frac{\partial(J(w))}{\partial(w)} wj:wj(1−mλ)−∂(w)∂(J(w))
- 从上式可以看到,与未添加L2正则化的迭代公式相比,每一次迭代 θ j \theta_j θj,都要先乘以一个小于1的因子,从而使得 θ j \theta_j θj的值不断减小,所以,从整体上来看相对于不加l2, θ j \theta_j θj减小的更大一些。
2.5 Lasso回归
Lasso回归的loss如下所示:
J ( w ) = ∑ ( y − h θ ( x ) ) ) 2 + λ ∣ ∣ w ∣ ∣ 1 J(w) = \sum (y - h_{\theta }(x)))^2 + \lambda ||w||_{1} J(w)=∑(y−hθ(x)))2+λ∣∣w∣∣1
- J(w)中的第一项的导数结果如下:
2 ∗ X T X w − 2 ∗ X T Y 2*X^{T}Xw - 2*X^{T}Y 2∗XTXw−2∗XTY
- 对于第二项的导数来说,由于在0点函数不可导,故有2种比较好的方法进行求导:一种是次梯度下降法(收敛慢,不常用),还有一种是sklearn中使用的坐标下降法:
- 坐标下降法的步骤如下所示:
算法的核心思想就是选择一个维度,固定其它的维度,然后不断的遍历这个维度上的数值,最后直到选择出目标函数的值最小
1.首先给定一个初始点,如 X_0=(x1,x2,…,xn);
2.for x_i=1:n
固定除x_i以外的其他维度
以x_i为自变量,求取使得f取得最小值的x_i;
end
🔍 3. 代码实践
3.1 自己实现
如果要从0到1开始实现线性回归算法,具体的代码如下所示:
def linear_regression(x: np.array(),
y: np.array()
):
'''
其中@符号相当于两个数组点乘,也可以使用函数np.dot(a, b)来实现相同的功能
求线性回归的参数w:其中x的shape为(n,m),y的shape为(n,1)
w = (X^T X)^{-1} X^T y
'''
tmp = (x.T@x).I
w = tmp@x.T@y
return w
- 岭回归代码
def ridge_regression(x: np.array(),
y: np.array(),
lambda_x):
'''
求岭回归的参数w:其中x的shape为(n,m),y的shape为(n,1), lambda为数值
w = (X^T X + lambdaI)^{-1} X^T y
'''
xtx = x.T@x
m,_ = xtx.shape
I_x = np.eye(m)
tmp = (xtx + lambda_x*I_x).I
w = tmp@x.T@y
return w
# 在求解w也可以使用梯度下降的方法来求解w
def gradientDescent(X, Y, alpha, epoch, c):
W = np.random.normal(0,1,size=(X.shape[1],))
for i in range(epoch):
W -= alpha*(X.T).dot(X.dot(W)-Y)/X.shape[0] + c*W
return W
3.2 sklearn线性回归使用
我们构建数据来模型线性回归的整个过程,具体的代码如下所示:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
# 创建一些示例数据
X = 2 * np.random.rand(100, 1) # 自变量,100个样本
y = 4 + 3 * X + np.random.randn(100) # 因变量,添加噪声
# 添加截距项
X_b = np.c_[np.ones((100, 1)), X] # 添加一列1s作为截距项
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_b, y, test_size=0.2, random_state=42)
# 创建线性回归模型实例
model = LinearRegression()
# 训练模型
model.fit(X_train, y_train)
# 在训练集和测试集上进行预测
y_train_pred = model.predict(X_train)
y_test_pred = model.predict(X_test)
# 计算MSE和R²
train_mse = mean_squared_error(y_train, y_train_pred)
test_mse = mean_squared_error(y_test, y_test_pred)
train_r2 = r2_score(y_train, y_train_pred)
test_r2 = r2_score(y_test, y_test_pred)
print(f"训练集MSE: {train_mse:.2f}, R²: {train_r2:.2f}")
print(f"测试集MSE: {test_mse:.2f}, R²: {test_r2:.2f}")
训练集MSE: 0.00, R²: 1.00
测试集MSE: 0.00, R²: 1.00
🔍 4. 注意事项
- 线性回归模型假设自变量和因变量之间存在线性关系,如果这种关系不成立,模型可能不适用。
- 线性回归对异常值敏感,需要在建模前进行适当的数据清洗。
- 考虑使用特征缩放,特别是当自变量的量纲不一致时。