机器学习系列四【多项式回归与特征工程】

机器学习系列四:打破线性束缚——多项式回归与特征工程

欢迎来到“机器学习系列”的第四篇文章!在前面的文章中,我们学习了线性回归(预测连续数值)和逻辑回归(解决二分类问题)。你可能会发现,无论是拟合一条直线,还是画出一条笔直的分类决策边界,我们都在处理“线性”关系。

但在真实的物理世界和商业场景中,数据往往不会乖乖地排成一条直线。如果数据呈现出弯曲的 U 型、S 型或更复杂的波浪形,我们手中的线性模型是不是就彻底失效了?

并非如此!今天,我们将学习一种极其巧妙的“欺骗”模型的方法——特征工程(Feature Engineering),并借此引出我们对付非线性数据的利器:多项式回归(Polynomial Regression)


1. 现实世界的痛点:非线性关系

想象一下我们在预测某款手机电池的寿命(因变量 $y$)与充电次数(自变量 $x$)之间的关系。在最初的几百次充电中,电池寿命可能下降得很慢;但一旦超过某个临界点,寿命可能会呈现断崖式下跌。

如果我们在散点图上把这些数据画出来,它绝对不是一条直线,而是一条向下弯曲的曲线。这时候,如果我们强行用 $h_\theta(x) = \theta_0 + \theta_1 x$ 去拟合,误差将会大得惊人。这种模型在训练集和测试集上表现都很差的情况,被称为欠拟合(Underfitting)

我们需要一条曲线。但问题是,线性回归只能画直线,怎么办?


2. 魔法时刻:什么是多项式回归?

多项式回归的核心思想非常简单且粗暴:既然特征不够,那我们就自己制造特征!

我们可以人为地把原有特征的平方、立方甚至更高次方,当作“全新”的特征喂给模型。例如,原本我们只有一个特征 $x$,现在我们增加两个新特征 $x^2$ 和 $x^3$。

我们的假设函数就变成了如下形式:

$$h_\theta(x) = \theta_0 + \theta_1 x + \theta_2 x^2 + \theta_3 x^3$$

这里有一个极其重要、也最容易让人迷惑的考点:多项式回归到底是不是线性模型?

答案是:它是线性模型! 判断一个模型是否是线性的,不是看它对输入特征 $x$ 是不是线性,而是看它对参数 $\theta$ 是不是线性。在上述公式中,如果我们把 $x^2$ 看作是一个新特征 $x_2$,把 $x^3$ 看作是一个新特征 $x_3$,公式就变成了:

$$h_\theta(x) = \theta_0 + \theta_1 x_1 + \theta_2 x_2 + \theta_3 x_3$$

这不就是我们最熟悉的多元线性回归吗?我们利用这种“升维”的魔法,在更高维度的空间里画了一个超平面,但当它投影回原本的低维空间时,就变成了一条完美的曲线!


3. 更广阔的天地:特征工程

多项式回归其实只是特征工程(Feature Engineering)中的一种基本操作。在机器学习界流传着一句名言:“数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。”

特征工程就是将原始数据转化为能更好地表达问题本质、更适合模型学习的新特征的过程。除了多项式转换,常见的特征工程还包括:

  • 交互特征(Interaction Features):不仅可以求平方,还可以把两个不同的特征相乘。比如,预测房价时,我们有“长”和“宽”两个特征,把它们相乘得到一个新特征“面积”,这个新特征对模型的帮助可能比长和宽大得多($x_3 = x_1 \times x_2$)。
  • 对数变换(Log Transformation):对于一些数值跨度极大的数据(如用户收入),取对数可以让数据分布更加平滑,减少极端值的影响。
  • 分箱/离散化(Binning):将连续的年龄数值变成“青年”、“中年”、“老年”三个类别,有时候能让模型更容易捕捉到不同群体的宏观规律。

4. 警惕多项式的反噬:高次幂与过拟合

多项式回归虽然能画出漂亮的曲线,但它也是一把双刃剑。

如果我们为了追求在训练集上的完美表现,盲目地增加特征的最高次幂(例如加到 $x^{15}$),这条曲线就会变得极其扭曲和疯狂。它会不择手段地穿过每一个训练数据点,导致模型变得极其复杂。

