1. 从零开始:为什么你需要掌握多项式拟合?
如果你刚开始接触机器学习或者数据分析,可能会被那些听起来高大上的算法名字吓到。别担心,今天咱们聊的“多项式拟合”,其实是你入门路上最好的一块敲门砖。说白了,它就是一种用曲线去“描”数据点的方法。想象一下,你有一堆散落在纸上的点,你想画一条光滑的曲线,让它尽可能地从这些点中间穿过去,这条曲线就是“拟合”出来的。这条曲线如果是一个多项式(比如 y = a + bx + cx²),那这个过程就叫多项式拟合。
我刚开始学的时候,也觉得这玩意儿有啥用?后来在真实项目里踩过坑才发现,它的应用场景多到离谱。比如,你想预测一个产品未来几个月的销量趋势,手头只有过去一年的月度数据;或者,你在分析实验数据,想找到一个公式来描述温度和时间的关系。这些时候,一个简单的线性公式(一条直线)可能根本描述不了数据的弯曲变化,而多项式拟合就能派上大用场。它比那些复杂的深度学习模型要轻量、好理解得多,而且计算速度快,结果也直观,特别适合做快速原型验证和趋势分析。
那么,为什么我们要同时学 Numpy 和 Torch 两种实现方式呢?这就像你工具箱里得有螺丝刀和扳手一样,各有各的适用场景。Numpy 是 Python 科学计算的基石,它的实现方式非常直接,一两行代码就能出结果,适合快速验证想法、进行数据分析的前期探索。而 PyTorch 是当下深度学习领域的主流框架,用它来实现多项式拟合,看似“杀鸡用牛刀”,但实际上,这是你理解机器学习训练流程(准备数据、定义模型、计算损失、反向传播、更新参数)的绝佳起点。通过这个简单的例子,你能把深度学习的核心套路摸得一清二楚,以后再学复杂的神经网络,心里就有底了。
所以,这篇指南的目的,就是手把手带你用这两种工具,走完从生成数据、构建模型、训练优化到评估可视化的完整闭环。我会分享我实际编码时觉得好用的技巧,也会指出一些新手容易掉进去的坑。咱们不搞纯理论,就讲怎么用代码把它实实在在地做出来。
2. 用 Numpy 实现:五分钟搞定你的第一条拟合曲线
好了,理论不多说,咱们直接上手。用 Numpy 做多项式拟合,可以说是简单到令人发指。它的核心函数就是 np.polyfit,你几乎不用关心背后的数学(最小二乘法)是怎么算的,它帮你全包了。
2.1 核心三件套:生成、拟合、画图
我们先来复现并深入理解一下原始文章里的那个例子。这个过程我称之为“核心三件套”。
import numpy as np
import matplotlib.pyplot as plt
# 1. 生成模拟数据
np.random.seed(42) # 设置随机种子,确保每次运行结果一致,这是非常重要的调试习惯
x = np.sort(np.random.rand(100)) # 生成100个0到1之间的随机数,并排序
# 我们的目标是一条有起伏的曲线,这里用正弦函数加噪声来模拟真实世界的数据
y = np.sin(2 * np.pi * x) + 0.3 * np.random.randn(100)
# 2. 执行拟合 - 最关键的一行代码
# np.polyfit(x, y, 3) 的意思是:用3次多项式来拟合x和y的数据
# 它返回的是多项式各项的系数,从高次项到低次项
coefficients = np.polyfit(x, y, 3)
print(f"拟合得到的三次多项式系数为: {coefficients}")
# 输出可能类似:[ 10.2 -15.8 6.1 -0.2],对应 a*x^3 + b*x^2 + c*x + d
# 用np.poly1d将系数数组变成一个可调用的“函数”,方便后续计算y值
p = np.poly1d(coefficients)
# 3. 可视化对比
x_plot = np.linspace(0, 1, 200) # 为了画出光滑曲线,生成更密集的x值
plt.figure(figsize=(10, 6))
plt.scatter(x, y, alpha=0.6, label='原始数据 (含噪声)', color='blue')
plt.plot(x_plot, p(x_plot), 'r-', linewidth=2, label='三次多项式拟合曲线')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Numpy 多项式拟合演示')
plt.legend()
plt.grid(True, linestyle='--', alpha=0.5)
plt.show()
跑完这段代码,你就能看到一张图,蓝色的散点是我们的原始数据,那条红色的光滑曲线就是拟合出来的三次多项式。怎么样,是不是感觉数据背后的“趋势”一下子就被抓住了?这里我想强调一个细节:np.sort 对x排序。这不是必须的,但排序后的x在画图时能保证曲线是连贯的,而不是来回穿梭的折线。这个小技巧能让你的可视化结果更专业。
2.2 深入参数:不只是换个次数那么简单
原始文章里只用了3次拟合,但 np.polyfit 的魅力在于你可以轻松尝试不同的多项式次数。这里就涉及到一个核心问题:到底选几次多项式合适?
# 尝试不同的多项式次数
degrees = [1, 3, 5, 10] # 分别尝试1次(线性),3次,5次,10次
plt.figure(figsize=(12, 10))
for i, deg in enumerate(degrees):
coeffs = np.polyfit(x, y, deg)
p_func = np.poly1d(coeffs)
plt.subplot(2, 2, i+1)
plt.scatter(x, y, alpha=0.3, s=20)
plt.plot(x_plot, p_func(x_plot), 'r-', linewidth=2)
plt.title(f'多项式次数 = {deg}')
plt.grid(True, linestyle='--', alpha=0.3)
# 计算并显示R-squared,这是一个衡量拟合好坏的常用指标
# 残差平方和
residuals = y - p_func(x)
ss_res = np.sum(residuals**2)
# 总平方和
ss_tot = np.sum((y - np.mean(y))**2)
r_squared = 1 - (ss_res / ss_tot)
plt.text(0.05, 0.9, f'$R^2$ = {r_squared:.4f}', transform=plt.gca().transAxes, fontsize=10)
plt.tight_layout()
plt.show()
运行这段代码,你会看到四张子图。可以明显观察到:
- 1次(线性):曲线太简单,很多数据点的波动都没捕捉到,这就是典型的“欠拟合”。</

62

被折叠的 条评论
为什么被折叠?



