Я провожу логистическую регрессию на наборе данных Lalonde для оценки показателей склонности.Я использовал функцию logit
из statsmodels.statsmodels.formula.api
и обернул ковариаты в C()
, чтобы сделать их категоричными.Обработка age
и educ
в качестве непрерывных переменных приводит к успешной конвергенции, но их категоризация вызывает ошибку
Warning: Maximum number of iterations has been exceeded.
Current function value: 0.617306
Iterations: 35
---------------------------------------------------------------------------
LinAlgError Traceback (most recent call last)
<ipython-input-29-bae905b632a4> in <module>
----> 1 psmodel = fsms.logit('treatment ~ 1 + C(age) + C(educ) + C(black) + C(hisp) + C(married) + C(nodegr)', tdf).fit()
2 tdf['ps'] = psmodel.predict()
3 tdf.head()
~/venv/lib/python3.7/site-packages/statsmodels/discrete/discrete_model.py in fit(self, start_params, method, maxiter, full_output, disp, callback, **kwargs)
1832 bnryfit = super(Logit, self).fit(start_params=start_params,
1833 method=method, maxiter=maxiter, full_output=full_output,
-> 1834 disp=disp, callback=callback, **kwargs)
1835
1836 discretefit = LogitResults(self, bnryfit)
~/venv/lib/python3.7/site-packages/statsmodels/discrete/discrete_model.py in fit(self, start_params, method, maxiter, full_output, disp, callback, **kwargs)
218 mlefit = super(DiscreteModel, self).fit(start_params=start_params,
219 method=method, maxiter=maxiter, full_output=full_output,
--> 220 disp=disp, callback=callback, **kwargs)
221
222 return mlefit # up to subclasses to wrap results
~/venv/lib/python3.7/site-packages/statsmodels/base/model.py in fit(self, start_params, method, maxiter, full_output, disp, fargs, callback, retall, skip_hessian, **kwargs)
471 Hinv = cov_params_func(self, xopt, retvals)
472 elif method == 'newton' and full_output:
--> 473 Hinv = np.linalg.inv(-retvals['Hessian']) / nobs
474 elif not skip_hessian:
475 H = -1 * self.hessian(xopt)
~/venv/lib/python3.7/site-packages/numpy/linalg/linalg.py in inv(a)
549 signature = 'D->D' if isComplexType(t) else 'd->d'
550 extobj = get_linalg_error_extobj(_raise_linalgerror_singular)
--> 551 ainv = _umath_linalg.inv(a, signature=signature, extobj=extobj)
552 return wrap(ainv.astype(result_t, copy=False))
553
~/venv/lib/python3.7/site-packages/numpy/linalg/linalg.py in _raise_linalgerror_singular(err, flag)
95
96 def _raise_linalgerror_singular(err, flag):
---> 97 raise LinAlgError("Singular matrix")
98
99 def _raise_linalgerror_nonposdef(err, flag):
LinAlgError: Singular matrix
Для воспроизведения загрузите набор данных Lalonde (вы можете написать в csvиз R data(lalonde)
) и запустите следующий код
import numpy as np
import pandas as pd
from statsmodels.formula import api as fsms
filename = 'lalonde.csv'
df = pd.read_csv(filename)
tdf = df.drop(['re74', 're75', 'u74', 'u75'], axis=1)
formula = 'treat ~ 1 + C(age) + C(educ) + C(black) + C(hisp) + C(married) + C(nodegr)'
psmodel = fsms.logit(formula, tdf).fit()
Не уверен, почему это не смогло сойтись / дойти до единственного гессиана во время обучения.
Интересно, что некоторые примеры, которые я нашел в Интернете о причинно-следственной связиВывод и набор данных lalonde не делают переменные категориальными, что для меня не имеет смысла.Одним из примеров является Microsoft DoWhy , который использует LogisticRegression от sklearn из коробки.Кажется, он не кодирует переменные как категориальные.
Существуют и другие подобные примеры, включающие выполнение логистической регрессии на наборе данных Lalonde без категоризации переменных.Они числовые в данных, но значения не должны рассматриваться как непрерывные.По крайней мере, я чувствую, что они должны быть помещены в бункеры, если не одна категория на значение.Но это другой вопрос, который больше подходит для CrossValidated.Может ли кто-нибудь помочь мне понять, почему я получил эту ошибку и как правильно ее исправить?