web-dev-qa-db-ja.com

Sklearn SGDClassifier部分適合

SGDを使用して大規模なデータセットを分類しようとしています。データが大きすぎてメモリに収まらないので、partial_fitメソッドを使用して分類器をトレーニングしたいと思います。テストするメモリに適合するデータセットのサンプル(100,000行)を選択しましたfit vs. partial_fit

from sklearn.linear_model import SGDClassifier

def batches(l, n):
    for i in xrange(0, len(l), n):
        yield l[i:i+n]

clf1 = SGDClassifier(shuffle=True, loss='log')
clf1.fit(X, Y)

clf2 = SGDClassifier(shuffle=True, loss='log')
n_iter = 60
for n in range(n_iter):
    for batch in batches(range(len(X)), 10000):
        clf2.partial_fit(X[batch[0]:batch[-1]+1], Y[batch[0]:batch[-1]+1], classes=numpy.unique(Y))

次に、同一のテストセットで両方の分類器をテストします。最初のケースでは、100%の精度が得られます。私が理解しているように、SGDはデフォルトでトレーニングデータを5回通過します(n_iter = 5)。

2番目のケースでは、同じ精度を得るためにデータを60回渡さなければなりません。

なぜこの違い(5対60)?それとも私は何か間違ったことをしていますか?

35
David M.

私はついに答えを見つけました。 各反復の間にトレーニングデータをシャッフルするが必要です。モデルをインスタンス化するときにshuffle = Trueを設定すると、partial_fitfitにのみ適用されます)。注: sklearn.linear_model.SGDClassifierページ でこの情報を見つけると役に立ちます。

修正されたコードは次のようになります。

from sklearn.linear_model import SGDClassifier
import random
clf2 = SGDClassifier(loss='log') # shuffle=True is useless here
shuffledRange = range(len(X))
n_iter = 5
for n in range(n_iter):
    random.shuffle(shuffledRange)
    shuffledX = [X[i] for i in shuffledRange]
    shuffledY = [Y[i] for i in shuffledRange]
    for batch in batches(range(len(shuffledX)), 10000):
        clf2.partial_fit(shuffledX[batch[0]:batch[-1]+1], shuffledY[batch[0]:batch[-1]+1], classes=numpy.unique(Y))
55
David M.