这就会陷入我们在《系列二》中提到的噩梦——过拟合(Overfitting)

如何解决这个问题?

  1. 控制阶数(Degree):通常情况下,2阶或3阶的多项式已经足够应对大部分场景,不要轻易尝试过高的阶数。
  2. 祭出正则化:还记得上一篇的岭回归(Ridge)和 Lasso 吗?我们可以把多项式特征生成后的数据喂给带有正则化的回归模型,让算法自动去打压那些导致曲线扭曲的无用高次幂特征的权重。

5. 总结

多项式回归和特征工程教会了我们一个重要的道理:当模型本身能力受限时,我们可以通过改变数据的表达方式来破局。

  • 多项式回归本质上依然是线性回归,但它赋予了线性模型拟合非线性数据的超能力。
  • 特征工程是连接原始数据与强大模型之间的桥梁,创造性的特征往往比复杂的算法更管用。

掌握了这些,你处理现实复杂数据的能力又上了一个台阶。


6. 实战演练:Python (Scikit-Learn) 代码——让直线“变弯”

理论听起来很神奇,但代码实现起来其实出乎意料地简单。Scikit-Learn 为我们提供了一个非常方便的工具:PolynomialFeatures

接下来,我们将自己动手生成一组明显的非线性数据(一个带有噪点的二次函数抛物线),然后分别用普通线性回归多项式回归去拟合它,看看效果有何不同。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures

# 1. 生成非线性模拟数据 (y = 0.5 * X^2 + X + 2 + 噪声)
np.random.seed(42)
m = 100 # 样本数量
X = 6 * np.random.rand(m, 1) - 3 # 生成 -3 到 3 之间的随机数
y = 0.5 * X**2 + X + 2 + np.random.randn(m, 1) # 添加正态分布的噪声

# 2. 尝试使用普通的线性回归拟合 (直线)
lin_reg = LinearRegression()
lin_reg.fit(X, y)

# 3. 使用 PolynomialFeatures 进行特征工程 (制造特征)
# degree=2 表示我们将生成 X 的二次方特征
poly_features = PolynomialFeatures(degree=2, include_bias=False)
X_poly = poly_features.fit_transform(X)

# 打印看看 X_poly 到底长什么样
print("原始的第一个特征 X:", np.round(X[0], 2))
print("升维后的特征 X_poly (包含了 X 和 X^2):", np.round(X_poly[0], 2))

# 4. 用制造出来的新特征,再次训练线性回归模型 (曲线)
poly_reg = LinearRegression()
poly_reg.fit(X_poly, y)

# 5. 可视化对比结果
# 生成密集的 X 坐标用于画平滑的预测曲线
X_new = np.linspace(-3, 3, 100).reshape(100, 1)
X_new_poly = poly_features.transform(X_new) # 别忘了对新的 X 也要做同样的特征转换

y_new_lin = lin_reg.predict(X_new) # 普通线性回归的预测结果
y_new_poly = poly_reg.predict(X_new_poly) # 多项式回归的预测结果

plt.figure(figsize=(8, 6))
plt.plot(X, y, "b.", label="Original Data") # 原始数据点
plt.plot(X_new, y_new_lin, "r-", linewidth=2, label="Linear Regression (Underfitting)") # 直线
plt.plot(X_new, y_new_poly, "g-", linewidth=2, label="Polynomial Regression (Degree=2)") # 曲线

plt.xlabel("Feature X")
plt.ylabel("Target y")
plt.title("Linear vs Polynomial Regression")
plt.legend(loc="upper left")
plt.show()

代码运行结果解析:

当你运行这段代码时,控制台和图表会告诉你两个关键信息:

  1. 升维的本质X_poly 的输出会清楚地显示,原本只有一个数值的特征,变成了两个数值(一个是 $X$ 本身,另一个是 $X^2$)。我们硬生生地凭空“捏造”出了一个新特征!
  2. 视觉的震撼:在图表中,红色的直线(普通线性回归)硬邦邦地穿过数据,显然欠拟合了,它错失了数据在两端翘起的规律;而绿色的曲线(多项式回归)则极其优雅地捕捉到了数据的抛物线趋势,完美贴合!

这,就是多项式回归的魅力。