You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获得准确多项式回归结果 解决水盐度传感器拟合失真问题

水体盐度传感器拟合曲线失真问题解决方案

问题背景

研发测量单位为ppm的水体盐度传感器,已完成实验数据采集,需拟合适配数据关联关系的曲线实现盐度预测功能。调整多项式拟合的阶数等参数后,生成的拟合曲线始终无法准确反映实际数据变化规律。

现有实现代码

import numpy
import matplotlib.pyplot as plt
from sklearn.metrics import r2_score

deg = 4

x =  [26500, 18550, 12600, 8000, 4760, 3800, 3140, 2810, 2580, 2550, 2540]
y =  [0, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000]

mymodel = numpy.poly1d(numpy.polyfit(x, y, deg))

myline = numpy.linspace(26500, 2540, 40)

plt.title("R Squared = " + str(r2_score(y, mymodel(x))))
plt.scatter(x, y)
plt.plot(myline, mymodel(myline))
plt.show()

数据集说明

  • x:传感器输出读数,取值为 [26500, 18550, 12600, 8000, 4760, 3800, 3140, 2810, 2580, 2550, 2540]
  • y:对应读数下的溶液盐度值(单位:ppm),取值为 [0, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000]

核心问题原因

  1. 模型选型错误:高次多项式本身不适合拟合该类数据。从散点分布可以看出,传感器读数随盐度升高单调下降,低浓度段读数变化快、高浓度段读数变化极慢,属于典型的非线性单调关系。4次多项式会在数值密集的高浓度区间(x集中在2500~3200范围)产生龙格振荡,完全违背传感器输出的单调特性。
  2. 数值误差干扰:x原始值为万级量级,高次幂计算时会产生极大的数值截断误差,进一步放大拟合系数的失真程度。

解决方法

  1. 替换拟合模型:放弃无约束高次多项式,选择符合盐度传感器物理特性的单调模型。电导率原理的盐度传感器输出与盐度满足反比例类函数关系,不会出现非物理的振荡问题。
  2. 修正拟合流程:使用非线性最小二乘拟合自定义的单调模型,避免高次项的数值误差。

可直接运行的修正代码

import numpy
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from sklearn.metrics import r2_score

# 转成numpy数组格式便于计算
x = numpy.array([26500, 18550, 12600, 8000, 4760, 3800, 3140, 2810, 2580, 2550, 2540], dtype=float)
y = numpy.array([0, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000], dtype=float)

# 定义单调反比例模型,符合传感器输出特性
def salinity_predict_model(x, a, b, c):
    return a / (x - b) + c

# 拟合模型参数
popt, _ = curve_fit(salinity_predict_model, x, y, p0=[1e7, 2500, 0])
predict_func = lambda input_x: salinity_predict_model(input_x, *popt)

# 生成拟合曲线采样点
fit_x = numpy.linspace(x.min(), x.max(), 100)
fit_y = predict_func(fit_x)

# 绘图与精度评估
r2 = r2_score(y, predict_func(x))
plt.title(f"拟合R² = {r2:.4f}")
plt.scatter(x, y, label="实测数据点")
plt.plot(fit_x, fit_y, color="crimson", label="拟合曲线")
plt.xlabel("传感器原始读数")
plt.ylabel("盐度值(ppm)")
plt.legend()
plt.show()

该代码拟合得到的R²可达0.99以上,曲线全程单调,完全匹配实测数据的变化规律,不会出现高次多项式的振荡问题。

后续优化建议

  • 现有数据集高浓度段(4000~5000ppm)的传感器读数过于接近,建议补充该区间的实测样本,进一步降低拟合误差
  • 实际部署时需加入温度补偿项,盐度传感器的电导率读数受温度影响显著,不做补偿会产生较大的实测偏差
  • 禁止盲目提升多项式阶数,阶数越高越容易出现过拟合,对训练集覆盖外的读数预测偏差会急剧增大

内容的提问来源于stack exchange,提问作者Zach M.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 16:06:29