Как мне вручную `predict_proba` из модели логистической регрессии в scikit-learn?

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

Я пытался:

from sklearn.datasets import load_iris
from scipy.special import expit
import numpy as np

X, y = load_iris(return_X_y=True)
clf = LogisticRegression(random_state=0).fit(X, y)
# use sklearn's predict_proba function
sk_probas = clf.predict_proba(X[:1, :])
# and attempting manually (using scipy's inverse logit)
manual_probas = expit(np.dot(X[:1], clf.coef_.T)+clf.intercept_)
# with a completely manual inverse logit
full_manual_probas = 1/(1+np.exp(-(np.dot(iris_test, iris_coef.T)+clf.intercept_)))

выходы:

>>> sk_probas
array([[9.81815067e-01, 1.81849190e-02, 1.44120963e-08]])
>>> manual_probas
array([[9.99352591e-01, 9.66205386e-01, 2.26583306e-05]])
>>> full_manual_probas
array([[9.99352591e-01, 9.66205386e-01, 2.26583306e-05]])

Мне кажется, что классы совпадают (используя np.argmax), но вероятности разные. Что мне не хватает?

Я просмотрел это и это, но пока не разобрался.

Какой результат вы получаете с manual_probas = expit(np.dot(X[:1] - np.max(X[:1], axis=1), clf.coef_.T) + clf.intercept_)?

Sanjar Adilov 04.05.2022 19:42

Выходы на manual_probas показаны под выходами в вопросе.

s_pike 04.05.2022 20:51

В моем комментарии я вычесть максимум логитов от каждого логита: X[:1] - np.max(X[:1], axis=1). Не так, как ты. Я ожидаю, что эта модификация вернет значения, равные sk_probas. Большинство реализаций softmax используют одинаковые приемы для предотвращения переполнения.

Sanjar Adilov 05.05.2022 06:35

Извините, я пропустил, что вы изменили определение. Ваша формулировка дает что-то другое снова. Принятый ответ работает и объясняет, чего мне не хватало.

s_pike 05.05.2022 10:12
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

документация утверждает, что

For a multi_class problem, if multi_class is set to be “multinomial” the softmax function is used to find the predicted probability of each class

То есть, чтобы получить те же значения, что и sklearn, вам нужно нормализовать с помощью softmax, например:

from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
import numpy as np

X, y = load_iris(return_X_y=True)
clf = LogisticRegression(random_state=0, max_iter=1000).fit(X, y)
decision = np.dot(X[:1], clf.coef_.T)+clf.intercept_
print(clf.predict_proba(X[:1]))
print(np.exp(decision) / np.exp(decision).sum())

Чтобы использовать сигмоиды вместо этого, вы можете сделать это следующим образом:

from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
import numpy as np

X, y = load_iris(return_X_y=True)
clf = LogisticRegression(random_state=0, max_iter=1000, multi_class='ovr').fit(X, y) # Notice the extra argument
full_manual_probas = 1/(1+np.exp(-(np.dot(X[:1], clf.coef_.T)+clf.intercept_)))
print(clf.predict_proba(X[:1]))
print(full_manual_probas / full_manual_probas.sum())

Другие вопросы по теме