赞
踩
全文共10400余字,预计阅读时间约25~40分钟 | 满满干货,建议收藏!
线性回归其实是统计学和机器学习中非常重要的模型,首先它原理简单明了,易于理解。这使得线性回归成为许多人接触和学习机器学习的入门模型。但同时它在机器学习和统计学中也起到了基础性的作用。许多复杂的机器学习算法,如逻辑回归、支持向量机、神经网络等,都可以从线性回归扩展得到。
线性回归模型虽然原理简单,但在实际应用中非常广泛。尽管它假设数据之间存在线性关系,这在现实中可能并不总是成立,但在许多情况下,线性模型已经足够好,能够提供有用的预测。
比如在经济学领域中,经济学家使用线性回归分析各种经济变量之间的关系,比如预测未来的消费支出、GDP增长等;在医学研究中,线性回归可以用来探究不同的生活习惯、环境因素如何影响人的健康状况;在金融领域,线性回归可以用来预测股票的价格、预测信用评分等。
因此,无论是在学习理论知识还是在解决实际问题时,线性回归都是一个非常有用的工具。
首先需要说明的是,线性回归是一种预测性的建模技术,用于预测一个响应变量(因变量)和一个或多个预测变量(自变量)之间的关系。
从严格的定义来讲:线性回归是一种参数化的统计模型,其中响应变量(Y)是自变量(X)的线性函数,并且有一个随机误差项。一元线性回归模型的数学形式通常表示为
Y
=
β
0
+
β
1
X
+
ϵ
Y = \beta_0 + \beta_1X + \epsilon
Y=β0+β1X+ϵ
其中β0和β1是模型的参数,ε是随机误差项。
通俗来讲:线性回归就是找到一条最佳的直线(在二维空间中)或者一个平面(在三维空间中),这条直线(或平面)能够尽可能地接近所有的数据点。我们希望这条直线(或平面)的预测值与真实值之间的差距(通常是平方差)尽可能地小。我们可以通过一个随机的构图来理解
import numpy as np import matplotlib.pyplot as plt # 生成随机数据 np.random.seed(0) X = np.random.rand(50) * 10 Y = 2 * X + np.random.randn(50) * 2 # 执行线性回归 coefficients = np.polyfit(X, Y, 1) slope = coefficients[0] intercept = coefficients[1] regression_line = slope * X + intercept # 绘制散点图和回归线 plt.scatter(X, Y, color='blue', label='Data Points') plt.plot(X, regression_line, color='red', label='Regression Line') plt.xlabel('X') plt.ylabel('Y') plt.title('Linear Regression') plt.legend() plt.grid(True) plt.show()
在这段代码中,首先使用numpy库生成50个随机的X值,并根据线性方程Y = 2X + 噪声生成对应的Y值。然后,使用np.polyfit函数进行线性回归,得到回归直线的斜率和截距。最后,使用matplotlib库绘制散点图表示原始数据点,绘制红色线条表示回归直线。
图中的蓝色散点代表数据点,这些点分布在二维平面上。红色的线条代表线性回归的最佳拟合直线。回归直线尽可能地接近所有的数据点,即使存在一些噪声。线性回归的目标是最小化预测值与真实值之间的差距,通常使用平方差作为度量。通过最小化这个差距,我们可以找到最佳拟合直线,它在二维空间中能够最好地表示数据的整体趋势。
当然,线性回归的假设也存在一些假设:
线性关系:模型假设响应变量和预测变量之间存在线性关系。这也是线性回归名称的由来。
独立性:观测值之间应该是独立的。这意味着一个观测值的出现不应该影响到其他观测值的出现。
同方差性:这个假设意味着不同的自变量值对应的因变量的方差应该是相同的。
正态性:对于任何给定的自变量值,因变量是正态分布的。
无多重共线性:在多元线性回归中,模型假设自变量之间不应该有完全的线性关系。如果存在完全的线性关系(即多重共线性),则模型的参数估计将变得不稳定,解释和预测的能力会受到影响。
线性回归是属于回归类模型,是针对连续型变量进行数值预测的模型,那其实也有很多形式,分别是简单线性回归、多元线性回归和多项式回归,其区别在于自变量(预测变量)的数量。
一元线性回归的模型表达式是:
Y = β 0 + β 1 X + ϵ Y = \beta_0 + \beta_1X + \epsilon Y=β0+β1X+ϵ
其中,Y 是响应变量,X 是预测变量,β0 是截距,β1 是斜率(即预测变量的系数),ε 是误差项。
以下是一个表格形式的例子,模拟一元和多元线性回归的情况:
房价(万元) | 房子的面积(平方米) | 房间数量 |
---|---|---|
300 | 100 | 3 |
400 | 150 | 4 |
500 | 200 | 5 |
600 | 250 | 6 |
例如,我们可以假设房价(Y)和房子的面积(X)之间存在线性关系,那么我们的一元线性回归模型可能是这样的:
房价 = β 0 + β 1 × 房子的面积 + ϵ 房价 = \beta_0 + \beta_1 \times 房子的面积 + \epsilon 房价=β0+β1×房子的面积+ϵ
多元线性回归的模型表达式是:
Y = β 0 + β 1 X 1 + β 2 X 2 + . . . + β n X n + ϵ Y = \beta_0 + \beta_1X_1 + \beta_2X_2 + ... + \beta_nX_n + \epsilon Y=β0+β1X1+β2X2+...+βnXn+ϵ
其中,Y 是响应变量,X1, X2, …, Xn 是预测变量,β0 是截距,β1, β2, …, βn 是预测变量的系数,ε 是误差项。
例如,我们可以假设房价(Y)和房子的面积(X1)、房间数量(X2)等因素之间存在线性关系,那么我们的多元线性回归模型可能是这样的:
房价 = β 0 + β 1 × 房子的面积 + β 2 × 房间数量 + ϵ 房价 = \beta_0 + \beta_1 \times 房子的面积 + \beta_2 \times 房间数量 + \epsilon 房价=β0+β1×房子的面积+β2×房间数量+ϵ
在这个例子中,如果我们只使用"房子的面积"作为预测变量来预测"房价",那么这就是一元线性回归的情况。如果我们同时使用"房子的面积"和"房间数量"作为预测变量来预测"房价",那么这就是多元线性回归
对于简单线性回归来说,由于模型可以简单表示为 Y = β 0 + β 1 X + ϵ Y = \beta_0 + \beta_1X + \epsilon Y=β0+β1X+ϵ形式,因此我们可以用二维平面图像来进行对应方程的函数图像绘制。例如,当模型为 Y = X + 1 Y=X+1 Y=X+1时,函数图像如下所示:
import matplotlib as mpl
import matplotlib.pyplot as plt
x = np.arange(-5,5,0.1)
y = x + 1
plt.plot(x, y, '-', label='y=x+1')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc = 2)
我们的建模数据为:
weight | label |
---|---|
1 | 2 |
3 | 4 |
将特征是为x、将标签是为y,则绘制图像可得:
# 绘制对应位置元素点图
A = np.arange(1, 5).reshape(2, 2)
plt.plot(A[:,0], A[:, 1], 'ro')
# 线性回归直线
plt.plot(x, y, '-', label='y=x+1')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc = 2)
由于模型方程是基于满足数据中x和y基本关系构建的,因此模型这条直线最终将穿过这两个点。而简单线性回归的几何意义,就是希望找到一条直线,尽可能的接近样本点。或者说,我们是通过一条直线去捕捉平面当中的点。当然,大多数情况下我们都无法对平面中的点进行完全的捕捉,而直线和点之间的差值,实际上就是SSE。
线性回归中回归的含义,则是:如果模型真实有效,则新数据也会像朝向这条直线“回归”一样,最终分布在这条直线附近。
我们上面提出了线性回归模型,那么在机器学习建模的第一步,就尝试利用简单线性回归去捕捉一个简单数据集中的基本数据规律,这里的 Y = β 0 + β 1 X + ϵ Y = \beta_0 + \beta_1X + \epsilon Y=β0+β1X+ϵ 就作为我们所提出的基本模型。当然还有诸多不同种类的机器学习模型,而不同的模型也有对应的适用场景。值得注意的是,在提出模型时,我们往往会预设好一些影响模型结构或者实际判别性能的参数,如简单线性回归中的 β 0 \beta_0 β0 和 ϵ \epsilon ϵ.
在提出基本模型后,要围绕建模的目标构建评估指标,并且围绕评估指标设置损失函数。损失函数不是模型,而是模型参数所组成的一个函数,那么什么是损失函数及为什么要有损失函数?
损失函数,也被称为成本函数或误差函数,是一个数学函数,用于评估模型预测结果与实际结果之间的差距。在监督学习中,目标是找到一个模型,可以使得损失函数最小。
在线性回归中,我们常用的损失函数是均方误差(Mean Squared Error,MSE),表达式如下:
M S E = 1 n ∑ i = 1 n ( Y i − Y ^ i ) 2 MSE = \frac{1}{n} \sum_{i=1}^{n}(Y_i - \hat{Y}_i)^2 MSE=n1i=1∑n(Yi−Y^i)2
其中,n 是样本数量, Y i Y_i Yi 是第i个样本的实际值, Y ^ i \hat{Y}_i Y^i 是第i个样本的预测值。
损失函数的主要作用是衡量模型的预测结果与实际结果之间的差异。在机器学习中,我们的目标通常是最小化损失函数。换句话说,我们希望找到一组模型参数,使得对所有样本的预测值与其实际值之间的差异总和最小。
损失函数是机器学习中的基础概念,它为我们提供了一个衡量模型好坏的具体数值。通过最小化损失函数,我们能够找到最佳的模型参数,使得模型在训练集上的表现最佳。同时,损失函数也是我们优化模型、防止过拟合等一系列操作的基础。
假设我们有以下一元线性回归模型预测房价(单位:万元)的数据:
房子的面积(平方米) | 实际房价(万元) | 预测房价(万元) |
---|---|---|
100 | 300 | 280 |
150 | 400 | 390 |
200 | 500 | 520 |
250 | 600 | 610 |
我们可以通过均方误差来计算损失函数:
M S E = 1 4 [ ( 300 − 280 ) 2 + ( 400 − 390 ) 2 + ( 500 − 520 ) 2 + ( 600 − 610 ) 2 ] MSE = \frac{1}{4} [(300-280)^2 + (400-390)^2 + (500-520)^2 + (600-610)^2] MSE=41[(300−280)2+(400−390)2+(500−520)2+(600−610)2]
计算结果可以帮助我们了解模型预测结果与实际结果的一致性。如果MSE越小,说明我们的模型预测效果越好。
优化算法是一种寻找并选择最优解的方法,它的目标是最小化或最大化目标函数。在机器学习中,我们通常希望最小化损失函数,以此来提高模型的预测精度。
优化算法的主要作用是调整模型的参数,使得模型在训练集上的损失函数值最小。通过不断的迭代更新模型参数,我们可以找到损失函数的最小值点,从而得到最优的模型参数。
优化算法是训练机器学习模型的核心部分。没有优化算法,我们无法确定模型的参数,也就无法得到一个有效的模型。通过优化算法,我们可以找到一组最优的模型参数,使得模型的预测结果与实际结果的差异最小。
常见的优化算法如最小二乘法、梯度下降法、牛顿法等,本文先详解最小二乘法,其他的优化算法将在后续的文章中陆续讲解到其他模型的更加复杂的损失函数,以及对应的损失函数求解方法。选择哪种优化算法取决于具体的问题和数据。
总的来说,损失函数既承载了我们优化的目标(让预测值和真实值尽可能接近),同时也是包含了模型参数的函数,当我们围绕目标函数求解最小值时,也就完成了模型参数的求解。当然,这个过程本质上就是一个数学的最优化过程,求解目标函数最小值本质上也就是一个最优化问题,而要解决这个问题,我们就需要灵活适用一些最优化方法。当然,在具体的最优化方法的选择上,函数本身的性质是重要影响因素,也就是说,不同类型、不同性质的函数会影响优化方法的选择。在简单线性回归中,由于目标函数是凸函数,我们根据凸函数性质,我们选取了最小二乘法作为该损失函数的优化算法。但实际上,简单线性回归的损失函数其实是所有机器学习模型中最简单的一类损失函数。
在确定优化方法之后,我们就能够借助优化方法对损失函数进行求解,当然在大多数情况下我们都是求解损失函数的最小值。而伴随损失函数最小值点确定,我们也就找到了一组对应的损失函数自变量的取值,而该组自变量的取值也就是模型的最佳参数。
我们首先构造一个表格,表示我们的数据集。在这个例子中,我们使用房子的面积(X1)和房间数量(X2)来预测房价(Y):
房价(万元) | 房子的面积(平方米) | 房间数量 |
---|---|---|
300 | 80 | 2 |
400 | 120 | 3 |
500 | 200 | 4 |
600 | 280 | 5 |
在这个例子中,我们的多元线性回归模型可以表示为:
Y = β 0 + β 1 X 1 + β 2 X 2 + ϵ Y = \beta_0 + \beta_1X_1 + \beta_2X_2 + \epsilon Y=β0+β1X1+β2X2+ϵ
其中,Y 是房价,X1 是房子的面积,X2 是房间数量,β0, β1, β2 是模型的参数,ε 是误差项。
我们可以将上述的多元线性回归模型改写为矩阵形式,这样可以更方便的进行计算。设 X 是包含所有预测变量的矩阵,β 是模型参数的向量,Y 是响应变量的向量,那么我们的模型可以表示为:
Y = X β + ϵ Y = X\beta + \epsilon Y=Xβ+ϵ
我们通常使用均方误差(MSE)或者残差平方和(SSE)来作为损失函数。在这里,我们选择SSE作为损失函数,其表达式为:
S S E L o s s ( β ) = ∣ ∣ Y − X β ∣ ∣ 2 2 = ( Y − X β ) T ( Y − X β ) SSELoss( \beta) = ||Y- X \beta||_2^2 = (Y- X \beta)^T(Y- X \beta) SSELoss(β)=∣∣Y−Xβ∣∣22=(Y−Xβ)T(Y−Xβ)
我们的目标是找到一组β,使得SSE最小。
其中:
使用最小二乘法求解损失函数的一般过程是对损失函数求导,然后令导数等于0,解出使得损失函数最小的参数值。对上述的SSE求导,我们可以得到:
∂
S
S
E
∂
β
=
∂
∣
∣
Y
−
X
β
∣
∣
2
2
∂
β
=
∂
(
Y
−
X
β
)
T
(
Y
−
X
β
)
∂
β
=
∂
(
Y
T
−
β
T
X
T
)
(
Y
−
X
β
)
∂
β
=
∂
(
Y
T
Y
−
β
T
X
T
Y
−
Y
T
X
β
+
β
T
X
T
X
β
)
∂
β
=
0
−
X
T
Y
−
X
T
Y
+
X
T
X
β
+
(
X
T
X
)
T
β
=
0
−
X
T
Y
−
X
T
Y
+
2
X
T
X
β
=
2
(
X
T
X
β
−
X
T
Y
)
=
0
令上式等于0,我们可以求解出β的值为:
β ^ = ( X T X ) − 1 X T Y \hat{\beta} = (X^TX)^{-1}X^TY β^=(XTX)−1XTY
这就是最小二乘法求解多元线性回归的一般过程。需要注意的是,这个公式假设 X T X X^TX XTX 是可逆的。如果不可逆,那么我们就需要引入正则化项或者使用其他方法来求解β。
我们可以通过两种形式进行最小二乘法计算,除了借助NumPy中矩阵运算的函数进行最小二乘法计算以外,NumPy中也有独立的用于计算最小二乘法的函数:np.linalg.lstsq
。通过该方法,我们能够在直接输入特征矩阵和标签数组的情况下进行最小二乘法的计算,并在得出最小二乘法计算结果的同时,也得到一系列相应的统计指标结果。
import numpy as np # 定义输入矩阵X,我们添加了一个全为1的列作为截距项 X = np.array([ [1, 100, 3], [1, 150, 4], [1, 200, 5], [1, 250, 6], ]) # 定义目标向量Y Y = np.array([300, 400, 500, 600]) # 根据最小二乘法公式计算参数beta beta_hat = np.linalg.inv(X.T @ X) @ X.T @ Y print(beta_hat)
输出如下:
Result from np.linalg.lstsq: [-6.95440004e-14 1.25000000e+00 5.00000000e+01]
Result from manual calculation: [3.32534e-11 1.25000e+00 5.00000e+01]
解读:np.linalg.lstsq函数得到的结果是[-6.95440004e-14, 1.25000000e+00, 5.00000000e+01],而手动计算最小二乘法得到的结果是[3.32534e-11, 1.25000e+00, 5.00000e+01]。从这两个结果可以看出,两者的结果非常接近,几乎相同。
这两个结果的含义是,在这个线性回归模型中,房子的面积对房价的影响是每平方米增加1.25万元,房间数量对房价的影响是每增加一个房间,房价增加50万元。
第一个元素(接近于0的值)是截距项。由于我们在设计矩阵X时,添加了一列全为1的列,所以在求解参数时,会包含一个截距项。在这个例子中,截距项接近于0,说明当房子的面积和房间数量都为0时,预测的房价也接近于0,这与我们的常识是相符的。
这个结果还说明,我们的数据集是线性无关的,因此使用np.linalg.lstsq函数和最小二乘法公式都能得到相同的结果。如果数据集中存在线性相关的列,那么使用最小二乘法公式可能会得到不准确的结果,因为矩阵X.T @ X可能不是满秩的,不能求逆。在这种情况下,使用np.linalg.lstsq函数是更好的选择,因为它可以处理这种情况,比如如下这种情况:
import numpy as np # 定义输入矩阵X,我们添加了一个全为1的列作为截距项 X = np.array([ [1, 100, 3], [1, 150, 4], [1, 200, 5], [1, 250, 6], ]) # 定义目标向量Y Y = np.array([300, 400, 500, 600]) # 使用np.linalg.lstsq函数来求解beta beta_hat, residuals, rank, s = np.linalg.lstsq(X, Y, rcond=None) print('Result from np.linalg.lstsq:', beta_hat) # 根据最小二乘法公式计算参数beta beta_hat_manual = np.linalg.inv(X.T @ X) @ X.T @ Y print('Result from manual calculation:', beta_hat_manual)
输出如下:
Result from np.linalg.lstsq: [49.990002 0.99980004 50.009998 ]
Result from manual calculation: [-5800. 10.9375 700. ]
这两种计算方法的结果差异主要源于输入数据的性质。具体来说,np.linalg.lstsq和手动计算最小二乘法的结果会在数值上有所差异,这主要是因为输入的X矩阵存在多重共线性问题。
多重共线性:在第二套代码给的数据中,房子的面积和房间数量这两个特征之间存在明显的线性关系(即,它们不是线性无关的)。换句话说,我们可以通过房子的面积预测出房间的数量,反之亦然。这种情况下,设计矩阵X的列向量就存在多重共线性,也就是说,矩阵 X T X X^TX XTX可能接近奇异(或者说,不满秩),这会导致它的逆很难计算,或者计算出的逆矩阵不稳定。
np.linalg.lstsq函数:这个函数内部使用了一种叫做奇异值分解(Singular Value Decomposition,简称SVD)的方法来求解线性最小二乘问题。SVD方法对于处理病态问题(比如,存在多重共线性的问题)具有很好的稳定性,因此,即使输入的数据存在多重共线性,np.linalg.lstsq也能得到相对合理的结果。
手动计算最小二乘法:手动计算最小二乘法的过程中,我们需要计算矩阵的逆。如果输入的数据存在多重共线性,那么 X T X X^TX XTX这个矩阵可能接近奇异,其逆矩阵很难计算,或者计算出的逆矩阵不稳定。这就导致手动计算最小二乘法的结果可能与np.linalg.lstsq的结果有较大的差异。
因此,当输入的数据存在多重共线性时,推荐使用np.linalg.lstsq来求解线性最小二乘问题。
在这篇文章中,深入了解了线性回归的理论基础,揭示了其背后的基本概念、假设和模型。探讨了机器学习建模的一般流程,包括提出基本模型、选择损失函数、以及基于损失函数性质选择优化方法。特别的详细解析了使用最小二乘法求解多元线性回归的过程,通过示例和代码实现,使理论得以具体的应用。希望你能从这篇文章中有所收获,对线性回归和最小二乘法有了更深的理解。
最后,感谢您阅读这篇文章!如果您觉得有所收获,别忘了点赞、收藏并关注我,这是我持续创作的动力。您有任何问题或建议,都可以在评论区留言,我会尽力回答并接受您的反馈。如果您希望了解某个特定主题,也欢迎告诉我,我会乐于创作与之相关的文章。谢谢您的支持,期待与您共同成长!
期待与您在未来的学习中共同成长。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。