校准基础数学:最小二乘法原理、线性回归、多项式拟合、插值法
各位工程师朋友,咱们今天聊点实在的。
做传感器校准,说白了就是跟数据打交道。你从芯片读回来的原始值,跟真实的物理量之间,总差着那么一口气。怎么把这口气理顺?靠的就是数学。
我个人习惯,把校准数学分成四大块:最小二乘法、线性回归、多项式拟合、插值法。这四样东西,就像钳工手里的锉刀、焊工手里的烙铁,缺一不可。今天我就把这四把刀,一把一把递到你手里。
1. 最小二乘法:校准的“定海神针”
先问个问题:你有一堆测量点,想画一条直线穿过它们,怎么画最合理?
你可能会说,目测一下,让线尽量靠近所有点。嗯,这想法没错,但不够精确。我们需要一个数学标准。
最小二乘法的核心思想就一句话:让所有数据点到这条直线的垂直距离的平方和,最小。
为什么是平方?不是绝对值?
我在项目中遇到过这个问题。用绝对值的话,数学上处理起来很麻烦,求导不连续。平方就不一样了,光滑、可导,方便我们用微积分找最小值。说白了,就是为了计算方便。
核心公式(一元线性回归):
假设直线方程为 y = ax + b,那么我们要最小化的目标函数是:
J(a, b) = Σ(yi - (a*xi + b))²
其中 (xi, yi) 是第 i 个测量点。
怎么求 a 和 b?对 J 分别求 a 和 b 的偏导,令其等于 0,解方程组就行。结果就是:
a = (n*Σ(xi*yi) - Σxi*Σyi) / (n*Σ(xi²) - (Σxi)²)
b = (Σyi - a*Σxi) / n
嗯,看着有点复杂,但代码实现起来很简单。你想想看,这其实就是 Excel 里“添加趋势线”时,勾选“线性”背后的数学原理。
避坑指南:
我曾经在一个温度传感器项目里,直接用最小二乘法拟合全量程。结果发现,在低温段误差很大。后来才意识到,传感器在低温区的非线性比较严重,单纯用一条直线去拟合,效果肯定不好。这时候,就该分段拟合或者上多项式了。
2. 线性回归:从理论到代码
线性回归,其实就是最小二乘法在“线性模型”上的具体应用。我们刚才推导的,就是最简单的一元线性回归。
在传感器校准里,线性回归最常见的场景是:两点校准。
比如一个压力传感器,你测两个点:零点(0 kPa)和满量程(100 kPa)。然后你假设中间是线性的,用这两点算出一条直线。这就是线性回归的简化版。
但实际中,我建议你多测几个点。比如测 5 个点,然后用最小二乘法去拟合。为什么?因为传感器本身有噪声,多测几个点能平均掉随机误差,结果更稳定。
// 一个简单的线性回归 C 代码示例
// 输入:x[] 和 y[] 数组,n 为点数
// 输出:斜率 a,截距 b
void linear_regression(float x[], float y[], int n, float *a, float *b) {
float sum_x = 0, sum_y = 0, sum_xy = 0, sum_xx = 0;
for (int i = 0; i < n; i++) {
sum_x += x[i];
sum_y += y[i];
sum_xy += x[i] * y[i];
sum_xx += x[i] * x[i];
}
*a = (n * sum_xy - sum_x * sum_y) / (n * sum_xx - sum_x * sum_x);
*b = (sum_y - (*a) * sum_x) / n;
}
这段代码我用了很多年,基本没出过问题。唯一要注意的是,分母不能为零。如果分母为零,说明所有 x 值都一样,那就没法拟合了。
3. 多项式拟合:对付非线性的一把好手
现实世界不是完美的线性。很多传感器,比如热电偶、NTC 热敏电阻,天生就是非线性的。
这时候,线性回归就不够用了。我们需要多项式拟合。
多项式拟合的原理,跟线性回归一模一样,只是把模型从 y = ax + b 换成了 y = a0 + a1*x + a2*x² + ... + an*xⁿ。
你可能会问:阶数选多少合适?
我个人经验是:能低就别高。阶数太高,容易过拟合。什么叫过拟合?就是你的曲线完美地穿过了每一个测量点,但在测量点之间,曲线剧烈震荡,完全不符合物理规律。
重要提醒:
我曾经在一个项目中,用 7 阶多项式去拟合一个温度传感器的 8 个标定点。结果拟合出来的曲线,在标定点之间来回振荡,误差反而比 3 阶多项式还大。后来我改成 3 阶,效果反而更好。
记住:阶数一般不超过 3~4 阶。除非你有非常充分的理由。
多项式拟合的代码实现,通常用“最小二乘法的矩阵形式”来解。这里不展开矩阵运算的细节,你直接用现成的库函数就行。比如 Python 的 numpy.polyfit,或者 C 语言的 gsl_multifit_linear。
4. 插值法:当模型失效时的最后防线
有时候,传感器的响应太复杂,用多项式拟合效果也不好。或者,你手头只有一张标定数据表,没有明确的数学模型。
这时候,就该插值法登场了。
插值法的思路很简单:在两个已知点之间,用某种规则估算出未知点的值。
常见的插值法有几种:
| 方法 | 原理 | 适用场景 |
|---|---|---|
| 线性插值 | 两点之间用直线连接 | 数据点密集,且变化平缓 |
| 三次样条插值 | 分段用三次多项式连接,保证光滑 | 数据点较少,且需要光滑曲线 |
| 拉格朗日插值 | 用一个高次多项式穿过所有点 | 点数很少(如 3~5 个),且精度要求高 |
我个人最常用的是线性插值。为什么?因为它简单、稳定、计算快。在嵌入式芯片上,线性插值只需要一次乘法和一次除法,开销极小。
// 线性插值 C 代码示例
// 输入:已知点 (x1, y1) 和 (x2, y2),待插值点 x
// 输出:插值结果 y
float linear_interp(float x1, float y1, float x2, float y2, float x) {
if (x2 == x1) return y1; // 防止除零
return y1 + (y2 - y1) * (x - x1) / (x2 - x1);
}
嗯,就这么简单。但要注意,插值法只能用于已知点之间。如果你要预测已知点范围之外的值,那叫“外推”,误差会急剧增大,我强烈不建议这么做。
实战建议:
在传感器校准中,我通常的做法是:
- 先尝试线性回归。如果误差在可接受范围内,就用它。
- 如果线性不行,上 2~3 阶多项式拟合。
- 如果多项式拟合也搞不定,或者数据点非常稀疏,就用三次样条插值。
- 最后,如果计算资源极其有限(比如 8 位单片机),就用分段线性插值。
这个顺序,是我踩了无数坑之后总结出来的。你照着做,至少不会出大错。
总结一下
今天咱们聊了四样东西:
- 最小二乘法:校准的数学基础,核心是让误差平方和最小。
- 线性回归:最小二乘法在线性模型上的应用,适合线性传感器。
- 多项式拟合:对付非线性传感器,但阶数别太高。
- 插值法:当模型失效时的备用方案,线性插值最实用。
这些数学工具,说白了就是帮你把传感器的“坏脾气”给捋顺了。下次你拿到一个传感器,先别急着上复杂算法,拿这四把刀挨个试一遍,总有一把适合你。
好,今天就到这儿。下一章咱们聊聊具体的标定流程,从数据采集到参数写入,一条龙讲清楚。