Есть некоторые проблемы с вашим кодом.
Начнем с того, что две модели, которые вы здесь показываете, не эквивалентны: хотя вы соответствуете своему scikit-learn LogisticRegression
с fit_intercept=True
(это настройка по умолчанию), вы не делаете этого со своими statsmodels one; из statsmodels docs :
Перехват не включен по умолчанию и должен быть добавлен пользователем. См. statsmodels.tools.add_constant
.
Кажется, это частая путаница - см., Например, scikit-learn & statsmodels - какой R-квадрат правильный? (и собственный ответьте и там).
Другая проблема заключается в том, что, хотя вы используете двоичную классификацию, вы запрашиваете multi_class='multinomial'
в своем LogisticRegression
, чего не должно быть.
Третья проблема заключается в том, что, как объясняется в соответствующем потоке с перекрестной проверкой Logisti c Регрессия: Scikit Learn vs Statsmodels :
Нет способа отключить регуляризацию в scikit-learn, но вы можете сделать его неэффективным, установив параметр настройки C на большое число.
, что делает две модели снова несовместимыми в принципе, но вы успешно обратились к это здесь, установив C=1e8
. Фактически, с тех пор (2016 г.) scikit-learn действительно добавил способ отключения регуляризации, установив penalty='none'
, поскольку, согласно docs :
If 'none' (не поддерживается либлинеарным решателем), регуляризация не применяется.
который теперь следует рассматривать как канонический способ отключения регуляризации.
Итак, включение этих изменения в вашем коде, мы имеем:
np.random.seed(42) # for reproducibility
#### Statsmodels
# first artificially add intercept to x, as advised in the docs:
x_ = sm.add_constant(x)
res_sm = sm.Logit(y, x_).fit(method="ncg", maxiter=max_iter) # x_ here
print(res_sm.params)
Что дает результат:
Optimization terminated successfully.
Current function value: 0.403297
Iterations: 5
Function evaluations: 6
Gradient evaluations: 10
Hessian evaluations: 5
[-1.65822763 3.65065752]
с первым элементом массива, являющимся перехватом, а второй - коэффициентом x
. В то время как для scikit learn у нас есть:
#### Scikit-Learn
res_sk = LogisticRegression(solver='newton-cg', max_iter=max_iter, fit_intercept=True, penalty='none')
res_sk.fit( x.reshape(n, 1), y )
print(res_sk.intercept_, res_sk.coef_)
с результатом:
[-1.65822806] [[3.65065707]]
Эти результаты практически идентичны, в пределах точности c машины.
Повторение процедуры для разных значений np.random.seed()
не меняет сути результатов, показанных выше.