Scikit-learn: Предложение: добавить поддержку нештатной логистической регрессии

Созданный на 30 апр. 2016  ·  34Комментарии  ·  Источник: scikit-learn/scikit-learn

LinearRegression предоставляет нештатную OLS, а SGDClassifier , который поддерживает loss="log" , также поддерживает penalty="none" . Но если вам нужна простая старая непенализованная логистическая регрессия, вы должны подделать ее, установив в C в LogisticRegression большое число или используя Logit из statsmodels вместо.

Documentation Easy

Самый полезный комментарий

Вы спрашиваете, зачем мне делать логистическую регрессию без регуляризации? Потому что (1) иногда выборка достаточно велика по отношению к количеству признаков, что регуляризация ничего не даст, и (2) иногда интересны наиболее подходящие коэффициенты, а не максимизация точности прогнозов.

Все 34 Комментарий

вам нужно подделать это, установив C в LogisticRegression на большое число

В чем проблема такого подхода?

Я предположил, что это неточно и медленнее, чем прямая реализация нештатной логистической регрессии. Я ошибся?

Я заметил, что установка слишком высокого значения C , как показано ниже, приведет к зависанию LogisticRegression.fit . Но я не знаю, является ли это ошибкой или просто неотъемлемым свойством алгоритма и его реализации на 64-битном компьютере.

import numpy as np
from sklearn.linear_model import LogisticRegression

x = np.matrix([0, 0, 0, 0,  1, 1, 1, 1]).T
y =           [1, 0, 0, 0,  1, 1, 1, 0]

m = LogisticRegression(C = 1e200)
m.fit(x, y)
print m.intercept_, m.coef_

Я заметил, что установка слишком высокого C, как показано ниже, приведет к зависанию LogisticRegression.fit

Да, этого следовало ожидать, поскольку проблема становится некорректной, когда C велик. Итерационные решатели медленны с некорректно поставленными задачами.

В вашем примере алгоритму требуется вечность, чтобы достичь желаемого допуска. Вам нужно либо увеличить tol либо жестко указать max_iter .

@mblondel есть ли альтернатива "итеративным решателям"?
Вы не получите именно нерегулярный вариант, верно?

@Kodiologist, зачем тебе это?

Вы спрашиваете, зачем мне делать логистическую регрессию без регуляризации? Потому что (1) иногда выборка достаточно велика по отношению к количеству признаков, что регуляризация ничего не даст, и (2) иногда интересны наиболее подходящие коэффициенты, а не максимизация точности прогнозов.

Да, это был мой вопрос.

(1) неверно. Он всегда купит вам более быстрый решатель.

(2) больше относится к области статистического анализа, который на самом деле не является фокусом scikit-learn. Я думаю, мы могли бы добавить это, но я не знаю, какой решатель мы бы использовали. Как не статистик, мне интересно, что хорошего в любых коэффициентах, которые меняются с небольшой регуляризацией.

Я не могу много сказать о (1), поскольку вычисления - не моя сильная сторона. Что касается (2), я аналитик данных с опытом работы в статистике. Я знаю, что scikit-learn фокусируется на традиционном машинном обучении, но, на мой взгляд, это лучший пакет Python для анализа данных прямо сейчас, и я думаю, что он выиграет, если не будет слишком сильно ограничивать себя. (Я также думаю, вслед за Ларри Вассерманом и Эндрю Гельманом, что статистика и машинное обучение взаимно выиграют от большего смешения, но я полагаю, что это отдельная банка червей.) Все коэффициенты изменятся с регуляризацией; вот что делает регуляризация.

Я не против добавления решателя без регуляризации. Мы можем проверить, что было бы хорошо, или просто внести залог и использовать l-bfgs и заранее проверить, не подходит ли он?

Да, все коэффициенты меняются при регуляризации. Мне просто интересно, что ты хочешь с ними делать потом.

Привет,
Каков статус по этой теме? Я был бы действительно заинтересован в неоправданной логистической регрессии. Таким образом, p-значения будут означать что-то статистически говоря. В противном случае мне придется продолжать использовать R 😢 для таких случаев использования ...
Спасибо,
Алекс

Или государственные модели?

Какие решатели вы предлагаете реализовать? Чем это будет отличаться от решателей, которые у нас уже есть с C -> infty?

Какие решатели вы предлагаете реализовать? Чем это будет отличаться от решателей, которые у нас уже есть с C -> infty?

Вы можете попробовать поискать идеи в R или статистических моделях. Я не знаком с их методами, но они достаточно быстрые и вообще не используют регуляризацию.

Да, statsmodels тоже работает, если вы используете QR-алгоритм для инверсии матриц. Мой вариант использования связан с интерпретируемостью модели. Для производительности я бы обязательно использовал регуляризацию.

Я не думаю, что нам нужно добавлять какой-либо новый решатель ... Логистическая регрессия не имеет решения в закрытой форме, что означает, что statsmodel также должна использовать какой-то итеративный решатель (я предполагаю, что это итеративный пересмотренный метод наименьших квадратов, но Я не проверял). Установка C=np.inf (или эквивалентно альфа = 0 ) в принципе должна работать с нашими текущими решателями. Я бы порекомендовал переключиться на решатель L-BFGS или Newton-CG, поскольку liblinear действительно может быть очень медленным в этой настройке. Возможно, мы можем добавить параметр solver="auto" и автоматически переключиться на один из них, когда C=np.inf или эквивалентно penalty="none" ?

мы меняем решатель по умолчанию на lbfgs в # 10001 fwiw

