Scikit-learn: отримання SGDClassifier для прогнозування, а також логістичної регресії


24

Способом навчання логістичної регресії є використання стохастичного градієнтного спуску, яке scikit-learn пропонує інтерфейс.

Що я хотів би зробити, це взяти SGDClassifier для scikit-learn і мати його так, як логістична регресія тут . Однак я повинен бракувати деяких удосконалень машинного навчання, оскільки мої бали не рівноцінні.

Це мій поточний код. Що мені не вистачає на SGDClassifier, який би дав йому ті самі результати, що і Логістична регресія?

from sklearn import datasets
from sklearn.linear_model import LogisticRegression
from sklearn.linear_model import SGDClassifier
import numpy as np
import pandas as pd
from sklearn.cross_validation import KFold
from sklearn.metrics import accuracy_score

# Note that the iris dataset is available in sklearn by default.
# This data is also conveniently preprocessed.
iris = datasets.load_iris()
X = iris["data"]
Y = iris["target"]

numFolds = 10
kf = KFold(len(X), numFolds, shuffle=True)

# These are "Class objects". For each Class, find the AUC through
# 10 fold cross validation.
Models = [LogisticRegression, SGDClassifier]
params = [{}, {"loss": "log", "penalty": "l2"}]
for param, Model in zip(params, Models):
    total = 0
    for train_indices, test_indices in kf:

        train_X = X[train_indices, :]; train_Y = Y[train_indices]
        test_X = X[test_indices, :]; test_Y = Y[test_indices]

        reg = Model(**param)
        reg.fit(train_X, train_Y)
        predictions = reg.predict(test_X)
        total += accuracy_score(test_Y, predictions)
    accuracy = total / numFolds
    print "Accuracy score of {0}: {1}".format(Model.__name__, accuracy)

Мій вихід:

Accuracy score of LogisticRegression: 0.946666666667
Accuracy score of SGDClassifier: 0.76

3
Питання та спостереження: наскільки стабільна ваша точність SGD на повторних пробігах? два алгоритми не є еквівалентними і не обов'язково виробляти однакову точність з урахуванням одних і тих же даних. Практично ви можете спробувати змінити епохи та / або рівень навчання для SGD. Крім цього, ви можете спробувати нормалізувати функції для SGD.
image_doctor

Отже, я не перевіряв SGD на повторних запусках, оскільки вищевказане використовує 10-кратну перехресну перевірку; для мене цього вистачило.
hlin117

Чи можете ви пояснити мені, чому такі алгоритми не рівнозначні? Якщо я дивлюся на SGDClassifier тут, він згадує "Втрата" log "дає логістичну регресію, імовірнісний класифікатор". Я вважаю, що в моїх знаннях машинного навчання є розрив.
hlin117

Без детального вивчення реалізацій я не думаю, що я можу бути конкретним щодо того, чому вони не є еквівалентними, але хороша підказка про те, що вони не є рівнозначними, полягає в тому, що результати для кожного методу значно відрізняються. Я думаю, що це має відношення до властивостей конвергенції методів оцінки, що використовуються в кожному.
image_doctor

1
Ці алгоритми відрізняються тим, що при логістичній регресії використовується градієнтне спуск, де в якості стохастичного градієнтного спуску використовується стохастичний градієнтний спуск. Конвергенція колишнього буде більш ефективною і дасть кращі результати. Однак, оскільки розмір набору даних збільшується, SGDC повинен підійти до точності логістичної регресії. Параметри для GD означають різні речі, ніж параметри для SGD, тому слід спробувати їх трохи коригувати. Я б запропонував трохи пограти з (зменшившись) курсами навчання SGD, щоб спробувати досягти кращої конвергенції, оскільки це може трохи бити.
AN6U5

Відповіді:


23

Зауваження щодо номера ітерації розміщено на місці. За замовчуванням SGDClassifier n_iterце 5означає , що ви робите 5 * num_rowsкроки у ваговому просторі. За типовими даними правило склеарного правила становить ~ 1 мільйон кроків. Для вашого прикладу просто встановіть його на 1000, і він може спочатку досягти толерантності. Ваша точність нижча, SGDClassifierоскільки вона досягає межі ітерації перед толерантністю, тому ви "рано зупиняєтесь"

Модифікація вашого коду швидко і брудно, я отримую:

# Added n_iter here
params = [{}, {"loss": "log", "penalty": "l2", 'n_iter':1000}]

for param, Model in zip(params, Models):
    total = 0
    for train_indices, test_indices in kf:
        train_X = X[train_indices, :]; train_Y = Y[train_indices]
        test_X = X[test_indices, :]; test_Y = Y[test_indices]
        reg = Model(**param)
        reg.fit(train_X, train_Y)
        predictions = reg.predict(test_X)
        total += accuracy_score(test_Y, predictions)

    accuracy = total / numFolds
    print "Accuracy score of {0}: {1}".format(Model.__name__, accuracy)

Accuracy score of LogisticRegression: 0.96
Accuracy score of SGDClassifier: 0.96

4

SGDClassifier, як випливає з назви, використовує походження Stohastic Gradient як свій алгоритм оптимізації.

Якщо ви подивитесь на реалізацію LogisiticRegression у Sklearn, передбачено п’ять методів оптимізації (solver), і за замовчуванням це "LibLinear", який використовує координатне сходження (CD) для конвергенції.

Окрім кількості ітерацій, оптимізація, тип регуляризації (штраф) та її величина (С) також впливають на продуктивність алгоритму.

Якщо ви запускаєте його в настройці набору даних Iris, всі ці гіперпараметри можуть не принести суттєвих змін, але для складного набору даних вони відіграють важливу роль.

Для отримання додаткової інформації ви можете ознайомитись з документацією щодо логістичної регресії Sklearn .


3

Також слід здійснити пошук сітки для гіперпараметра "альфа" для SGDClassifier. Це чітко зазначено в документації на склеарн, і з мого досвіду має великий вплив на точність. Другий гіперпараметр, на який слід звернути увагу, - це "n_iter" - проте я побачив менший ефект із моїми даними.


1

TL; DR : Ви можете вказати сітку альфа та n_iter (або max_iter ) і використовувати parfit для гіпероптимізації на SGDClassifier

Мій колега, Вінай Патлолла, написав чудову публікацію в блозі на тему: Як зробити класифікатор SGD, а також логістичну регресію за допомогою parfit .

Parfit - це пакет оптимізації гіперпараметрів, який він використовував для пошуку відповідної комбінації параметрів, які слугували оптимізації виконання SGDClassifier, а також логістичної регресії на його прикладі даних, встановлених за набагато менший час.

Підводячи підсумок, двома ключовими параметрами для SGDClassifier є альфа та n_iter . Цитуйте Vinay безпосередньо:

n_iter у sklearn за замовчуванням є None. Ми встановлюємо його тут на досить велику кількість (1000). Альтернативний параметр n_iter, який нещодавно був доданий, - max_iter. Ця ж порада повинна застосовуватися і до max_iter.

Альфа-параметр служить подвійному призначенню. Це як параметр регуляризації, так і початковий рівень навчання за графіком за замовчуванням. Це означає, що, крім регуляції коефіцієнтів логістичної регресії, вихід моделі залежить від взаємодії між альфа та кількістю епох (n_iter), яку виконує звичайна установка. Зокрема, оскільки альфа стає дуже маленькою, n_iter необхідно збільшувати, щоб компенсувати повільну швидкість навчання. Ось чому безпечніше (але повільніше) вказувати достатньо великий n_iter, наприклад 1000, при пошуку в широкому діапазоні альфа.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.