注意
转到末尾以下载完整示例代码,或通过JupyterLite或Binder在浏览器中运行此示例。
普通最小二乘法和岭回归#
普通最小二乘法:我们将演示如何在糖尿病数据集的一个特征上使用普通最小二乘法 (OLS) 模型
LinearRegression。我们对部分数据进行训练,在测试集上进行评估,并可视化预测结果。普通最小二乘法和岭回归方差:然后,我们将通过重复拟合非常小的合成样本来展示 OLS 在数据稀疏或嘈杂时如何具有高方差。岭回归
Ridge通过惩罚(收缩)系数来减少这种方差,从而使预测更加稳定。
# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause
数据加载和准备#
加载糖尿病数据集。为简单起见,我们只保留数据中的一个特征。然后,我们将数据和目标拆分为训练集和测试集。
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
X, y = load_diabetes(return_X_y=True)
X = X[:, [2]] # Use only one feature
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=20, shuffle=False)
线性回归模型#
我们创建一个线性回归模型并在训练数据上拟合它。请注意,默认情况下,模型中会添加一个截距。我们可以通过设置 fit_intercept 参数来控制此行为。
from sklearn.linear_model import LinearRegression
regressor = LinearRegression().fit(X_train, y_train)
模型评估#
我们使用均方误差和决定系数来评估模型在测试集上的性能。
from sklearn.metrics import mean_squared_error, r2_score
y_pred = regressor.predict(X_test)
print(f"Mean squared error: {mean_squared_error(y_test, y_pred):.2f}")
print(f"Coefficient of determination: {r2_score(y_test, y_pred):.2f}")
Mean squared error: 2548.07
Coefficient of determination: 0.47
绘制结果#
最后,我们在训练和测试数据上可视化结果。
import matplotlib.pyplot as plt
fig, ax = plt.subplots(ncols=2, figsize=(10, 5), sharex=True, sharey=True)
ax[0].scatter(X_train, y_train, label="Train data points")
ax[0].plot(
X_train,
regressor.predict(X_train),
linewidth=3,
color="tab:orange",
label="Model predictions",
)
ax[0].set(xlabel="Feature", ylabel="Target", title="Train set")
ax[0].legend()
ax[1].scatter(X_test, y_test, label="Test data points")
ax[1].plot(X_test, y_pred, linewidth=3, color="tab:orange", label="Model predictions")
ax[1].set(xlabel="Feature", ylabel="Target", title="Test set")
ax[1].legend()
fig.suptitle("Linear Regression")
plt.show()

在此单特征子集上,OLS 学习一个线性函数,该函数使训练数据上的均方误差最小化。我们可以通过查看测试集上的 R^2 分数和均方误差来了解它泛化的好坏。在更高的维度中,纯 OLS 经常会过拟合,尤其是当数据嘈杂时。正则化技术(如岭回归或 Lasso)可以帮助减少这种情况。
普通最小二乘法和岭回归方差#
接下来,我们通过使用一个微小的合成数据集来更清楚地说明高方差问题。我们只采样两个数据点,然后重复地向它们添加小的 Gaussian 噪声,并重新拟合 OLS 和 Ridge。我们绘制每条新线,以查看 OLS 的跳动程度,而 Ridge 由于其惩罚项而保持更稳定。
import matplotlib.pyplot as plt
import numpy as np
from sklearn import linear_model
X_train = np.c_[0.5, 1].T
y_train = [0.5, 1]
X_test = np.c_[0, 2].T
np.random.seed(0)
classifiers = dict(
ols=linear_model.LinearRegression(), ridge=linear_model.Ridge(alpha=0.1)
)
for name, clf in classifiers.items():
fig, ax = plt.subplots(figsize=(4, 3))
for _ in range(6):
this_X = 0.1 * np.random.normal(size=(2, 1)) + X_train
clf.fit(this_X, y_train)
ax.plot(X_test, clf.predict(X_test), color="gray")
ax.scatter(this_X, y_train, s=3, c="gray", marker="o", zorder=10)
clf.fit(X_train, y_train)
ax.plot(X_test, clf.predict(X_test), linewidth=2, color="blue")
ax.scatter(X_train, y_train, s=30, c="red", marker="+", zorder=10)
ax.set_title(name)
ax.set_xlim(0, 2)
ax.set_ylim((0, 1.6))
ax.set_xlabel("X")
ax.set_ylabel("y")
fig.tight_layout()
plt.show()
结论#
在第一个示例中,我们将 OLS 应用于真实数据集,展示了普通线性模型如何通过最小化训练集上的平方误差来拟合数据。
在第二个示例中,每次添加噪声时,OLS 线都会发生剧烈变化,反映出当数据稀疏或嘈杂时其高方差。相比之下,岭回归引入了一个正则化项,收缩了系数,从而稳定了预测。
像 Ridge 或 Lasso(应用 L1 惩罚)这样的技术都是提高泛化能力和减少过拟合的常用方法。当特征相关、数据嘈杂或样本量较小时,经过良好调整的 Ridge 或 Lasso 通常优于纯 OLS。
脚本总运行时间: (0 minutes 0.357 seconds)
相关示例

