校准基础数学:最小二乘法原理、线性回归、多项式拟合、插值法

各位工程师朋友,咱们今天聊点实在的。

做传感器校准,说白了就是跟数据打交道。你从芯片读回来的原始值,跟真实的物理量之间,总差着那么一口气。怎么把这口气理顺?靠的就是数学。

我个人习惯,把校准数学分成四大块:最小二乘法、线性回归、多项式拟合、插值法。这四样东西,就像钳工手里的锉刀、焊工手里的烙铁,缺一不可。今天我就把这四把刀,一把一把递到你手里。

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);
}

嗯,就这么简单。但要注意,插值法只能用于已知点之间。如果你要预测已知点范围之外的值,那叫“外推”,误差会急剧增大,我强烈不建议这么做。

实战建议:

在传感器校准中,我通常的做法是:

  1. 先尝试线性回归。如果误差在可接受范围内,就用它。
  2. 如果线性不行,上 2~3 阶多项式拟合。
  3. 如果多项式拟合也搞不定,或者数据点非常稀疏,就用三次样条插值。
  4. 最后,如果计算资源极其有限(比如 8 位单片机),就用分段线性插值。

这个顺序,是我踩了无数坑之后总结出来的。你照着做,至少不会出大错。

总结一下

今天咱们聊了四样东西:

  • 最小二乘法:校准的数学基础,核心是让误差平方和最小。
  • 线性回归:最小二乘法在线性模型上的应用,适合线性传感器。
  • 多项式拟合:对付非线性传感器,但阶数别太高。
  • 插值法:当模型失效时的备用方案,线性插值最实用。

这些数学工具,说白了就是帮你把传感器的“坏脾气”给捋顺了。下次你拿到一个传感器,先别急着上复杂算法,拿这四把刀挨个试一遍,总有一把适合你。

好,今天就到这儿。下一章咱们聊聊具体的标定流程,从数据采集到参数写入,一条龙讲清楚。