Пакетный градиентный спуск с scikit learn (склеарн)
Я играю с классификатором "Логистическая регрессия один-на-все", используя Scikit-Learn (sklearn). У меня есть большой набор данных, который слишком медленный, чтобы запускать все сразу; Также я хотел бы изучить кривую обучения в процессе обучения.
Я хотел бы использовать пакетный градиентный спуск, чтобы обучить мой классификатор партиями, скажем, 500 образцов. Есть ли какой-нибудь способ использования sklearn для этого, или я должен отказаться от sklearn и "бросить свой собственный"?
Это то, что я до сих пор:
from sklearn.linear_model import LogisticRegression
from sklearn.multiclass import OneVsRestClassifier
# xs are subsets of my training data, ys are ground truth for same; I have more
# data available for further training and cross-validation:
xs.shape, ys.shape
# => ((500, 784), (500))
lr = OneVsRestClassifier(LogisticRegression())
lr.fit(xs, ys)
lr.predict(xs[0,:])
# => [ 1.]
ys[0]
# => 1.0
Т.е. он правильно идентифицирует тренировочный образец (да, я понимаю, что было бы лучше оценить его с новыми данными - это всего лишь быстрая дымовая проверка).
Повторный градиентный спуск: я не дошел до создания кривых обучения, но можно просто запустить fit
повторно на последующих подмножествах обучающих данных? Или есть какая-то другая функция для обучения в партиях? Документация и Google довольно молчат по этому вопросу. Спасибо!
1 ответ
То, что вы хотите, это не пакетный градиентный спуск, а стохастический градиентный спуск; Пакетное обучение означает обучение всему обучающему набору за один раз, в то время как то, что вы описываете, правильно называется миниатюрным обучением. Это реализовано в sklearn.linear_model.SGDClassifier
, которая соответствует модели логистической регрессии, если вы даете ей возможность loss="log"
,
С SGDClassifier
как с LogisticRegression
нет необходимости оборачивать оценщик в OneVsRestClassifier
- оба проводят тренировку "один против всех" из коробки.
# you'll have to set a few other options to get good estimates,
# in particular n_iterations, but this should get you going
lr = SGDClassifier(loss="log")
Затем, чтобы тренироваться на миниатчах, используйте partial_fit
метод вместо fit
, В первый раз вы должны передать ему список классов, потому что не все классы могут присутствовать в каждом мини-пакете:
import numpy as np
classes = np.unique(["ham", "spam", "eggs"])
for xs, ys in minibatches:
lr.partial_fit(xs, ys, classes=classes)
(Здесь я прохожу classes
для каждого мини-пакета, который не является необходимым, но не наносит вреда и делает код короче.)