线性回归与多项式特征:拟合不足与过拟合

在机器学习领域,模型的泛化能力是衡量其性能的重要指标之一。然而,在实际应用中,经常会遇到两种极端情况:拟合不足(underfitting)和过拟合(overfitting)。拟合不足指的是模型过于简单,无法捕捉数据中的复杂关系;而过拟合则是指模型过于复杂,以至于学习到了数据中的噪声,导致模型在新数据上的表现不佳。本文将通过一个具体的例子,展示如何使用线性回归模型搭配多项式特征来近似非线性函数,并探讨如何通过交叉验证来评估模型的泛化能力。

线性回归与多项式特征

线性回归是机器学习中最基本的模型之一,它假设输入特征与输出之间存在线性关系。然而,在现实世界中,很多问题的数据分布并非线性,这时候就需要引入多项式特征来增加模型的复杂度。多项式特征是通过将原始特征进行多项式变换(如平方、立方等)来生成新的特征,从而使得模型能够捕捉到更复杂的关系。

拟合不足与过拟合的示例

在本例中,尝试使用不同次数的多项式特征来拟合一个余弦函数的部分曲线。通过比较不同模型的拟合效果,可以直观地看到拟合不足和过拟合的现象。具体来说,当多项式次数较低时,模型过于简单,无法捕捉到数据中的复杂关系,导致拟合不足;而当多项式次数过高时,模型过于复杂,学习到了数据中的噪声,导致过拟合。

交叉验证与模型评估

为了定量评估模型的泛化能力,使用交叉验证的方法来计算模型在验证集上的平均平方误差(MSE)。MSE是衡量模型预测误差的常用指标,其值越小,说明模型的预测效果越好。通过对比不同模型的MSE,可以判断模型是否存在拟合不足或过拟合的问题。

代码实现

以下是使用Python的scikit-learn库来实现上述过程的代码示例。首先,定义了一个真实的函数,然后生成了一些随机样本,并添加了一些噪声。接着,使用不同次数的多项式特征来训练线性回归模型,并使用交叉验证来评估模型的性能。

import matplotlib.pyplot as plt import numpy as np from sklearn.linear_model import LinearRegression from sklearn.model_selection import cross_val_score from sklearn.pipeline import Pipeline from sklearn.preprocessing import PolynomialFeatures def true_fun(X): return np.cos(1.5 * np.pi * X) np.random.seed(0) n_samples = 30 degrees = [1, 4, 15] X = np.sort(np.random.rand(n_samples)) y = true_fun(X) + np.random.randn(n_samples) * 0.1 plt.figure(figsize=(14, 5)) for i in range(len(degrees)): ax = plt.subplot(1, len(degrees), i + 1) plt.setp(ax, xticks=(), yticks=()) polynomial_features = PolynomialFeatures(degree=degrees[i], include_bias=False) linear_regression = LinearRegression() pipeline = Pipeline([ ("polynomial_features", polynomial_features), ("linear_regression", linear_regression), ]) pipeline.fit(X[:, np.newaxis], y) # Evaluate the models using crossvalidation scores = cross_val_score(pipeline, X[:, np.newaxis], y, scoring="neg_mean_squared_error", cv=10) X_test = np.linspace(0, 1, 100) plt.plot(X_test, pipeline.predict(X_test[:, np.newaxis]), label="Model") plt.plot(X_test, true_fun(X_test), label="True function") plt.scatter(X, y, edgecolor="b", s=20, label="Samples") plt.xlabel("x") plt.ylabel("y") plt.xlim((0, 1)) plt.ylim((-2, 2)) plt.legend(loc="best") plt.title("Degree {}\nMSE = {:.2e} (+/- {:.2e})".format(degrees[i], -scores.mean(), scores.std())) plt.show()

通过上述代码,可以生成不同多项式次数下的拟合曲线,并计算出对应的MSE值。这有助于直观地理解拟合不足和过拟合的概念,并学会如何使用交叉验证来评估模型的泛化能力。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485