我试图计算Numpy中的least squares问题(即简单回归的普通最小二乘法(OLS)),以便找到相应的R²值。但是,在某些情况下,Numpy会返回残差的空列表。采用以下 over-determined 示例(,更多方程而不是未知数)来说明此问题:
(注意:无常数因子(即截距)(即所有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²: []
...当方程式未确定或未确定时,残差将为空,但当超定值时返回值。
然而,这个问题显然过于确定(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不是?在给出最佳拟合平面的情况下,人们还可以清楚地计算残差:
答案 0 :(得分:3)
来自numpy.linalg.lstsq()
的文档:
残差:{(),(1,),(K,)} ndarray
...如果a的等级为
< N
或M <= N
,则这是一个空数组。 ...
矩阵的等级为1。
注意:您认为“缺失”残差也可以使用numpy
找到(您不需要其他套餐):
residuals = y - np.dot(A, model_parameters)