scikit-learn Прогнозирование логистической регрессии не то же самое, что самореализация

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

  1. Обучение модели mlogit с помощью scikit-learn
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
import json

# Split data into train-test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)

# Train model
mlr = LogisticRegression(random_state=21, multi_class='multinomial', solver='newton-cg')
mlr.fit(X_train, y_train)
y_pred = mlr.predict(X_test)

# Save test data and coefficients
json.dump(X_test.tolist(), open('X_test.json'), 'w'), indent=4)
json.dump(y_pred.tolist(), open('y_pred.json'), 'w'), indent=4)
json.dump(mlr.classes_.tolist(), open('classes.json'), 'w'), indent=4)
json.dump(mlr.coef_.tolist(), open('weights.json'), 'w'), indent=4)
  1. Самостоятельная реализация softmax с помощью Scipy
from scipy.special import softmax
import numpy as np
import json

def predict(x, w, classes):
    z = np.dot(x, np.transpose(w))
    sm = softmax(z)
    return [classes[i] for i in sm.argmax(axis=1)]

x = json.load(open('X_test.json'))
w = json.load(open('weights.json'))
classes = json.load(open('classes.json'))

y_pred_self = predict(x, w, classes)
  1. Результаты не совпадают. По сути, когда я сравниваю y_pred_self с y_pred, они не совпадают (примерно на 85% похожи).

Итак, мой вопрос в том, является ли scikit-learn softmax или predict реализация содержит нестандартные / скрытые настройки?

Примечание: я также пробовал самореализацию в Ruby, и она также дает неверные прогнозы.


person Hamman Samuel    schedule 28.02.2020    source источник


Ответы (1)


Есть некоторые различия, которые я заметил на первый взгляд. Обратите внимание на следующие моменты:

1. Регуляризация
Согласно docs scikit-learn использует термин регуляризации:

Этот класс реализует регуляризованную логистическую регрессию [...]. Обратите внимание, что по умолчанию применяется регуляризация.

Таким образом, вы можете деактивировать термин регуляризации из реализации scikit-learn или добавить регуляризацию в свою собственную реализацию.

2. Предвзятость
В документации вы можете прочитать, что используется термин предвзятость:

fit_interceptbool, default = True
Определяет, следует ли добавлять константу (также известную как смещение или перехват) к функции принятия решения.

Таким образом, вы можете отключить смещение в реализации scikit-learn или добавить термин смещения в свою реализацию.

Возможно, используйте известный набор данных из библиотеки scikit-learn или предоставьте свой набор данных, чтобы было легче воспроизвести проблему. Сообщите мне, как это работало.

person mephisto    schedule 28.02.2020
comment
Отличный ответ! Решение состояло в том, чтобы учесть смещение в вычислениях. Поэтому я сохранил значения смещения через json.dump(mlr.intercept_.tolist(), open('bias.json'), 'w'), indent=4), а также изменил часть скалярного произведения моей функции predict(x, w, classes, bias) на z = np.dot(x, np.transpose(w))+bias. Теперь у меня 100% совпадение прогнозов обоих решений! - person Hamman Samuel; 28.02.2020