part_fit с SGDClassifier дает колеблющуюся точность
У меня есть данные в разреженной матрице. Сейчас я сначала работаю над подмножеством с ~500 тыс. Строк, прежде чем начинать большие вычисления. Данные представляют собой число биграмм плюс энтропию и длину строки, а полный набор данных содержит 100 миллионов строк и 1400 столбцов. Модель предназначена для характеристики этих строк, поэтому я использую SGDClassifier
для логистической регрессии.
Из-за большого размера я решил использовать partial_fit
на моем SGDClassifier
, но рассчитывается area-under-curve
ценность, которую я получаю в каждую эпоху, кажется, сильно колеблется.
Вот мой код:
from sklearn.linear_model import SGDClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
model = SGDClassifier(loss='log', alpha=1e-10, n_iter=50, n_jobs=-1, shuffle=True)
for f in file_list:
data = dill.load(open(f))
X_train, X_test, y_train, y_test = train_test_split(data, labels, test_size=0.2)
X_train, X_holdout, y_train, y_holdout = train_test_split(data, labels, test_size=0.05)
for ep in range(max_epoch):
model.partial_fit(X_train, y_train, classes=np.unique(y_train))
# Calculate Area under ROC curve to see if things improve
probs = model.predict_proba(X_holdout)
auc = roc_auc_score(y_holdout, [x[1] for x in probs])
if auc > best_auc: best_auc = auc
print('Epoch: %d - auc: %.2f (best %.2f)' %(ep, auc, best_auc))
Что происходит, так это то, что auc быстро поднимается до ~0.9, но затем сильно колеблется. Иногда он падает до ~ 0,5-0,6 даже, а затем обратно. Я думал, что более логично auc
следует продолжать увеличиваться, как правило, с каждой эпохой, с возможными лишь небольшими провалами, пока не будет найдено равновесное значение, при котором больше тренировок вряд ли что-либо улучшит.
Есть ли что-то, что я делаю неправильно, или это возможно "нормальное" поведение с partial_fit
? Я никогда не видел такого поведения, когда я использовал fit
на меньшем наборе данных.
0 ответов
Обычно, partial_fit
было замечено, что они подвержены снижению или колебаниям в точности. В некоторой степени это можно немного смягчить, перетасовывая и предоставляя только небольшие части всего набора данных. Но для больших данных онлайн-обучение, похоже, дает только снижение точности с SGDClassifier/SVM Classifier.
Я попытался поэкспериментировать с этим и обнаружил, что использование низкой скорости обучения иногда может нам помочь. Грубая аналогия заключается в том, что повторное обучение одной и той же модели на больших данных приводит к тому, что модель забывает то, что она извлекла из предыдущих данных. Таким образом, использование крошечной скорости обучения замедляет скорость обучения, а также снижает скорость забывания!
Вместо того, чтобы указывать ставку вручную, мы можем использовать adaptive
функция скорости обучения, предоставляемая sklearn
. Обратите внимание на часть инициализации модели,
model = SGDClassifier(loss="hinge", penalty="l2", alpha=0.0001, max_iter=3000, tol=None, shuffle=True, verbose=0, learning_rate='adaptive', eta0=0.01, early_stopping=False)
Это описано в [scikit docs] как:
"адаптивный": eta = eta0, пока обучение продолжает уменьшаться. Каждый раз, когда n_iter_no_change последовательных эпох не может уменьшить потери на обучение на tol или не может увеличить оценку валидации на tol, если Early_stopping имеет значение True, текущая скорость обучения делится на 5.
Я получил действительно хорошие результаты (от начального падения с 98% до 28% в четвертой части набора данных) до 100% точности модели с изменением скорости обучения.