You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

强制零截距线性回归拟合:解决np.linalg.lstsq维度报错问题

拟合截距为0的线性回归模型 y = bx 的最佳方法

你碰到的LinAlgError问题很常见——np.linalg.lstsq要求自变量输入是二维数组,但你传入的_x本质是一维结构(即使套了列表,还是1行多列的一维数据),所以才会报错。下面给你几种实用的解决方案,结合你的示例数据来演示:

方法1:手动推导最小二乘法计算b

当强制截距a=0时,最小二乘法的系数b可以通过公式直接推导得到:
b = (Σ(x_i * y_i)) / (Σ(x_i²))
我们可以把这个逻辑封装成函数,还顺便计算b的标准差:

import numpy as np

def calc_no_intercept_coeffs(_x, _y):
    # 先把输入转成一维numpy数组,避免维度问题
    x = np.array(_x).flatten()
    y = np.array(_y).flatten()
    
    # 计算b的核心公式
    numerator = np.sum(x * y)
    denominator = np.sum(x ** 2)
    b = numerator / denominator
    
    # 计算b的标准差
    y_pred = b * x
    residuals = y - y_pred
    n = len(x)
    sig_b = np.sqrt(np.sum(residuals ** 2) / ((n - 1) * denominator))
    
    return b, sig_b

方法2:调整数组维度后用np.linalg.lstsq

只需要把你的一维_x转换成列向量(二维数组),就能满足lstsq的输入要求了——注意不要添加全1的截距列,因为我们要强制截距为0:

import numpy as np

# 处理你的示例数据:把_x转成22行1列的二维数组
_x = np.array([(0.009412743,0.014965211,0.013263312,0.013529132,0.009989368,0.013932615,0.020849682,0.010953529,0.003608903,0.007220992,0.012750529,0.021608436,0.031742052,0.022482958,0.021137599,0.018703295,0.021633681,0.019866029,0.020260629,0.034433715,0.009241074,0.012027059)]).T
_y = np.array([0.294158677,0.359935335,0.313484808,0.301917271,0.169190763,0.486254864,0.305846328,0.347077387,0.188928817,0.422194367,0.41157232,0.39281496,0.497935681,0.34763333,0.281712023,0.352045535,0.339958296,0.395932086,0.359905526,0.450004349,0.395200865,0.365162443])

# 使用lstsq,设置rcond=None消除版本警告
b, residuals, rank, singular_vals = np.linalg.lstsq(_x, _y, rcond=None)
print(f"拟合得到的b值:{b[0]:.6f}")

这里的_x.T是关键,它把原来的(1,22)形状数组转成(22,1)的二维列向量,完美匹配lstsq的输入要求。

方法3:用scipy的封装工具快速拟合

如果你不想手动写公式,也可以用scipy.optimize.curve_fit来指定截距为0的线性模型,它会自动完成拟合和参数误差计算:

from scipy.optimize import curve_fit

# 定义截距为0的线性模型
def zero_intercept_model(x, b):
    return b * x

# 把输入转成一维数组后拟合
x_flat = np.array(_x).flatten()
params, param_cov = curve_fit(zero_intercept_model, x_flat, _y)

b = params[0]
sig_b = np.sqrt(param_cov[0][0])
print(f"拟合的b值:{b:.6f},标准差:{sig_b:.6f}")

结果验证

这三种方法本质都是基于最小二乘法,用你的示例数据计算出来的b值会完全一致,你可以根据自己的需求选择最顺手的方式。

内容的提问来源于stack exchange,提问作者warrenfitzhenry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:50:16