核心点:过拟合&欠拟合,如何防止!
哈喽,我是Johngo~
在机器学习中,有一项很重要的概念,那就是:过拟合(Overfitting)和欠拟合(Underfitting)。
很长一段时间,和不少同学私信聊到过拟合和欠拟合的问题。尤其是对于初学者来说,这个有时候感觉很难把握。
过拟合和欠拟合,涉及到机器学习中常见的两种模型性能问题,分别表示模型在训练数据上表现得过于复杂或过于简单。
下面咱们先来简单聊聊关于过拟合和欠拟合的特征,以及防止性能问题的方法。
ok,咱们一起来学习一下~
简单来说,过拟合就是模型在训练集上学习得太好,以至于学到了训练数据中的噪声和细节,导致模型泛化能力差,即模型在新的、未见过的数据上表现不佳。
通常发生在模型复杂度较高时,此时模型可能会尝试去捕捉训练数据中的每个小的特征,包括那些不具代表性的特征,而这些特征可能仅仅是由于随机噪声而存在。
这里总结过拟合4个最主要的特征~
防止过拟合的方法很多,要根据不同的情况进行不同的操作,以下总结了11种方法。
相比于之前文中的5种方式,多增加了5种,都可以作为大家使用的方式~
大家在实验中,这些方法的应用和结合,可以在一定程度上避免过拟合,从而提高模型对新数据的泛化和预测能力。
欠拟合指的就是在训练数据上没有获得足够的学习,以至于无法捕捉到数据的基本结构,既不能在训练集上表现良好,也不能在新的数据上做出准确的预测。
欠拟合通常是因为模型过于简单,没有足够的参数来学习数据的复杂性。
这里也是总结了4点,大家可以大概看下:
同样是11种最常用的方法~
在实验中,大家可以用起来~
下面,咱们通过一个具体的案例来说明过拟合现象及其解决方法。使用多项式特征和线性回归模型来演示过拟合,并展示如何通过增加正则化来减轻过拟合。
实验设置
实验说明
完整代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.metrics import mean_squared_error
# 生成数据集
np.random.seed(0)
x = np.linspace(-3, 3, 100)
y = x**2 + np.random.randn(100) * 2 + 3
X = x[:, np.newaxis] # 转换为二维数组,用于模型训练
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 创建多项式特征
poly = PolynomialFeatures(degree=10, include_bias=False)
X_poly_train = poly.fit_transform(X_train)
X_poly_test = poly.transform(X_test)
# 模型训练:线性回归
model_lr = LinearRegression()
model_lr.fit(X_poly_train, y_train)
# 模型训练:岭回归
model_ridge = Ridge(alpha=100)
model_ridge.fit(X_poly_train, y_train)
# 预测和评估
x_range = np.linspace(X.min(), X.max(), 100).reshape(-1, 1)
x_range_poly = poly.transform(x_range)
y_pred_lr = model_lr.predict(x_range_poly)
y_pred_ridge = model_ridge.predict(x_range_poly)
print("Linear Regression MSE:", mean_squared_error(y_test, model_lr.predict(X_poly_test)))
print("Ridge Regression MSE:", mean_squared_error(y_test, model_ridge.predict(X_poly_test)))
# 绘制图形
plt.scatter(X_train, y_train, color='gray', marker='o', label='Training data')
plt.scatter(X_test, y_test, color='gold', marker='x', label='Test data')
plt.plot(x_range, y_pred_lr, label='Linear Regression', color='red', linewidth=2)
plt.plot(x_range, y_pred_ridge, label='Ridge Regression', color='blue', linewidth=2)
plt.legend()
plt.xlabel('x')
plt.ylabel('y')
plt.title('Overfitting Example and Solution')
plt.grid(True)
plt.show()
过拟合的情况
很显然,大家可以看到。在未添加正则化的线性回归模型中(红色曲线),会看到模型尝试非常精确地通过每个训练数据点,导致在测试集上的表现(黄色点)较差,这就是典型的过拟合现象。
解决过拟合后的情况
引入L2正则化的岭回归模型(蓝色曲线)能够有效降低模型复杂度,虽然它不再尝试穿过所有训练数据点,但在测试集上的MSE(均方误差)有显著降低,显示出了更好的泛化能力。
这里,咱们再通过一个案例说明欠拟合的情况~
实验设置
实验说明
完整代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
# 生成数据集
np.random.seed(42)
x = np.random.rand(100) * 10 - 5 # 生成-5到5之间的随机数
y = x**3 + np.random.randn(100) * 20 + 10 # 非线性关系加上噪声
X = x.reshape(-1, 1)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
# 线性回归模型(可能导致欠拟合)
model_linear = LinearRegression()
model_linear.fit(X_train, y_train)
# 多项式回归(解决欠拟合)
poly_features = PolynomialFeatures(degree=3) # 选择三阶多项式特征
X_poly_train = poly_features.fit_transform(X_train)
X_poly_test = poly_features.transform(X_test)
model_poly = LinearRegression()
model_poly.fit(X_poly_train, y_train)
# 预测与评估
x_range = np.linspace(X.min(), X.max(), 100).reshape(-1, 1)
y_pred_linear = model_linear.predict(x_range)
y_pred_poly = model_poly.predict(poly_features.transform(x_range))
print("Linear Regression MSE:", mean_squared_error(y_test, model_linear.predict(X_test)))
print("Polynomial Regression MSE:", mean_squared_error(y_test, model_poly.predict(X_poly_test)))
# 绘制结果
plt.scatter(X_train, y_train, color='gray', marker='o', label='Training data')
plt.scatter(X_test, y_test, color='gold', marker='x', label='Test data')
plt.plot(x_range, y_pred_linear, label='Linear Regression', color='red', linewidth=2)
plt.plot(x_range, y_pred_poly, label='Polynomial Regression', color='blue', linewidth=2)
plt.legend()
plt.xlabel('x')
plt.ylabel('y')
plt.title('Underfitting Example and Solution')
plt.grid(True)
plt.show()
欠拟合的情况
在使用简单的线性回归模型中(红色曲线),由于模型复杂度不足以捕捉底层数据的非线性关系,导致在训练集和测试集上的表现都不理想,这就是典型的欠拟合现象。
解决欠拟合后的情况
通过引入多项式特征并应用线性回归模型(蓝色曲线),我们显著提高了模型的复杂度,使得模型能够更好地逼近具有非线性关系的真实数据。结果显示,多项式回归的MSE明显低于简单线性回归模型,有效地解决了欠拟合问题。