为何scipy.stats.linregress与numpy.polyfit(deg=1)线性回归结果不同?
为什么numpy.polyfit和scipy.stats.linregress的线性回归结果有差异?
首先得明确:理论上,这两个函数默认都是用普通最小二乘法(OLS)拟合线性回归,结果应该几乎完全一致。你遇到的差异(尤其是scipy拟合直线高估所有数据的情况)大概率不是算法本身的问题,而是以下几种可能性:
可能的原因分析
使用时的操作失误
最常见的是搞反了x和y的传入顺序。比如如果不小心把linregress(y, x)当成了linregress(x, y),拟合出来的直线就会完全偏离,出现高估/低估所有数据的情况。你可以检查一下自己的代码,确认参数顺序是否正确。
另外,有没有对其中一组数据做了预处理(比如归一化、缩放)而另一组没有?比如如果给numpy的x做了标准化,scipy的x没做,结果肯定不一样。数值计算的微小精度差异
虽然都是OLS,但两个函数的底层实现细节不同:numpy的polyfit用的是奇异值分解(SVD)来求解,而scipy的linregress用的是QR分解。这两种方法在处理极端数据(比如你的x里有50这样的大值,y是很小的小数)时,可能会产生极其微小的精度差异,但这种差异通常小到可以忽略,不会出现“高估所有数据”的明显偏差。旧版本scipy的bug
如果你的scipy版本比较老旧,某些版本的linregress可能存在边缘场景的bug。建议升级到最新稳定版再测试,大概率能解决问题。
scipy.stats.linregress的适用场景
它可不是只适用于特定场景,反而比numpy.polyfit多了很多统计功能:
- 除了返回斜率和截距,它还会给出相关系数r、p值、标准误差等统计指标,适合需要做统计推断的场景(比如判断回归关系是否显著、计算置信区间)。
- 而
numpy.polyfit更偏向于数值拟合,支持更高次多项式、带权重的拟合,但不提供任何统计检验相关的输出。
建议你做的事
- 先检查代码里的参数顺序和数据预处理步骤,确保两个函数用的是完全相同的原始x和y数据;
- 升级scipy到最新版本(比如用
pip install --upgrade scipy); - 手动计算一次OLS的斜率和截距,和两个函数的结果对比,就能快速定位问题出在哪。
内容的提问来源于stack exchange,提问作者M Waz
相关产品推荐
相关产品推荐

