线性回归 :标准方程法的求解 (包含numpy对矩阵加工的代码)

线性回归

生活满意度的回归模型: l i f e − s a t i s f a c t i o n = θ 0 + θ 1 × G D P − p e r − c a p i t a life-satisfaction = \theta_0 +\theta_1 \times GDP-per-capita lifesatisfaction=θ0+θ1×GDPpercapita
这个模型就是输入特征GDP_per_capita的线性函数, θ 0 \theta _0 θ0 θ 1 \theta _1 θ1是模型的参数。

更为概括地说,线性模型就是对输入特征加权求和,再加上一个我们称为偏置项(也称为截距项)的常数,以此进行预测。
线性回归模型预测公式如下:
y ^ = θ 0 + θ 1 x 1 + θ 2 x 2 + ⋯ + θ n x n \hat y = \theta _0 +\theta _1 x_1 +\theta_2x_2 +\dots +\theta_nx_n y^=θ0+θ1x1+θ2x2++θnxn
在此等式中:

  • y ^ \hat y y^是预测值。
  • n n n是特征数量。
  • x i x_i xi是第i个特征值。
  • θ j \theta _j θj是第j个模型参数(从0开始, θ 0 \theta_0 θ0也算)

也可以使用向量化的形式更简洁地表示
y ^ = h θ ( x ) = θ × x \hat y = h_{\theta}(x) = \theta \times x y^=hθ(x)=θ×x

在此等式中:

  • θ \theta θ是模型的参数向量,其中包含偏差项 θ 0 \theta_0 θ0和特征权重 θ 1 \theta_1 θ1
    n。
  • x x x是实例的特征向量,包含从 x 0 x_0 x0 x n x_n xn x 0 x_0 x0始终等于1。
  • θ × x \theta \times x θ×x是向量 θ \theta θ x x x的点积,它当然等于 θ 0 x 0 + θ 1 x 1 + θ 2 x 2 + ⋯ + θ n x n \theta _0 x_0 +\theta_1 x_1 +\theta_2 x_2+\dots +\theta_n x_n θ0x0+θ1x1+θ2x2++θnxn
  • h θ h_\theta hθ是假设函数,使用模型参数 θ \theta θ

在机器学习中,向量通常表示为列向量,是有单一列的二维数组。如果 θ \theta θ x x x为列向量,则预测为 ,其中 θ T \theta ^T θT θ \theta θ(行向量而不是列向量)的转置,且 θ T \theta ^T θT x x x θ T \theta ^T θT x x x的矩阵乘积。当然这是相同的预测,除了现在是以单一矩阵表示而不是一个标量值。

这就是线性回归模型,我们该怎样训练线性回归模型呢?回想一下,训练模型就是设置模型参数直到模型最拟合训练集的过程。为此,我们首先需要知道怎么测量模型对训练数据的拟合程度是好还是差。我们了解到回归模型最常见的性能指标是均方根误差(RMSE)。

因此,在训练线性回归模型时,你需要找到最小化RMSE的 θ \theta θ值。在实践中,将均方误差(MSE)最小化比最小化RMSE更为简单,二者效果相同(因为使函数最小化的值,同样也使其平方根最小)
MSE公式如下
M S E = ( X , h θ ) = 1 m ∑ i = 1 m ( θ T x ( i ) − y ( i ) ) 2 MSE = (X,h_\theta) = \frac{1}{m}\sum^m_{i=1}(\theta^Tx^{(i)} - y^{(i)})^2 MSE=(X,hθ)=m1i=1m(θTx(i)y(i))2
y ( i ) y^{(i)} y(i)表示第i个真实值。

标准方程

为了得到使成本函数最小的θ值,有一个闭式解方法——也就是一个直接得出结果的数学方程,即标准方程。
公式:标准方程 θ ^ = ( X T X ) − 1 X T y \hat \theta = (X^TX)^{-1}X^Ty θ^=(XTX)1XTy
这个方程中:

  • θ ^ \hat \theta θ^是使成本函数最小的θ值。

  • y y y是包含 y ( i ) y^{(i)} y(i) y ( m ) y^{(m)} y(m)的目标值向量。

