scikit-learn 线性回归实现与优化原理
一、scikit-learn 线性回归相关函数
LinearRegression 类
- fit(X_train, y_train) :通过正规方程(最小二乘法)训练模型,直接求解最小化损失函数的解析解。
- predict(X_test) :输入测试集特征 X_test,输出预测值。
- coef_ :返回线性回归模型的权重参数(系数 w)。
- intercept_ :返回模型的截距参数(b)。
SGDRegressor 类(随机梯度下降回归器)
- fit(X_train, y_train) :通过随机梯度下降(SGD)迭代优化损失函数,逐步逼近最优参数。需设置参数如 max_iter(最大迭代次数)、learning_rate(学习率)等。
- predict(X_test) :与 LinearRegression 类似,生成预测结果。
- coef_ 和 intercept_ :同样用于获取模型参数。
辅助函数
- sklearn.preprocessing.StandardScaler :用于特征标准化(Z-Score 归一化),减少特征尺度差异对梯度下降的影响。
二、最小损失函数(均方误差 MSE)的数学原理
线性回归的目标是最小化均方误差(Mean Squared Error, MSE),其定义为:
J ( w , b ) = 1 2 m ∑ i = 1 m ( y ( i ) − y ^ ( i ) ) 2 J(w,b)=\frac{1}{2m}\sum_{i=1}^m(y^{(i)}-\hat{y}^{(i)})^2 J(w,b)=2m1i=1∑m(y(i)−y^(i))2
其中:
- (m) 为样本数量;
- (y^{(i)}) 为第 (i) 个样本的真实值;
- (\hat{y}{(i)}=wTx^{(i)}+b) 为模型预测值;
- (J(w,b)) 是损失函数,表示预测值与真实值的平均误差平方。
优化方法
正规方程(Normal Equation)
- 适用场景 :特征维度较小时(如 (n \leq 10^4))。
- 原理 :直接对损失函数求导并令导数为零,解析解为 (w=(XTX){-1}X^Ty)。
- scikit-learn 实现 :LinearRegression 默认使用此方法。
梯度下降(Gradient Descent)
- 适用场景 :特征维度较高或数据量较大时。
- 原理 :通过迭代更新参数 (w) 和 (b),逐步降低损失函数值。参数更新公式为:
w : = w − α ∂ J ( w , b ) ∂ w , b : = b − α ∂ J ( w , b ) ∂ b w:=w-\alpha \frac{\partial J(w,b)}{\partial w}, \quad b:=b-\alpha \frac{\partial J(w,b)}{\partial b} w:=w−α∂w∂J(w,b),b:=b−α∂b∂J(w,b)
其中 (\alpha) 是学习率。
- scikit-learn 实现 :SGDRegressor 采用随机梯度下降(每次迭代随机选择一个样本更新参数)。
三、关键区别与选择建议
方法 | 优点 | 缺点 |
---|---|---|
LinearRegression | 计算快,适合小数据集 | 大数据集下矩阵逆运算计算复杂度高 |
SGDRegressor | 适合大数据集,支持在线学习 | 需调参(如学习率、迭代次数) |
实际应用中,推荐优先使用 LinearRegression;若数据量过大或需逐步更新模型,则选择 SGDRegressor。
四、完整代码示例
# 导入必要库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression, SGDRegressor
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error, r2_score# 加载数据集
diabetes = load_diabetes()
X, y = diabetes.data, diabetes.target# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 特征标准化(对梯度下降模型必需)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)# 创建模型实例
models = {"LinearRegression (Normal Equation)": LinearRegression(),"SGDRegressor (Gradient Descent)": SGDRegressor(max_iter=1000, eta0=0.01, random_state=42)
}# 训练并评估模型
results = {}
for name, model in models.items():# 训练模型(注意:SGD需要标准化后的数据)if "SGD" in name:model.fit(X_train_scaled, y_train)else:model.fit(X_train, y_train)# 预测测试集if "SGD" in name:y_pred = model.predict(X_test_scaled)else:y_pred = model.predict(X_test)# 计算指标mse = mean_squared_error(y_test, y_pred)r2 = r2_score(y_test, y_pred)results[name] = {"MSE": mse, "R²": r2, "Coef": model.coef_, "Intercept": model.intercept_}# 打印结果
for name, metrics in results.items():print(f"Model: {name}")print(f" MSE: {metrics['MSE']:.2f}")print(f" R² Score: {metrics['R²']:.2f}")print(" Coefficients:", np.round(metrics['Coef'][:3], 2), "...") # 仅显示前3个系数print(" Intercept:", np.round(metrics['Intercept'], 2), "\n")# 可视化预测结果(以LinearRegression为例)
plt.scatter(y_test, results["LinearRegression (Normal Equation)"]["Coef"] * X_test[:, 0] + results["LinearRegression (Normal Equation)"]["Intercept"], alpha=0.5, label="Predicted")
plt.scatter(y_test, y_test, alpha=0.5, label="True Value")
plt.xlabel("True Values")
plt.ylabel("Predictions")
plt.title("LinearRegression: True vs Predicted")
plt.legend()
plt.show()
五、关键步骤解释
数据集加载与划分
- 使用 load_diabetes 加载糖尿病数据集(特征为生理指标,目标为疾病进展值)。
- train_test_split 划分训练集和测试集(80% 训练,20% 测试)。
特征标准化
- StandardScaler 对数据进行 Z-Score 标准化(均值为 0,标准差为 1),梯度下降法必须标准化以加速收敛,而正规方程法无需此步骤。
模型训练
- LinearRegression :使用正规方程直接求解最优参数。
- SGDRegressor :通过随机梯度下降迭代优化,需设置 max_iter(最大迭代次数)和 eta0(初始学习率)。
评估指标
- 均方误差(MSE) :衡量预测值与真实值的平均平方误差,越小越好。
- R² Score :模型解释的方差比例,越接近 1 越好。
结果可视化
- 绘制真实值(True Value)与预测值(Predicted)的散点图,观察线性关系。
六、关键点总结
- 数据标准化 :梯度下降模型(如 SGDRegressor)对特征尺度敏感,必须标准化;正规方程法(LinearRegression)不需要。
- 模型选择 :小数据优先用正规方程,大数据或在线学习场景用梯度下降。
- 超参数调优 :SGD 需调整 learning_rate(学习率策略)和 max_iter,避免欠拟合或震荡。