Для людей, которые действительно хотят нерегулируемой логистической регрессии (например, я). Мне приходилось соглашаться с использованием statsmodels и создания класса-оболочки, имитирующего SKLearn API.

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

@shermstats предлагает как улучшить документацию по этому поводу? Я согласен, что это может быть не очень очевидно.
Разрешает ли l-bfgs C=np.inf ?

Вы можете указать C=np.inf , но это даст тот же результат, что и C=large value . В примере, который я пробовал, он подходит лучше, чем statsmodel, а statsmodel не сходится с большинством других случайных семян:

from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
import statsmodels.api as sm

X, y = make_classification(random_state=2)
lr = LogisticRegression(C=np.inf, solver='lbfgs').fit(X, y)


logit = sm.Logit(y, X)
res = logit.fit()
Optimization terminated successfully.
         Current function value: 0.167162
         Iterations 10
from sklearn.metrics import log_loss
log_loss(y, lr.predict_proba(X))
log_loss(y, res.predict(X))
0.16197793224715606
0.16716164149746823

Поэтому я бы сказал, что мы должны просто задокументировать, что вы можете получить непенализованную модель, установив C large или np.inf.

Я бы предложил добавить в строку документации и руководство пользователя
«Модель LogisticRegregression штрафуется по умолчанию. Вы можете получить модель без штрафов, установив C = np.inf и solver = 'lbfgs'».

он подошел лучше, чем statsmodel, а statsmodel не смог сходиться с большинством других случайных начальных чисел

glm R более зрелый и может дать лучшее сравнение.

Я бы предложил добавить в строку документации и руководство пользователя
«Модель LogisticRegregression штрафуется по умолчанию. Вы можете получить модель без штрафов, установив C = np.inf и solver = 'lbfgs'».

Почему бы не добавить allow penalty = "none" a la SGDClassifier ?

@Kodiologist Я не против добавления penalty="none" но я не уверен, в чем польза от добавления избыточной опции.
И я думаю, мы приветствовали бы сравнения с glm. Я не очень хорошо знаком с glm, поэтому я, вероятно, не лучший человек для сравнения. Однако мы оптимизируем потерю журнала, поэтому на самом деле не должно быть никакой разницы. Возможно, они реализуют разные решатели, поэтому было бы неплохо иметь тест.

Я не против добавления penalty="none" но я не уверен, в чем преимущество добавления избыточной опции.

  1. Становится понятнее, как получить нештатную модель.
  2. Читателю становится понятнее, что пытается сделать код, использующий непонятную модель.
  3. Это позволяет sklearn изменить свою реализацию нерегулируемых моделей в будущем, не нарушая код людей.

Если вы чувствуете, что это увеличивает обнаруживаемость, мы можем добавить его, и 3 является допустимой точкой (хотя на самом деле мы не можем изменить это без устаревания, вероятно, см. Текущее изменение решателя).
Хотите отправить PR?

У меня нет для этого круглых туфлей; извиняюсь.

@Kodiologist, по крайней мере, ты научил меня идиоме, о которой я не знал;)

Так что открыто для участников: добавьте penalty='none' в качестве опции. Также, возможно, проверьте, какие решатели поддерживают это / эффективны с этим (liblinear, вероятно, нет) и ограничьтесь этими решателями.

Я бы предложил добавить в строку документации и руководство пользователя
«Модель LogisticRegregression штрафуется по умолчанию. Вы можете получить модель без штрафов, установив C = np.inf и solver = 'lbfgs'».

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

@shermstats Итак, @Kodiologist предложил добавить penalty="none" чтобы сделать его более явным, что будет просто псевдонимом для C=np.inf . Для меня имеет смысл сделать это более явным таким образом. У вас есть мысли по этому поводу?
Тогда это будет то, что написано в документации. И я согласен, что жирный шрифт может быть хорошей идеей.
Я думаю, что для кого-то с опытом машинного обучения это (возможно?) Ожидается, для кого-то со статистическим опытом это кажется очень удивительным.

Точно! У меня есть опыт работы со статистикой, и я работал со многими специалистами по статистике, пришедшими из R или даже через интерфейсы «укажи и щелкни», и такое поведение нас очень удивляет. На данный момент я думаю, что penalty=None (не уверен, что "none" vs. None ) - хорошее решение. В будущем у нас должен быть отдельный решатель, который будет автоматически вызываться для нештатной логистической регрессии, чтобы предотвратить проблемы, описанные @mblondel .

Извините, о чем вы говорите? Мы переключаемся на l-bfgs по умолчанию, и мы также можем автоматически переключить решатель на l-bfgs, если кто-то указывает penalty='none' (часто None - это специальный токен, который мы используем для устаревших параметров, но мы остановили Тем не менее, "none" больше соответствовало бы остальной части библиотеки).
В любом случае нам нужен solver="auto" поэтому изменение решателя на основе штрафа не должно быть проблемой.

Эта проблема связана с тем, что итеративный алгоритм становится очень медленным для больших C. Я не специалист по численному анализу, но если l-bfgs не дает ему замедляться, это звучит как правильное решение. penalty='none' тоже звучит как правильный способ справиться с этим.

@shermstats да, с l-bfgs это не проблема. Однако я не проводил обширных тестов, и у меня не будет времени на это. Если кто-то хочет запустить тесты, это будет большим подспорьем.

Если необходимо включить штраф = 'none', я предлагаю добавить в руководство пользователя такое же предупреждение о коллинеарном X, что и для OLS (особенно для функций с горячим кодированием).

Была ли эта страница полезной?
0 / 5 - 0 рейтинги