使用NumPy进行多项式拟合及拟合优度计算的正确方法
本文详细介绍如何利用NumPy的
polyfit
函数实现高阶多项式数据拟合。内容包括封装自动化评估脚本以同时获取多项式系数与R²拟合优度,深入解析权重参数理解 NumPy 的 polyfit 参数逻辑
np.polyfit(x, y, deg, w=None) 是NumPy提供的标准加权最小二乘拟合工具。初学者常因文档表述产生误解,此处明确核心参数的实际行为:
x与y:一维数据集,分别代表自变量与目标因变量。deg(阶数):整数,直接指定多项式的最高次幂。例如需要拟合二次曲线(y = ax² + bx + c),传入的值应为 2,而非次数加 1。w(权重):可选的一维数组,长度需与x一致。拟合过程中,每个数据点的残差平方项会乘以对应的权重值。赋予较高权重的点会在计算中被视为误差容忍度更低的核心依据。

封装拟合引擎并计算 R² 指标
在实际工程应用中,除了获得多项式系数外,我们往往需要同步验证模型的可靠性。以下代码提供了一个完整的封装方案,它不仅能生成预测序列,还能基于残差统计自动输出决定系数(R²),帮助快速判断过拟合或欠拟合状态。
import numpy as np
def poly_fit_with_r2(x, y, deg, weight=None):
# 数据量必须大于阶数,否则方程欠定无法求解
if len(x) <= deg:
raise ValueError("样本数量不能超过多项式阶数")
# 1. 执行拟合,返回从高次到低次的系数列表
coefficients = np.polyfit(x, y, deg, w=weight)
p = np.poly1d(coefficients)
# 2. 获取拟合序列与残差向量
y_pred = p(x)
residuals = y - y_pred
# 3. 计算总离差平方和 (SStotal),注意均值中心的偏移
ss_resid = np.sum(residuals ** 2)
ss_tot = np.sum((y - np.mean(y)) ** 2)
# 4. 防御性处理:当所有 y 值相同时分母为零,此时模型完美捕获趋势
r_squared = 1 - (ss_resid / ss_tot) if ss_tot != 0 else 1.0
return coefficients, r_squared, y_pred
# 模拟测试:构建带有随机扰动的二次函数关系
np.random.seed(42)
x_data = np.arange(0, 5, 0.1)
z_true = 2 + 3*x_data + 4*(x_data**2)
y_noise = np.array([np.random.normal(val, 3) for val in z_true])
coeffs, score, fitted_vals = poly_fit_with_r2(x_data, y_noise, 2)
print(f"拟合优度 R²: {score:.4f}")
print(f"还原系数: {np.round(coeffs, 2)}")利用权重 Hack 强制多项式过原点
在物理建模或特定业务场景中,有时必须保证拟合曲线经过某个已知关键点(如时间轴的零点 (0,0))。由于polyfit本身不支持硬性约束,可以通过添加一个带有巨大惩罚权重的虚拟数据点来“欺骗”算法,使其轨迹必然穿过该坐标。
# 假定原始数据与权重
force_origin_x = np.append(x_data, 0)
force_origin_y = np.append(y_noise, 0)
force_origin_w = np.append(weight, 1e8) # 赋予极大的权重压制偏离
forced_coeffs, _, forced_y = poly_fit_with_r2(force_origin_x, force_origin_y, 2, weight=force_origin_w)
# 此时的曲线将极度贴合 (0,0) 附近区域关键注意事项
在进行数值拟合前,请务必对数据进行基础的清洗工作。异常值或数量级差异极大的特征点会严重扭曲最优解的方向。此外,当尝试过高阶多项式(如 deg > 5)时,即便 R² 接近 1,也极易引发龙格现象(Runge's phenomenon)导致曲线在边缘剧烈震荡。建议优先选择平滑的物理模型并结合交叉验证进行选择。以上就是如何使用NumPy进行多项式拟合及评估的详细内容,更多关于Python数据科学进阶技巧的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









