Numpy的最小二乘无剩余

时间:2018-06-05 17:18:40

标签: python numpy statsmodels least-squares empty-list

我试图计算Numpy中的least squares问题(即简单回归的普通最小二乘法(OLS)),以便找到相应的R²值。但是,在某些情况下,Numpy会返回残差的空列表。采用以下 over-determined 示例(,更多方程而不是未知数)来说明此问题:

OLS problem

(注意:常数因子(即截距)(即所有1的初始列向量),因此未中止平方和(TSS)将被使用。)

import numpy as np

A = np.array([[6, 6, 3], [40, 40, 20]]).T
y = np.array([0.5, 0.2, 0.6])

model_parameters, residuals, rank, singular_values = np.linalg.lstsq(A, y, rcond=None)

# No Intercept, therefore use Uncentered Total Sum of Squares (TSS)
uncentered_tss = np.sum((y)**2)  
numpy_r2 = 1.0 - residuals / uncentered_tss

print("Numpy Model Parameter(s): " + str(model_parameters))
print("Numpy Sum of Squared Residuals (SSR): " + str(residuals))
print("Numpy R²: " + str(numpy_r2))

以下产生以下输出:

Numpy Model Parameter(s): [0.00162999 0.01086661]
Numpy Sum of Squared Residuals (SSR): []
Numpy R²: []

根据numpy documentation

  

...当方程式未确定或未确定时,残差将为空,但当超定值时返回值。

然而,这个问题显然过于确定(3个方程式与2个未知数)。我甚至可以通过计算sum of squared residuals (SSR)给出的regression results来显示残差(以及statsmodels's OLS function):

import statsmodels.api as sm

A = np.array([[6, 6, 3], [40, 40, 20]]).T
y = np.array([0.5, 0.2, 0.6])

statsmodel_model = sm.OLS(y, A)
regression_results = statsmodels_model.fit()

calculated_r_squared = 1.0 - regression_results.ssr / np.sum((y)**2)

print("Parameters: " + str(regression_results.params))
print("Residuals: " + str(regression_results.resid))
print("Statsmodels R²: " + str(regression_results.rsquared))
print("Manually Calculated R²: " + str(calculated_r_squared))

以下产生以下输出:

Parameters: [0.00162999 0.01086661]
Residuals: [ 0.05555556 -0.24444444  0.37777778]
Statsmodels R²: 0.6837606837606838
Manually Calculated R²: 0.6837606837606838

如您所见,Statsmodels和Numpy模型已达成一致的参数。

为什么Numpy使用以下示例返回空SSR数组?这是numpy.linalg.lstsq的错误吗?如果这是错误,那么为什么Statsmodels能够计算sum of squared residuals (SSR)并且numpy不是?在给出最佳拟合平面的情况下,人们还可以清楚地计算残差:

function plane

1 个答案:

答案 0 :(得分:3)

来自numpy.linalg.lstsq()的文档:

  

残差:{(),(1,),(K,)} ndarray

     

...如果a的等级为< NM <= N,则这是一个空数组。 ...

矩阵的等级为1。

注意:您认为“缺失”残差也可以使用numpy找到(您不需要其他套餐):

residuals = y - np.dot(A, model_parameters)