大数跨境

面试官:“一换数据就崩?你看训练集?”我:“过拟合了!”导师:“用Codex把训练误差和测试误差画出来,答案一眼就清楚。”

面试官:“一换数据就崩?你看训练集?”我:“过拟合了!”导师:“用Codex把训练误差和测试误差画出来,答案一眼就清楚。” 机器学习和人工智能AI
2026-08-26
6

哈喽,大家好~

“模型在训练集上准确率都 99% 了,为什么一换数据就不行?”

这个问题,大家几乎都遇到过。因为它考察的不是某个算法,而是你是否真正理解了机器学习~

这篇文章我们就来聊聊机器学习里的一个核心能力:泛化能力

简单说,就是模型不仅能做好见过的题,还能把学到的规律应用到没见过的新数据上。

01什么是泛化能力?

我们先用一个生活中的例子理解~

如果一个学生把课本上的 100 道题答案全部背下来,考试时原题出现,他当然能考满分。但题目稍微换个数字,他就不会了。

这就是“记住训练数据”,但没有真正学会规律。

机器学习里的模型也是一样。训练集就像平时做过的题,测试集则像真正的考试。模型在新数据上的表现,才体现了它的泛化能力。

通常我们会把数据分成:

  • 训练集:用来学习模型参数;
  • 验证集:用来选择模型结构和超参数;
  • 测试集:最后评估模型的真实表现。

模型在训练集上表现很好,但在测试集上表现很差,这种情况叫做过拟合

反过来,如果训练集和测试集表现都很差,说明模型过于简单,连训练数据中的基本规律都没有学会,这叫做欠拟合

一句话概括:泛化能力强的模型,训练误差不一定最低,但测试误差通常比较稳定。

02泛化能力背后的原理

假设我们希望模型学习一个真实规律  ,其中   是数据本身的规律,  是噪声。

模型最终的预测误差,通常可以理解为三部分:

这里的含义是:

  • 偏差:模型太简单,无法表达真实规律;
  • 方差:模型太复杂,过度依赖当前训练集;
  • 不可约误差:数据本身的噪声,模型无法消除。

比如用一条直线拟合明显弯曲的数据,偏差会很大;如果用一个次数很高的多项式,模型甚至会把每个噪声点都连起来,方差就会变大。

我们训练模型时真正关心的不是训练误差:

而是模型在未知数据上的期望误差:

前一个公式计算模型在手头数据上的平均损失,后一个公式描述模型面对真实数据分布时的平均损失。

当然,真实分布   我们拿不到,所以只能通过验证集、测试集和交叉验证来近似判断。

03观察过拟合

下面我们构造一组带噪声的正弦数据,再使用不同次数的多项式回归进行拟合。

模型复杂度较低时,可能学不出曲线;复杂度太高时,又会开始追着噪声跑。

我们用两张图观察这个过程:

  1. 左图比较低阶模型和高阶模型的拟合效果;
  2. 右图展示多项式次数变化时,训练误差和测试误差的变化。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import Ridge
from sklearn.metrics import mean_squared_error

np.random.seed(42)

# 数据:真实规律是 sin 曲线,同时加入噪声
X = np.linspace(010160).reshape(-11)
y = np.sin(X[:, 0]) + 0.25 * np.random.randn(len(X))

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=7
)

degrees = range(116)
train_errors, test_errors = [], []
models = {}

for degree in degrees:
    # Ridge 可以抑制过高阶多项式带来的参数爆炸
    model = make_pipeline(
        PolynomialFeatures(degree),
        Ridge(alpha=0.01)
    )
    model.fit(X_train, y_train)

    train_pred = model.predict(X_train)
    test_pred = model.predict(X_test)

    train_errors.append(mean_squared_error(y_train, train_pred))
    test_errors.append(mean_squared_error(y_test, test_pred))
    models[degree] = model

x_line = np.linspace(010500).reshape(-11)

fig, axes = plt.subplots(12, figsize=(145))

# 图一:低复杂度与高复杂度模型的拟合结果
axes[0].scatter(X_train, y_train, color="#00B4D8",
                label="Train data", alpha=0.75)
axes[0].scatter(X_test, y_test, color="#FF006E",
                label="Test data", alpha=0.85)

for degree, color in [(2"#06D6A0"), (14"#8338EC")]:
    axes[0].plot(
        x_line,
        models[degree].predict(x_line),
        color=color,
        linewidth=3,
        label=f"Degree {degree}"
    )

axes[0].set_title("Model complexity and fitting")
axes[0].set_xlabel("x")
axes[0].set_ylabel("y")
axes[0].legend()

# 图二:训练误差与测试误差
axes[1].plot(degrees, train_errors, "o-",
             color="#118AB2", linewidth=2.5, label="Train MSE")
axes[1].plot(degrees, test_errors, "o-",
             color="#EF476F", linewidth=2.5, label="Test MSE")

best_degree = degrees[np.argmin(test_errors)]
axes[1].axvline(best_degree, color="#FF9F1C",
                linestyle="--", linewidth=2,
                label=f"Best degree = {best_degree}")

axes[1].set_title("Generalization error curve")
axes[1].set_xlabel("Polynomial degree")
axes[1].set_ylabel("Mean squared error")
axes[1].legend()

plt.tight_layout()
plt.show()

左图中,2 次多项式通常比较平滑,可能无法充分表达正弦曲线,属于偏差较大的情况。14 次多项式会努力穿过更多训练点,曲线可能出现剧烈波动,这就是模型开始记忆噪声。

右图更直观:随着模型复杂度增加,训练误差通常持续下降;但测试误差往往先下降、后上升。测试误差最低的位置,就是当前数据下泛化效果相对较好的复杂度。

这也是机器学习中非常重要的现象:训练误差最低的模型,不一定是泛化能力最强的模型。

04如何提升泛化能力?

我们这里可以从几个方向入手。

第一,增加有效数据。数据越丰富,模型越不容易把偶然噪声当成规律。

第二,控制模型复杂度。例如降低树的深度、减少神经网络参数,或者使用正则化。

以 Ridge 回归为例,它会在原始损失后增加参数惩罚:

其中   控制惩罚强度。  越大,模型越倾向于使用较小的参数,从而减少过拟合。

第三,使用交叉验证。把训练数据分成多份,轮流训练和验证,可以减少一次划分带来的偶然性。

第四,不要反复查看测试集再调参。测试集应该像真正的期末考试,只在最后使用一次,否则测试集也会逐渐变成“训练资料”。

总结

泛化能力,就是模型从已知数据中学习规律,并在未知数据上保持稳定表现的能力。模型太简单会欠拟合,模型太复杂会过拟合,真正合适的模型通常处在两者之间。

接下来你可以尝试修改代码中的噪声大小,观察测试误差如何变化;也可以把 Ridge 换成普通线性回归,对比正则化对泛化能力的影响。总之,评价一个模型不能只看训练集分数,更要看它面对新数据时是否依然可靠。

【声明】内容源于网络
0
0
机器学习和人工智能AI
让我们一起期待 AI 带给我们的每一场变革!推送最新行业内最新最前沿人工智能技术!
内容 381
粉丝 0
机器学习和人工智能AI 让我们一起期待 AI 带给我们的每一场变革!推送最新行业内最新最前沿人工智能技术!
总阅读5.0k
粉丝0
内容381