Scikit-learn: Bắt SGDClassifier để dự đoán cũng như hồi quy logistic


24

Một cách để huấn luyện Hồi quy logistic là sử dụng phương pháp giảm độ dốc ngẫu nhiên, mà scikit-learn cung cấp giao diện.

Những gì tôi muốn làm là lấy một scikit-học của SGDClassifier và có nó ghi bàn giống như một Logistic Regression đây . Tuy nhiên, tôi phải thiếu một số cải tiến về máy học, vì điểm của tôi không tương đương.

Đây là mã hiện tại của tôi. Tôi còn thiếu gì trên SGDClassifier mà nó sẽ tạo ra kết quả tương tự như hồi quy logistic?

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)

Đầu ra của tôi:

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

3
Một câu hỏi và một quan sát: độ chính xác của SGD ổn định như thế nào trên các lần chạy lặp lại? hai thuật toán không tương đương và sẽ không nhất thiết tạo ra độ chính xác như nhau cho cùng một dữ liệu. Thực tế, bạn có thể thử thay đổi kỷ nguyên và hoặc tỷ lệ học tập cho SGD. Ngoài ra, bạn có thể thử bình thường hóa các tính năng cho SGD.
image_doctor

Vì vậy, tôi đã không kiểm tra SGD trên các lần chạy lặp lại vì ở trên sử dụng xác nhận chéo 10 lần; Đối với tôi điều này là đủ.
hlin117

Bạn có thể giải thích cho tôi tại sao các thuật toán này không tương đương? Nếu tôi nhìn vào SGDClassifier ở đây, nó đề cập đến "Mất 'log" mang lại hồi quy logistic, một phân loại xác suất. " Tôi tin rằng có một lỗ hổng trong máy học kiến ​​thức của tôi.
hlin117

Nếu không có một nghiên cứu chi tiết về việc triển khai, tôi không nghĩ mình có thể cụ thể về lý do tại sao chúng không tương đương, nhưng một manh mối tốt là chúng không tương đương là kết quả cho mỗi phương pháp khác nhau đáng kể. Tôi đoán là nó phải làm với các thuộc tính hội tụ của các phương thức ước lượng được sử dụng trong mỗi phương thức.
image_doctor

1
Các thuật toán này là khác nhau bởi vì hồi quy logistic sử dụng giảm dần độ dốc trong đó như độ dốc dốc ngẫu nhiên sử dụng độ dốc dốc ngẫu nhiên. Sự hội tụ của cái trước sẽ hiệu quả hơn và sẽ mang lại kết quả tốt hơn. Tuy nhiên, khi kích thước của tập dữ liệu tăng lên, SGDC nên tiếp cận độ chính xác của hồi quy logistic. Các tham số cho GD có nghĩa là những thứ khác với các tham số cho SGD, vì vậy bạn nên thử điều chỉnh chúng một chút. Tôi sẽ đề nghị chơi với (giảm) tốc độ học tập của SGD một chút để cố gắng hội tụ tốt hơn vì nó có thể bị phá vỡ xung quanh một chút.
AN6U5

Câu trả lời:


23

Các ý kiến ​​về số lần lặp là tại chỗ. Mặc định SGDClassifier n_iter5bạn thực 5 * num_rowshiện các bước trong không gian trọng lượng. Các quy tắc sklearn của ngón tay cái là ~ 1 triệu bước cho dữ liệu điển hình. Ví dụ của bạn, chỉ cần đặt nó thành 1000 và nó có thể đạt đến dung sai đầu tiên. Độ chính xác của bạn thấp hơn SGDClassifierbởi vì nó đạt giới hạn lặp trước khi dung sai nên bạn "dừng lại sớm"

Sửa đổi mã của bạn nhanh và bẩn tôi nhận được:

# 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, như tên cho thấy, sử dụng gốc Stochastic Gradient làm thuật toán tối ưu hóa.

Nếu bạn nhìn vào việc triển khai LogisiticRegression trong Sklearn, có năm kỹ thuật tối ưu hóa (bộ giải) được cung cấp và theo mặc định, đó là 'LibLinear' sử dụng tọa độ gốc tọa độ (CD) để hội tụ.

Khác với số lần lặp, tối ưu hóa, loại chính quy (hình phạt) và cường độ của nó (C) cũng ảnh hưởng đến hiệu suất của thuật toán.

Nếu bạn đang chạy nó trên bộ điều chỉnh tập dữ liệu Iris, tất cả các tham số siêu này có thể không mang lại thay đổi đáng kể nhưng đối với tập dữ liệu phức tạp thì chúng có vai trò có ý nghĩa.

Để biết thêm, bạn có thể tham khảo Tài liệu hồi quy logistic Sklearn .


3

Bạn cũng nên thực hiện tìm kiếm dạng lưới cho siêu tham số "alpha" cho SGDClassifier. Nó được đề cập rõ ràng trong tài liệu sklearn và từ kinh nghiệm của tôi có ảnh hưởng lớn đến độ chính xác. Siêu tham số thứ hai bạn nên xem là "n_iter" - tuy nhiên tôi thấy hiệu ứng nhỏ hơn với dữ liệu của mình.


1

TL; DR : Bạn có thể chỉ định lưới alphan_iter (hoặc max_iter ) và sử dụng parfit để siêu tối ưu hóa trên SGDClassifier

Đồng nghiệp của tôi, Vinay Patlolla, đã viết một bài đăng blog tuyệt vời về Cách làm cho Trình phân loại SGD hoạt động cũng như Hồi quy logistic bằng cách sử dụng parfit .

Parfit là gói tối ưu hóa siêu tham số mà anh ta đã sử dụng để tìm ra sự kết hợp các tham số thích hợp phục vụ để tối ưu hóa SGDClassifier để thực hiện cũng như Hồi quy logistic trên dữ liệu mẫu của anh ta trong thời gian ngắn hơn nhiều.

Tóm lại, hai tham số chính cho SGDClassifier là alphan_iter . Để báo giá trực tiếp cho Vinay:

Theo mặc định, n_iter trong sklearn là Không có. Chúng tôi đang đặt nó ở đây với số lượng đủ lớn (1000). Một tham số thay thế cho n_iter, đã được thêm gần đây, là max_iter. Lời khuyên tương tự nên áp dụng cho max_iter.

Các siêu tham số alpha phục vụ một mục đích kép. Nó vừa là tham số chính quy vừa là tỷ lệ học ban đầu theo lịch trình mặc định. Điều này có nghĩa là, ngoài việc thường xuyên hóa các hệ số hồi quy logistic, đầu ra của mô hình phụ thuộc vào sự tương tác giữa alpha và số epoch (n_iter) mà thói quen phù hợp thực hiện. Cụ thể, khi alpha trở nên rất nhỏ, n_iter phải được tăng lên để bù cho tốc độ học tập chậm. Đây là lý do tại sao an toàn hơn (nhưng chậm hơn) khi chỉ định n_iter đủ lớn, ví dụ 1000, khi tìm kiếm trên một loạt các bảng chữ cái.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.