我尝试使用SGD对大型数据集进行分类。由于数据太大而无法放入内存,我希望使用 partial_fit 方法来训练分类器。我选择了一个适合内存的数据集样本(100,000行)来测试 fit 与 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)。
在第二种情况下,我必须在数据上传递60次以达到相同的准确度。
为什么会出现这种差异(5对60)?或者我做错了什么?
答案 0 :(得分:51)
我终于找到了答案。您需要在每次迭代之间随机播放训练数据,因为在实例化模型时设置 shuffle = True 在使用 partial_fit 时不会随机播放数据(它仅适用于 fit )。注意:在sklearn.linear_model.SGDClassifier page上找到此信息会很有帮助。
修订后的代码如下:
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))