在实际应用中,许多问题都包含多个特征(输入变量),而不仅仅是单个输入变量。多元线性回归是线性回归的扩展,它能够处理多个输入特征并建立它们与目标变量的线性关系。本教程将系统性推演多元线性回归,包括向量化处理、特征放缩、梯度下降的收敛性和学习率选择等,并使用numpy
实现。最后,我们会通过sklearn
快速实现多元线性回归模型。
多元线性回归模型简介
多元线性回归的模型公式为:
y
=
X
⋅
w
+
b
y = X \cdot w + b
y=X⋅w+b
其中:
- ( y ) 是预测值(输出),
- ( X ) 是输入特征矩阵(每一行表示一个样本,每一列表示一个特征),
- ( w ) 是权重向量,
- ( b ) 是偏置项(通常看作一个常数项)。
模型的目标是找到最优的权重向量 ( w ) 和偏置 ( b ),使得预测值与真实值的差异最小。
向量化处理
在机器学习中,向量化是一种通过矩阵运算来加速模型训练的方式。我们将模型的多个样本和特征表示为矩阵形式,这样能够利用线性代数库(如 numpy
)中的优化操作来加速计算。
多元线性回归的预测可以用向量化表示为:
Y
pred
=
X
⋅
w
+
b
Y_{\text{pred}} = X \cdot w + b
Ypred=X⋅w+b
其中:
- ( X ) 是 ( n \times m ) 的矩阵,表示 ( n ) 个样本的 ( m ) 个特征,
- ( w ) 是 ( m \times 1 ) 的权重向量,
- ( b ) 是常数偏置项。
损失函数
我们依然使用**均方误差(MSE, Mean Squared Error)**作为损失函数,用来衡量模型预测值与真实值之间的差异。其公式为:
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−yi^)2
特征放缩(Feature Scaling)
在多元线性回归中,特征的尺度对模型训练的影响较大。如果某些特征的值范围过大,会导致它们在梯度下降中主导权重更新,导致收敛速度变慢甚至无法收敛。因此,通常会对特征进行标准化或归一化。
- 归一化(Normalization):将特征缩放到[0, 1]区间,公式如下:
X ′ = X − X min X max − X min X' = \frac{X - X_{\text{min}}}{X_{\text{max}} - X_{\text{min}}} X′=Xmax−XminX−Xmin
- 标准化(Standardization):将特征的均值归零,标准差为1,公式如下:
X ′ = X − μ σ X' = \frac{X - \mu}{\sigma} X′=σX−μ
梯度下降的收敛性
在使用梯度下降优化模型参数时,梯度下降的收敛性取决于学习率的选择和损失函数的性质。如果学习率过大,梯度下降可能会在更新中超出最优值;学习率过小,收敛速度会非常慢。通常我们需要通过实验选择合适的学习率。
代码实现:多元线性回归模型
接下来,我们使用numpy
从头实现多元线性回归模型。
数据准备
我们生成一个包含多个特征的数据集。
import numpy as np
import matplotlib.pyplot as plt
# 生成多元数据
np.random.seed(42)
X = 2 * np.random.rand(100, 3) # 生成 100 个样本,3 个特征
true_w = np.array([3, 4, 5])
y = X.dot(true_w) + 6 + np.random.randn(100) # y = 3x1 + 4x2 + 5x3 + 6 + 噪声
# 查看数据维度
print("X shape:", X.shape)
print("y shape:", y.shape)
损失函数
实现均方误差损失函数:
def mse_loss(y_true, y_pred):
return np.mean((y_true - y_pred) ** 2)
梯度计算
实现梯度计算函数:
def compute_gradients(X, y, w, b):
n = len(y)
y_pred = X.dot(w) + b
dw = (2/n) * X.T.dot(y_pred - y)
db = (2/n) * np.sum(y_pred - y)
return dw, db
梯度下降
我们定义梯度下降函数,更新权重和偏置:
def gradient_descent(X, y, w, b, learning_rate, iterations):
for i in range(iterations):
dw, db = compute_gradients(X, y, w, b)
w -= learning_rate * dw
b -= learning_rate * db
if i % 100 == 0:
y_pred = X.dot(w) + b
loss = mse_loss(y, y_pred)
print(f"Iteration {i}: Loss = {loss}")
return w, b
特征放缩
我们可以通过 StandardScaler
对特征进行标准化。
def standardize(X):
mean = np.mean(X, axis=0)
std = np.std(X, axis=0)
X_scaled = (X - mean) / std
return X_scaled
模型训练
初始化参数并训练模型:
# 初始化参数
w = np.random.randn(3)
b = np.random.randn(1)
# 特征标准化
X_scaled = standardize(X)
# 超参数设置
learning_rate = 0.01
iterations = 1000
# 训练模型
w_trained, b_trained = gradient_descent(X_scaled, y, w, b, learning_rate, iterations)
print(f"Trained weights: {w_trained}, Trained bias: {b_trained}")
可视化模型
对于多元回归,权重无法直接用图像展示,但可以展示损失值的收敛曲线:
# 绘制损失曲线
losses = []
for i in range(1000):
dw, db = compute_gradients(X_scaled, y, w, b)
w -= learning_rate * dw
b -= learning_rate * db
y_pred = X_scaled.dot(w) + b
loss = mse_loss(y, y_pred)
losses.append(loss)
plt.plot(losses)
plt.xlabel("Iterations")
plt.ylabel("Loss")
plt.title("Loss Curve")
plt.show()
使用 sklearn
实现多元线性回归
最后,我们使用sklearn
快速实现多元线性回归。
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
# 特征标准化
scaler = StandardScaler()
X_scaled_sklearn = scaler.fit_transform(X)
# 训练模型
lin_reg = LinearRegression()
lin_reg.fit(X_scaled_sklearn, y)
# 输出权重和偏置
print(f"Sklearn Trained weights: {lin_reg.coef_}, Sklearn Trained bias: {lin_reg.intercept_}")
总结
在本教程中,我们深入推演了多元线性回归的基本原理,从向量化、特征放缩、梯度下降收敛性到学习率选择,并使用numpy
实现了完整的多元线性回归模型。通过sklearn
的实现,我们验证了结果并加速了训练流程。希望这篇教程能帮助你进一步理解多元线性回归模型的核心概念。