gpt4 book ai didi

python-2.7 - 在 Python : LinAlgError 中建模时检测 mulicollinear 或具有线性组合的列

转载 作者:行者123 更新时间:2023-12-04 08:08:17 29 4
gpt4 key购买 nike

我正在为具有 34 个因变量的 logit 模型建模数据,并且它不断抛出奇异矩阵错误,如下所示 -:

Traceback (most recent call last):
File "<pyshell#1116>", line 1, in <module>
test_scores = smf.Logit(m['event'], train_cols,missing='drop').fit()
File "/usr/local/lib/python2.7/site-packages/statsmodels-0.5.0-py2.7-linux-i686.egg/statsmodels/discrete/discrete_model.py", line 1186, in fit
disp=disp, callback=callback, **kwargs)
File "/usr/local/lib/python2.7/site-packages/statsmodels-0.5.0-py2.7-linux-i686.egg/statsmodels/discrete/discrete_model.py", line 164, in fit
disp=disp, callback=callback, **kwargs)
File "/usr/local/lib/python2.7/site-packages/statsmodels-0.5.0-py2.7-linux-i686.egg/statsmodels/base/model.py", line 357, in fit
hess=hess)
File "/usr/local/lib/python2.7/site-packages/statsmodels-0.5.0-py2.7-linux-i686.egg/statsmodels/base/model.py", line 405, in _fit_mle_newton
newparams = oldparams - np.dot(np.linalg.inv(H),
File "/usr/local/lib/python2.7/site-packages/numpy/linalg/linalg.py", line 445, in inv
return wrap(solve(a, identity(a.shape[0], dtype=a.dtype)))
File "/usr/local/lib/python2.7/site-packages/numpy/linalg/linalg.py", line 328, in solve
raise LinAlgError, 'Singular matrix'
LinAlgError: Singular matrix

那是我偶然发现这种方法将矩阵减少到其独立列的时候
def independent_columns(A, tol = 0):#1e-05):
"""
Return an array composed of independent columns of A.

Note the answer may not be unique; this function returns one of many
possible answers.

https://stackoverflow.com/q/13312498/190597 (user1812712)
http://math.stackexchange.com/a/199132/1140 (Gerry Myerson)
http://mail.scipy.org/pipermail/numpy-discussion/2008-November/038705.html
(Anne Archibald)

>>> A = np.array([(2,4,1,3),(-1,-2,1,0),(0,0,2,2),(3,6,2,5)])
2 4 1 3
-1 -2 1 0
0 0 2 2
3 6 2 5
# try with checking the rank of matrixs
>>> independent_columns(A)
np.array([[1, 4],
[2, 5],
[3, 6]])
"""
Q, R = linalg.qr(A)
independent = np.where(np.abs(R.diagonal()) > tol)[0]
#print independent
return A[:, independent], independent


A,independent_col_indexes=independent_columns(train_cols.as_matrix(columns=None))
#train_cols will not be converted back from a df to a matrix object,so doing this explicitly
A2=pd.DataFrame(A, columns=train_cols.columns[independent_col_indexes])

test_scores = smf.Logit(m['event'],A2,missing='drop').fit()

我仍然得到 LinAlgError ,尽管我希望我现在可以降低矩阵等级。

另外,我看到 np.linalg.matrix_rank(train_cols)返回 33(即在调用 Independent_columns 函数之前总共“x”列是 34(即 len(train_cols.ix[0])=34 ),这意味着我没有满秩矩阵),而 np.linalg.matrix_rank(A2)返回 33(意味着我删除了一列,但我仍然看到 LinAlgError ,当我运行 test_scores = smf.Logit(m['event'],A2,missing='drop').fit() 时,我错过了什么?

引用上面的代码 -
How to find degenerate rows/columns in a covariance matrix

我试图通过一次引入每个变量来开始构建模型,这不会给我带来奇异矩阵错误,但我宁愿有一个确定性的方法,让我知道,我做错了什么&如何消除这些列。

编辑(更新后@@
user333700 以下)


1. 你是对的, "A2"没有 33 的降低等级。 IE。 len(A2.ix[0]) =34 -> 意味着可能共线的列不会被删除 - 我应该增加“tol”,公差以获得 A2 的等级(及其列数),为 33。如果我将上面的 tol 更改为“1e-05”,然后我得到 len(A2.ix[0]) =33 ,这表明 tol >0(严格来说)是一个指标。
在此之后,我只是做了同样的事情, test_scores = smf.Logit(m['event'],A2,missing='drop').fit() , 没有 nm 来获得收敛。

2. 尝试“nm”方法后出错。但奇怪的是,如果我只取 20,000 行,我确实得到了结果。由于它没有显示内存错误,而是“ Inverting hessian failed, no bse or cov_params available” - 我假设有多个几乎相似的记录 - 你会怎么说?
m  = smf.Logit(data['event_custom'].ix[0:1000000] , train_cols.ix[0:1000000],missing='drop')
test_scores=m.fit(start_params=None,method='nm',maxiter=200,full_output=1)
Warning: Maximum number of iterations has been exceeded

Warning (from warnings module):
File "/usr/local/lib/python2.7/site-packages/statsmodels-0.5.0-py2.7-linux-i686.egg/statsmodels/base/model.py", line 374
warn(warndoc, Warning)
Warning: Inverting hessian failed, no bse or cov_params available


test_scores.summary()

Traceback (most recent call last):
File "<pyshell#17>", line 1, in <module>
test_scores.summary()
File "/usr/local/lib/python2.7/site-packages/statsmodels-0.5.0-py2.7-linux-i686.egg/statsmodels/discrete/discrete_model.py", line 2396, in summary
yname_list)
File "/usr/local/lib/python2.7/site-packages/statsmodels-0.5.0-py2.7-linux-i686.egg/statsmodels/discrete/discrete_model.py", line 2253, in summary
use_t=False)
File "/usr/local/lib/python2.7/site-packages/statsmodels-0.5.0-py2.7-linux-i686.egg/statsmodels/iolib/summary.py", line 826, in add_table_params
use_t=use_t)
File "/usr/local/lib/python2.7/site-packages/statsmodels-0.5.0-py2.7-linux-i686.egg/statsmodels/iolib/summary.py", line 447, in summary_params
std_err = results.bse
File "/usr/local/lib/python2.7/site-packages/statsmodels-0.5.0-py2.7-linux-i686.egg/statsmodels/tools/decorators.py", line 95, in __get__
_cachedval = self.fget(obj)
File "/usr/local/lib/python2.7/site-packages/statsmodels-0.5.0-py2.7-linux-i686.egg/statsmodels/base/model.py", line 1037, in bse
return np.sqrt(np.diag(self.cov_params()))
File "/usr/local/lib/python2.7/site-packages/statsmodels-0.5.0-py2.7-linux-i686.egg/statsmodels/base/model.py", line 1102, in cov_params
raise ValueError('need covariance of parameters for computing '
ValueError: need covariance of parameters for computing (unnormalized) covariances

编辑 2: (更新后@user333700 的建议如下)

Reiterating what I am trying to model - less than about 1% of total users "convert" (success outcomes) - so I took a balanced sample of 35(+ve) /65 (-ve)



我怀疑该模型并不稳健,尽管它收敛了。因此,将使用“start_params”作为来自不同数据集的早期迭代的参数。
此编辑是关于确认“start_params”是否可以输入到结果中,如下所示 -:
A,independent_col_indexes=independent_columns(train_cols.as_matrix(columns=None))
A2=pd.DataFrame(A, columns=train_cols.columns[independent_col_indexes])
m = smf.Logit(data['event_custom'], A2,missing='drop')
#m = smf.Logit(data['event_custom'], train_cols,missing='drop')#,method='nm').fit()#This doesnt work, so tried 'nm' which work, but used lasso, as nm did not converge.
test_scores=m.fit_regularized(start_params=None, method='l1', maxiter='defined_by_method', full_output=1, disp=1, callback=None, alpha=0, \
trim_mode='auto', auto_trim_tol=0.01, size_trim_tol=0.0001, qc_tol=0.03)

a_good_looking_previous_result.params=test_scores.params #storing the parameters of pass1 to feed into pass2

test_scores.params
bidfloor_Quartile_modified_binned_0 0.305765
connectiontype_binned_0 -0.436798
day_custom_binned_Fri -0.040269
day_custom_binned_Mon 0.138599
day_custom_binned_Sat -0.319997
day_custom_binned_Sun -0.236507
day_custom_binned_Thu -0.058922
user_agent_device_family_binned_iPad -10.793270
user_agent_device_family_binned_iPhone -8.483099
user_agent_masterclass_binned_apple 9.038889
user_agent_masterclass_binned_generic -0.760297
user_agent_masterclass_binned_samsung -0.063522
log_height_width 0.593199
log_height_width_ScreenResolution -0.520836
productivity -1.495373
games 0.706340
entertainment -1.806886
IAB24 2.531467
IAB17 0.650327
IAB14 0.414031
utilities 9.968253
IAB1 1.850786
social_networking -2.814148
IAB3 -9.230780
music 0.019584
IAB9 -0.415559
C(time_day_modified)[(6, 12]]:C(country)[AUS] -0.103003
C(time_day_modified)[(0, 6]]:C(country)[HKG] 0.769272
C(time_day_modified)[(6, 12]]:C(country)[HKG] 0.406882
C(time_day_modified)[(0, 6]]:C(country)[IDN] 0.073306
C(time_day_modified)[(6, 12]]:C(country)[IDN] -0.207568
C(time_day_modified)[(0, 6]]:C(country)[IND] 0.033370
... more params here

现在在不同的数据集(pass2,用于索引)上,我的模型与以下相同 -:
IE。我读了一个新的数据框,做所有的变量转换,然后像之前一样通过 Logit 建模。
m_pass2  = smf.Logit(data['event_custom'], A2_pass2,missing='drop')
test_scores_pass2=m_pass2.fit_regularized(start_params=a_good_looking_previous_result.params, method='l1', maxiter='defined_by_method', full_output=1, disp=1, callback=None, alpha=0, \
trim_mode='auto', auto_trim_tol=0.01, size_trim_tol=0.0001, qc_tol=0.03)

并且,可能通过从早期的传递中选取“start_params”来继续迭代。

最佳答案

对此有几点说明:

您需要 tol > 0 来检测接近完美的共线性,这也可能会在以后的计算中导致数值问题。
查看A2的列数查看列是否真的被删除了。

Logit 需要对 exog 进行一些非线性计算,因此即使设计矩阵不是非常接近完美共线性,对数似然、导数或 Hessian 计算的变换变量最终可能仍会遇到数值问题,例如单一的黑森州。

(当我们在浮点精度 1e-15、1e-16 附近工作时,所有这些都是浮点问题。matrix_rank 和类似 linalg 函数的默认阈值有时存在差异,这可能意味着在某些边缘情况下,一个函数将其识别为单数,另一个没有。)

包括 Logit 在内的离散模型的默认优化方法是简单的 Newton 方法,它在相当不错的情况下很快,但在条件不佳的情况下可能会失败。您可以尝试其他优化器之一,这将是 scipy.optimize 中的优化器之一,method='nm'通常非常健壮但很慢,method='bfgs'在许多情况下效果很好,但也可能遇到收敛问题。

尽管如此,即使其他优化方法之一成功,仍然需要检查结果。通常情况下,一种方法的失败意味着模型或估计问题可能没有明确定义。

检查是否只是错误的起始值问题或规范问题的一个好方法是运行 method='nm'首先,然后运行一种更准确的方法,如 newtonbfgs使用 nm估计作为起始值,并从好的起始值看它是否成功。

关于python-2.7 - 在 Python : LinAlgError 中建模时检测 mulicollinear 或具有线性组合的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23848003/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com