绘制回归直线异常求助:反转y轴数据后回归线不符合预期
问题分析与修复方案
嘿,我发现你的代码里的核心问题出在estimate_coef函数中计算偏差平方和的部分——你错误地把整个减法表达式放进了np.sum()里,导致数学计算逻辑偏离了线性回归的公式。
错误原因详解
线性回归中,我们需要计算两个关键值:
- 交叉偏差和 SS_xy:公式是 $\sum_{i=1}^n (y_i - \bar{y})(x_i - \bar{x})$,展开后等价于 $\sum(x_i y_i) - n\bar{x}\bar{y}$
- x的偏差平方和 SS_xx:公式是 $\sum_{i=1}^n (x_i - \bar{x})^2$,展开后等价于 $\sum(x_i^2) - n\bar{x}^2$
你原来的代码写法:
SS_xy = np.sum(y*x - n*m_y*m_x) SS_xx = np.sum(x*x - n*m_x*m_x)
这里的问题是,n*m_y*m_x是一个常数,当你把它放进np.sum()时,相当于对这个常数求和n次,最终结果变成了sum(y*x) - n*n*m_y*m_x,这和正确公式差了一个n倍,直接导致回归系数b_1和b_0计算错误。
修复后的代码
只需要修改estimate_coef函数中的SS_xy和SS_xx计算方式,把求和操作和常数项分开:
from matplotlib import pyplot as plt import numpy as np def estimate_coef(x, y): # number of observations/points n = np.size(x) # mean of x and y vector m_x, m_y = np.mean(x), np.mean(y) # calculating cross-deviation and deviation about x # 修复:先计算求和项,再减去常数项 SS_xy = np.sum(x * y) - n * m_x * m_y SS_xx = np.sum(x ** 2) - n * m_x ** 2 # calculating regression coefficients b_1 = SS_xy / SS_xx b_0 = m_y - b_1 * m_x return (b_0, b_1) def plot_regression_line(xs, ys): # dev stands for deviation dev = estimate_coef(xs, ys) # 用numpy向量运算替代循环,更高效 y_pred = dev[0] + dev[1] * xs # plotting the regression line plt.plot(xs, y_pred, color = "g") def main(): # Defining points. xarr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] yarr = [1, 3, 2, 5, 7, 8, 8, 9, 10, 12] # 反转yarr测试 yarr.reverse() # Setting points as numpy arrays. x = np.array(xarr) y = np.array(yarr) # Plotting points. plt.scatter(x, y) plot_regression_line(x, y) plt.show() if __name__ == "__main__": main()
另外我还优化了plot_regression_line里的y_pred计算,用numpy的向量运算替代了循环,既简洁又高效。
现在你运行反转yarr后的代码,就能得到符合预期的回归直线了——它会正确拟合反转后的数据趋势(负相关的回归线)。
内容的提问来源于stack exchange,提问作者IMCoins
相关产品推荐
相关产品推荐

