如何获得准确多项式回归结果 解决水盐度传感器拟合失真问题
水体盐度传感器拟合曲线失真问题解决方案
问题背景
研发测量单位为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]
核心问题原因
- 模型选型错误:高次多项式本身不适合拟合该类数据。从散点分布可以看出,传感器读数随盐度升高单调下降,低浓度段读数变化快、高浓度段读数变化极慢,属于典型的非线性单调关系。4次多项式会在数值密集的高浓度区间(x集中在2500~3200范围)产生龙格振荡,完全违背传感器输出的单调特性。
- 数值误差干扰:x原始值为万级量级,高次幂计算时会产生极大的数值截断误差,进一步放大拟合系数的失真程度。
解决方法
- 替换拟合模型:放弃无约束高次多项式,选择符合盐度传感器物理特性的单调模型。电导率原理的盐度传感器输出与盐度满足反比例类函数关系,不会出现非物理的振荡问题。
- 修正拟合流程:使用非线性最小二乘拟合自定义的单调模型,避免高次项的数值误差。
可直接运行的修正代码
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.
相关产品推荐
相关产品推荐

