Логистическая регрессия: Scikit Learn против Statsmodels

31

Я пытаюсь понять, почему вывод из логистической регрессии этих двух библиотек дает разные результаты.

Я использую набор данных из учебника UCLA idre , прогнозирование admitна основе gre, gpaи rank. rankрассматривается как категориальная переменная, поэтому сначала она преобразуется в фиктивную переменную с помощью rank_1drop. Также добавлен столбец перехвата.

df = pd.read_csv("https://stats.idre.ucla.edu/stat/data/binary.csv")
y, X = dmatrices('admit ~ gre + gpa + C(rank)', df, return_type = 'dataframe')
X.head()
>  Intercept  C(rank)[T.2]  C(rank)[T.3]  C(rank)[T.4]  gre   gpa
0          1             0             1             0  380  3.61
1          1             0             1             0  660  3.67
2          1             0             0             0  800  4.00
3          1             0             0             1  640  3.19
4          1             0             0             1  520  2.93

# Output from scikit-learn
model = LogisticRegression(fit_intercept = False)
mdl = model.fit(X, y)
model.coef_
> array([[-1.35417783, -0.71628751, -1.26038726, -1.49762706,  0.00169198,
     0.13992661]]) 
# corresponding to predictors [Intercept, rank_2, rank_3, rank_4, gre, gpa]

# Output from statsmodels
logit = sm.Logit(y, X)
logit.fit().params
> Optimization terminated successfully.
     Current function value: 0.573147
     Iterations 6
Intercept      -3.989979
C(rank)[T.2]   -0.675443
C(rank)[T.3]   -1.340204
C(rank)[T.4]   -1.551464
gre             0.002264
gpa             0.804038
dtype: float64

Вывод с statsmodelsтакой же, как показано на веб-сайте idre, но я не уверен, почему Scikit-Learn производит другой набор коэффициентов. Минимизирует ли это какую-то другую функцию потерь? Есть ли документация, в которой говорится о реализации?

hurrikale
источник

Ответы:

28

Ваш ключ к пониманию этого должен состоять в том, что оценки параметров из оценки scikit-learn равномерно меньше по величине, чем аналог statsmodels. Это может привести вас к мысли, что scikit-learn применяет некоторую регуляризацию параметров. Вы можете подтвердить это, прочитав документацию scikit-learn .

В scikit-learn нет способа отключить регуляризацию, но вы можете сделать ее неэффективной, установив параметр настройки Cв большое число. Вот как это работает в вашем случае:

# module imports
from patsy import dmatrices
import pandas as pd
from sklearn.linear_model import LogisticRegression
import statsmodels.discrete.discrete_model as sm

# read in the data & create matrices
df = pd.read_csv("http://www.ats.ucla.edu/stat/data/binary.csv")
y, X = dmatrices('admit ~ gre + gpa + C(rank)', df, return_type = 'dataframe')

# sklearn output
model = LogisticRegression(fit_intercept = False, C = 1e9)
mdl = model.fit(X, y)
model.coef_

# sm
logit = sm.Logit(y, X)
logit.fit().params
tchakravarty
источник
Большое спасибо за объяснение! С этим упорядоченным результатом я пытался продублировать результат, используя glmnetпакет в R, но не смог получить тот же коэффициент. У glmnet немного другая функция стоимости по сравнению со sklearn , но даже если я установлю (имеется alpha=0в glmnetвиду только l2-штраф) и установлю 1/(N*lambda)=C, я все равно не получу тот же результат?
ураган
Моя интуиция заключается в том, что, если я разделю оба термина функции стоимости glmnetна lambdaи установлю новую константу в шрифте логарифмического правдоподобия, что 1/(N*lambda)равно значению in sklearn, две функции стоимости станут идентичными, или я что-то упустил?
ураган
@hurrikale Задайте новый вопрос и свяжите его здесь, и я посмотрю.
Чакраварти
Благодарность! Я разместил вопрос здесь .
ураган
Я думаю, что лучший способ отключить регуляризацию в scikit-learn - это настройка penalty='none'.
Нзбуу
3

Другое отличие состоит в том, что вы установили fit_intercept = False, что по сути является другой моделью. Вы можете видеть, что Statsmodel включает в себя перехват. Отсутствие перехвата, безусловно, изменяет ожидаемый вес объектов. Попробуйте следующее и посмотрите, как оно сравнивается:

model = LogisticRegression(C=1e9)

Брайан Далессандро
источник