线性回归(概述及案例)
线性回归(概述及案例)
线性回归是机器学习中用于预测分析的一种基本算法,特别是在统计学习中应用广泛。本文将从理论到实践,详细介绍线性回归的基本概念、数学原理以及实际应用案例。
线性回归概述
线性回归旨在建立自变量(输入的特征)与因变量(预测的目标)之间的线性关系模型。线性回归模型可分为单变量线性回归和多变量线性回归(也称多元线性回归)。
单变量线性回归
当只有一个自变量时,线性回归模型可以表示为:
$$
y = \beta_0 + \beta_1x + \epsilon
$$
其中:
- $y$:因变量,即要预测的变量。
- $x$:自变量,即预测所基于的特征。
- $\beta_0$:截距项,也称为偏置。
- $\beta_1$:斜率,表示自变量$x$与因变量$y$之间的线性关系强度。
- $\epsilon$:误差项,表示模型的随机干扰。
多变量线性回归
当有多个自变量时,线性回归模型可以推广为:
$$
y = \beta_0 + \beta_1x_1 + \beta_2x_2 + ... + \beta_nx_n + \epsilon
$$
其中:
- $x_1, x_2, ..., x_n$:自变量,预测所基于的多个特征。
- $\beta_0, \beta_1, ..., \beta_n$:模型参数,包含截距和每个自变量的系数。
- $\epsilon$:误差项。
在进行线性回归分析时,我们通常的目标是找到最适合数据的线性模型,即确定模型参数$\beta_0, \beta_1, ..., \beta_n$的值,使得模型对训练数据的拟合度最高,即使得误差项$\epsilon$的值尽可能小。最常用的方法是最小二乘法,其核心思想是最小化预测值与实际值之差的平方和,即最小化下面的目标函数:
$$
\text{MSE}(\beta) = \frac{1}{m} \sum_{i=1}^{m}(y^{(i)} - \hat{y}^{(i)})^2
$$
其中:
- $m$:样本数量。
- $y^{(i)}$:第$i$个样本的真实值。
- $\hat{y}^{(i)}$:第$i$个样本的预测值,根据线性模型计算得出。
通过数学方法,比如解析解(直接利用公式求解)或迭代方法(如梯度下降法),可以求出使得目标函数最小的参数值。
线性回归的优点主要包括模型简单、易于理解和实现,计算效率高。其缺点是无法很好地处理非线性关系和复杂的交互作用。在实际应用中,数据预处理和特征选择是提高线性回归模型表现的关键步骤。
案例一:单变量线性回归
假设我们要根据房子的大小(平方米)来预测其市场价格(万元)。首先,我们需要收集一些历史数据,这些数据可能来自于房地产市场的成交记录。我们可以得到一个数据集,示例如下:
- 房子1:80平米,价格:600万元。
- 房子2:120平米,价格:900万元。
- 房子3:100平米,价格:750万元。
- 房子4:200平米,价格:1500万元。
- ...
在这个例子中,房子的大小是自变量$x$,房价是因变量$y$。我们要建立一个线性模型来描述这两者之间的关系。模型可以表示为:
$$
y = \beta_0 + \beta_1x
$$
现在我们需要使用收集到的历史数据来估计模型参数$\beta_0$(截距)和$\beta_1$(斜率)。为了简化说明,假设我们通过某种方法(如最小二乘法)计算出来的参数估计值为$\beta_0 = 100$万元和$\beta_1 = 7$万元/平米。那么我们的预测模型就是:
$$
y = 100 + 7x
$$
这意味着,如果我们要预测一个70平米的房子的价格,我们可以将70代入$x$得到:
$$
\hat{y} = 100 + 7 \times 70 = 590
$$
所以,根据我们的模型,一个70平米的房子的预测价格是590万元。
代码实践
在实践中,会用更多的数据和更复杂的特征(例如房龄、位置、楼层、朝向等),并通过计算机程序(比如使用Python的scikit-learn库)来自动处理数据,计算模型参数。利用这样的模型,我们就可以基于给定的特征来预测房价。
这里,将创建一个房屋大小的数据集,然后根据一个假设的线性关系添加一些随机扰动,以生成相应的房价数据。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
# 生成随机数据
np.random.seed(0)
size = np.random.normal(100, 20, 200).reshape(-1, 1) # 房子大小的特征,正态分布
noise = np.random.normal(0, 50, 200) # 随机噪声
price = 100 + 5 * size[:, 0] + noise # 假设的真实房价公式
# 划分训练集和测试集
size_train, size_test, price_train, price_test = train_test_split(size, price, test_size=0.2, random_state=0)
# 创建线性回归模型实例
reg = LinearRegression()
# 训练模型
reg.fit(size_train, price_train)
# 预测结果
price_pred = reg.predict(size_test)
# 绘制散点图:训练集
plt.scatter(size_train, price_train, color='blue', label='训练集')
# 绘制散点图:测试集
plt.scatter(size_test, price_test, color='green', label='测试集')
# 绘制回归线
plt.plot(size_test, price_pred, color='red', linewidth=3, label='预测房价')
# 添加标题和坐标轴标签
plt.title('房价预测模型')
plt.xlabel('房屋大小(平方米)')
plt.ylabel('房屋价格(万元)')
plt.legend()
# 显示图形
plt.show()
在这段代码中,先是创建了200个数据点来模拟房屋大小和价格的数据集。之后,利用train_test_split
函数将数据分为训练集和测试集,其中80%用作训练集,20%用作测试集。
接着,使用训练集训练了线性回归模型,并在测试集上进行了预测。构建模型和绘图的步骤与之前相同,不同之处在于数据量更大,且带有噪声,这更符合现实世界数据的情况。
最后,代码绘制了包含训练集和测试集的散点图,以及线性回归模型预测的房价曲线。
案例二:多变量线性回归
举一个多变量线性回归的实际例子,假如我们想要研究房价($y$)与房屋的各种特征之间的关系,比如房屋的面积($x_1$)、房龄($x_2$)、房屋的所在区域($x_3$,可以是虚拟变量,例如市中心=1,郊区=0)等等。那么多变量线性回归模型可能如下所示:
$$
\text{房价} = \beta_0 + \beta_1 \times \text{面积} + \beta_2 \times \text{房龄} + \beta_3 \times \text{区域} + \epsilon
$$
在这个模型中:
- 房价是因变量。
- 面积、房龄和区域是自变量。
- $\beta_0$是常数项,可能代表在不考虑所有其他因素的情况下的基础房价。
- $\beta_1, \beta_2, \beta_3$分别是房屋面积、房龄和区域对房价的影响系数。
- $\epsilon$代表了模型无法解释的随机误差。
在拟合了这样的模型之后,我们可以通过分析回归系数来了解不同因素对房价的具体影响。比如,如果$\beta_1$的值为正,那么我们可以解释为房屋面积每增加一个单位,房价平均会增加$\beta_1$个单位。同理,$\beta_2$和$\beta_3$的正负和大小也分别反映了房龄和区域对房价的平均影响。
代码实践
以下是一个代码示例,说明如何使用Python进行数据模拟,并拟合一个多变量线性回归模型。代码的末尾会使用matplotlib
库来显示一个三维坐标图,因为展示所有自变量的坐标图可能在多于两个维度时变得复杂,所以通常只选择两个自变量来可视化。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from mpl_toolkits.mplot3d import Axes3D
# 生成随机数据
np.random.seed(0)
X = np.random.rand(100, 2) # 生成100个样本,每个样本有2个特征(代表面积和房龄)
beta = np.array([3, 5]) # 假定面积和房龄的真实回归系数分别为3和5
y = X.dot(beta) + np.random.randn(100) * 0.5 # 生成房价数据并添加随机噪声
# 创建线性回归模型
model = LinearRegression()
# 训练模型
model.fit(X, y)
# 打印回归系数
print("截距项:", model.intercept_)
print("回归系数:", model.coef_)
# 预测值
y_pred = model.predict(X)
# 绘制三维散点图
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 画出实际的点
ax.scatter(X[:, 0], X[:, 1], y, color='b', marker='o', s=15, label='Actual data')
# 画出预测的面
x0_surf, x1_surf = np.meshgrid(np.linspace(X[:, 0].min(), X[:, 0].max(), 20), np.linspace(X[:, 1].min(), X[:, 1].max(), 20))
y_surf = model.intercept_ + x0_surf * model.coef_[0] + x1_surf * model.coef_[1]
ax.plot_surface(x0_surf, x1_surf, y_surf, color='r', alpha=0.3)
ax.set_xlabel('Area')
ax.set_ylabel('Age')
ax.set_zlabel('Price')
ax.legend()
plt.show()
上面的代码中,我们假设了面积(Area
)和房龄(Age
)是自变量,房价(Price
)是因变量。散点图显示了实际的数据点,而平面代表了我们的回归模型预测出的房价。这个图可以帮助我们直观地理解我们的模型是如何在三维空间中进行数据拟合的。
输出的结果与模型如下: