使用 NumPy polyfit 进行多项式回归:完整指南
多项式回归是统计学和机器学习中一种强大的工具,用于建立自变量和因变量之间的非线性关系模型。当线性模型不足以描述数据中的复杂模式时,多项式回归便能派上用场。Python 的 NumPy 库提供了一个高效且易于使用的函数 polyfit,用于执行多项式回归。
本指南将深入探讨多项式回归的原理,详细介绍 NumPy polyfit 和 poly1d 的用法,并通过一个完整的示例展示如何实现多项式拟合、评估和可视化。
什么是多项式回归?
多项式回归是广义线性模型的一种特殊情况,其中自变量 x 和因变量 y 之间的关系被建模为 n 次多项式。其核心思想是,即使变量之间的关系不是线性的,我们也可以通过引入自变量的更高次幂(如 $x^2, x^3$ 等)来拟合曲线。
一个 deg 次多项式回归模型的一般形式如下:
$y = \beta_0 + \beta_1x + \beta_2x^2 + \beta_3x^3 + \dots + \beta_n x^n + \epsilon$
其中:
* $y$ 是因变量。
* $x$ 是自变量。
* $\beta_0, \beta_1, \dots, \beta_n$ 是多项式系数,我们需要通过数据拟合来估计它们。
* $n$ 是多项式的次数(degree)。
* $\epsilon$ 是误差项。
多项式回归的目标是找到最佳的多项式系数,使得模型预测值与实际观测值之间的误差最小化,通常采用最小二乘法来达成此目标。
为什么选择 NumPy polyfit?
NumPy 的 polyfit 函数是进行多项式拟合的首选工具,原因如下:
1. 效率高:作为 NumPy 库的一部分,polyfit 经过高度优化,能够快速处理大型数据集。
2. 易于使用:其接口简洁明了,只需提供 x 值、y 值和多项式次数即可。
3. 精确性:它使用最小二乘法,可以找到给定次数下的最佳拟合多项式。
4. 与 poly1d 结合使用:polyfit 返回的系数可以无缝地传递给 poly1d,创建一个可调用的多项式对象,极大地方便了后续的预测和评估。
NumPy polyfit 函数详解
numpy.polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False)
主要参数:
* x:一维数组,表示数据点的 x 坐标。
* y:一维数组,表示数据点的 y 坐标,与 x 具有相同的长度。
* deg:整数,表示拟合多项式的次数。例如,deg=1 进行线性拟合,deg=2 进行二次拟合。
* w (可选):数组,表示每个数据点的权重。如果提供,拟合将最小化加权平方误差。
返回值:
一个 NumPy 数组,包含多项式的系数。这些系数是按照降幂排列的,即 [c_n, c_{n-1}, \dots, c_1, c_0],对应于多项式 $c_n x^n + c_{n-1} x^{n-1} + \dots + c_1 x + c_0$。
NumPy poly1d 函数详解
numpy.poly1d(c_or_r, r=False, variable=None)
poly1d 是一个非常方便的类,它将 polyfit 返回的系数封装成一个可调用的多项式函数。
主要参数:
* c_or_r:通常是 polyfit 返回的多项式系数(降幂排列)。
* r (可选):如果设置为 True,则 c_or_r 被解释为多项式的根而不是系数。
返回值:
一个 poly1d 对象,可以像常规 Python 函数一样使用,传入 x 值即可计算对应的多项式值。
完整的实践示例
我们将通过一个模拟数据来演示如何使用 polyfit 和 poly1d 进行多项式回归,并可视化结果。
“`python
import numpy as np
import matplotlib.pyplot as plt
— 1. 生成模拟数据 —
假设真实数据服从一个三次多项式关系,并添加随机噪声
np.random.seed(42) # 为了结果的可复现性
x = np.linspace(-5, 5, 100) # 生成 100 个从 -5 到 5 的 x 值
true_coefficients = [-0.1, -0.5, 2, 10] # 真实的多项式系数:-0.1x^3 – 0.5x^2 + 2x + 10
y_true = true_coefficients[0]x3 + true_coefficients[1]x*2 + true_coefficients[2]x + true_coefficients[3]
y_noise = y_true + np.random.normal(0, 3, size=len(x)) # 添加均值为0,标准差为3的高斯噪声
— 2. 使用 polyfit 进行多项式拟合 —
尝试使用 3 次多项式拟合数据 (与真实模型次数相同)
degree = 3
fitted_coefficients = np.polyfit(x, y_noise, degree)
print(f”拟合得到的多项式系数 (降幂): {fitted_coefficients}”)
— 3. 使用 poly1d 创建多项式函数 —
将拟合得到的系数转换为一个可调用的多项式函数
polynomial_function = np.poly1d(fitted_coefficients)
print(f”\n拟合得到的多项式函数表达式:\n{polynomial_function}”)
— 4. 预测新数据点的值 —
使用拟合出的多项式函数在原始 x 值上进行预测
y_predicted = polynomial_function(x)
— 5. 可视化结果 —
plt.figure(figsize=(12, 7))
plt.scatter(x, y_noise, label=’原始带噪声数据’, color=’blue’, alpha=0.6, s=20)
plt.plot(x, y_true, label=’真实函数 (无噪声)’, color=’green’, linestyle=’–‘, linewidth=2)
plt.plot(x, y_predicted, label=f’拟合多项式 (次数={degree})’, color=’red’, linewidth=2)
plt.title(‘NumPy polyfit 多项式回归示例’, fontsize=16)
plt.xlabel(‘X 值’, fontsize=12)
plt.ylabel(‘Y 值’, fontsize=12)
plt.legend(fontsize=10)
plt.grid(True, linestyle=’:’, alpha=0.7)
plt.axhline(0, color=’gray’, linewidth=0.5)
plt.axvline(0, color=’gray’, linewidth=0.5)
plt.show()
— 6. 探讨不同次数多项式拟合的影响 —
print(“\n— 探讨不同次数多项式拟合的影响 —“)
degrees_to_compare = [1, 2, 3, 5, 8] # 尝试不同次数
plt.figure(figsize=(15, 9))
plt.scatter(x, y_noise, label=’原始带噪声数据’, color=’blue’, alpha=0.4, s=20)
plt.plot(x, y_true, label=’真实函数 (无噪声)’, color=’green’, linestyle=’–‘, linewidth=2)
for current_deg in degrees_to_compare:
coeffs_comp = np.polyfit(x, y_noise, current_deg)
poly_func_comp = np.poly1d(coeffs_comp)
y_pred_comp = poly_func_comp(x)
plt.plot(x, y_pred_comp, label=f’拟合多项式 (次数={current_deg})’, linewidth=1.5)
print(f”次数 {current_deg} 的拟合系数: {coeffs_comp}”)
plt.title(‘不同次数多项式拟合对比’, fontsize=16)
plt.xlabel(‘X 值’, fontsize=12)
plt.ylabel(‘Y 值’, fontsize=12)
plt.legend(fontsize=10)
plt.grid(True, linestyle=’:’, alpha=0.7)
plt.axhline(0, color=’gray’, linewidth=0.5)
plt.axvline(0, color=’gray’, linewidth=0.5)
plt.ylim(min(y_noise) – 10, max(y_noise) + 10) # 调整Y轴范围以便更好地观察
plt.show()
“`
代码解释:
- 生成模拟数据:我们定义了一个真实的三次函数,并向其添加了随机噪声,以模拟真实世界中带有观测误差的数据。这使我们能够评估拟合模型与真实潜在关系之间的接近程度。
np.polyfit(x, y_noise, degree):这是核心步骤。我们将x值、带噪声的y值以及我们希望拟合的多项式次数(这里是3)传递给polyfit。函数返回一个 NumPy 数组,其中包含从最高次幂到最低次幂排列的多项式系数。np.poly1d(fitted_coefficients):polyfit返回的系数直接用于创建一个poly1d对象。这个对象代表了拟合出的多项式,并且可以直接像函数一样调用。polynomial_function(x):通过调用poly1d对象并传入x值,我们可以获得模型对这些x值的预测y值。- 可视化:使用
matplotlib库,我们将原始的带噪声数据点、真实的潜在函数曲线以及我们拟合出的多项式曲线绘制在同一张图上。这提供了一个直观的方式来评估拟合的质量。 - 不同次数多项式拟合的影响:我们进一步展示了使用不同多项式次数(如 1 次、2 次、5 次、8 次)进行拟合的结果。这强调了选择合适多项式次数的重要性。
- 欠拟合 (Underfitting):如果选择的多项式次数过低(例如,用 1 次线性拟合来拟合三次关系),模型将过于简单,无法捕捉数据的真实模式,导致误差较大。
- 过拟合 (Overfitting):如果选择的多项式次数过高(例如,用 8 次多项式拟合三次关系),模型会变得过于复杂,不仅捕捉了数据的真实模式,还可能学习了数据中的随机噪声。这导致模型在训练数据上表现良好,但在新数据上的泛化能力差。
如何选择多项式的次数 (deg)?
选择合适的多项式次数是多项式回归中的一个关键决策,它直接影响模型的性能和泛化能力。没有一个通用的“最佳”次数,通常需要根据数据特性和问题背景进行权衡。以下是一些常用方法:
- 可视化检查:绘制不同次数的拟合曲线与原始数据,直观判断哪种次数的曲线最能捕捉数据的趋势,同时避免过度摆动。
- 残差分析:分析拟合后模型残差(实际值 – 预测值)的分布。如果残差呈现出某种模式(例如,V 形或 U 形),可能表明当前多项式次数不足以捕捉数据的非线性关系。
- 交叉验证:使用交叉验证技术(如 K 折交叉验证)来评估不同次数模型在未见过数据上的表现。选择在验证集上表现最佳的次数。
- 信息准则:赤池信息准则 (AIC) 或贝叶斯信息准则 (BIC) 等统计量可以帮助在模型复杂性和拟合优度之间找到平衡。
- 领域知识:如果对数据背后的物理或业务过程有深入了解,有时可以直接根据领域知识来确定多项式的大致次数。
局限性与注意事项
尽管多项式回归功能强大,但也有其局限性:
- 外推问题:多项式模型在拟合区间之外的表现可能非常差。当尝试预测超出训练数据范围的值时,多项式曲线可能迅速发散,给出不切实际的预测。
- 过拟合风险:如前所述,高次多项式很容易过拟合,尤其是在数据量不足或噪声较大的情况下。
- 解释性:当多项式次数较高时,模型中的每个系数的直接解释变得更加困难。
- 计算成本:虽然 NumPy 优化了计算,但随着多项式次数的增加,计算复杂性也会相应增加。
总结
NumPy 的 polyfit 和 poly1d 函数为 Python 用户提供了一个直观且高效的方式来执行多项式回归。通过理解多项式回归的原理、掌握 polyfit 的用法以及仔细选择多项式的次数,您可以构建出强大的非线性模型来解决各种数据分析和预测问题。在实践中,始终建议结合可视化和评估指标来验证您的多项式模型的拟合质量和泛化能力。