import numpy as np
import matplotlib.pyplot as plt
X = 2*np.random.rand(100,1) #生成一个形状为(100 ,1)的数组,从[0,2)中随机取值
y = 4+3*X +np.random.randn(100,1) 

np.random.rand(a,b) 生成一个在[0,1)上随机取值,形状为(a,b)的二维均匀分布数组
np.random.randn(a,b) 生成一个均值为0,标准差为1 ,形状为(a,b)的二维正态分布数组

画图查看分布情况

plt.plot(X,y,"r.")
plt.xlabel("$x_1$",fontsize=18)
plt.ylabel("$y$",fontsize = 18)
plt.axis([0,2,0,13])
plt.savefig("generated_data_plot")
plt.show()

结果如下
![[QQ_1725080864315.png]]

现在我们使用标准方程来计算 θ ^ \hat \theta θ^。使用Numpy 的线性代数模块 ( n p . l i n a l g ) (np.linalg) (np.linalg)中的 i n v ( ) inv() inv()函数来对矩阵求逆,并使用 d o t ( ) dot() dot()方法计算矩阵内积

X_b = np.c_[np.ones((100,1)),X] 
theta_best = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y)

θ ^ = ( X T X ) − 1 X T y \hat \theta = (X^TX)^{-1}X^Ty θ^=(XTX)1XTy
我们实际用来生成数据的函数是 y = 4 + 3 x 1 + y=4+3x_1+ y=4+3x1+高斯噪声。
我们要求的是 θ 0 \theta_0 θ0 θ 1 \theta_1 θ1 θ 0 \theta_0 θ0的系数是1,故需要添加一个1的矩阵。
看看结果如何

array([[4.21509616],
       [2.77011339]])

我们期待的是 θ 0 = 4 \theta_0 = 4 θ0=4 θ 1 = 3 \theta_1 = 3 θ1=3得到的是 θ 0 = 4.215 \theta_0=4.215 θ0=4.215 θ 1 = 2.770 \theta_1=2.770 θ1=2.770。非常
接近,噪声的存在使其不可能完全还原为原本的函数。

现在可以用 θ ^ \hat \theta θ^作出预测。

X_new = np.array([[0],[2]])
X_new_b = np.c_[np.ones((2,1)),X_new]
y_predict = X_new_b.dot(theta_best)
y_predict

结果如下:

array([[4.21509616]
 [9.75532293]])

绘制模型的预测结果:

plt.plot(X_new,y_predict,"r-")
plt.plot(X,y,"b.")
plt.axis([0,2,0,15])
plt.show()

结果如下:
![[QQ_1725082201305.png]]

使用Scikit-Learn执行线性回归也很简单

from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(X,y)
lin_reg.intercept_ #截距 
lin_reg.coef_ #系数
#(array([4.21509616]), array([[2.77011339]]))

LinearRegression类基于scipy.linalg.lstsq()函数(名称代表“最小二乘”),你可以直接调用它:

theta_best_svd ,residuals,rank, s = np.linalg.lstsq(X_b,y,rcond = 1e-6)
theta_best_svd

函数的返回值是一个元组,包含以下四个元素:

  • theta_best_svd:这是最小二乘解,即模型参数的最优估计。在线性回归的上下文中,这些参数对应于自变量(包括截距项,如果添加了的话)的系数。
  • residuals:这是残差数组,即实际观测值与模型预测值之间的差异。
  • rank:这是设计矩阵X_b的数值秩。它反映了矩阵中独立(非零)的行(或列)的数量。
  • s:这是奇异值的数组。这些值是从设计矩阵的奇异值分解中得到的,可以用来评估数值稳定性和模型的复杂度。
    结果如下:
array([[4.21509616],
       [2.77011339]])

此函数计算 θ ^ = X + y \hat \theta = X^+ y θ^=X+y,其中 X + X^+ X+ X X X的伪逆(具体来说是MoorePenrose逆)。你可以使用 n p . l i n a l g . p i n v () np.linalg.pinv() np.linalg.pinv()来直接计算这个伪逆:

np.linalg.pinv(X_b).dot(y)

伪逆: X + = ( X T X ) − 1 X T X^+ = (X^TX)^{-1}X^T X+=(XTX)1XT

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值