使用scikit-learn(sklearn)进行批量梯度下降
我正在使用Scikit-Learn(sklearn)玩一个一对多的逻辑回归分类器。我有一个很大的数据集,一次性运行太慢了;而且我还想在训练过程中研究学习曲线。
我想用批量梯度下降来训练我的分类器,比如每次处理500个样本。请问有没有办法用sklearn来做到这一点,还是说我应该放弃sklearn,自己写一个?
这是我目前的进展:
from sklearn.linear_model import LogisticRegression
from sklearn.multiclass import OneVsRestClassifier
# xs are subsets of my training data, ys are ground truth for same; I have more
# data available for further training and cross-validation:
xs.shape, ys.shape
# => ((500, 784), (500))
lr = OneVsRestClassifier(LogisticRegression())
lr.fit(xs, ys)
lr.predict(xs[0,:])
# => [ 1.]
ys[0]
# => 1.0
也就是说,它能正确识别一个训练样本(是的,我知道用新数据来评估会更好——这只是一个快速的测试)。
关于批量梯度下降:我还没有做到创建学习曲线,但可以简单地在后续的训练数据子集上反复运行fit
吗?还是说有其他函数可以批量训练?文档和谷歌对此没有太多说明。谢谢!
1 个回答
32
你想要的不是批量梯度下降,而是随机梯度下降。批量学习是指一次性使用整个训练集进行学习,而你描述的其实是小批量学习。这种方法在 sklearn.linear_model.SGDClassifier
中实现,如果你给它选项 loss="log"
,它会适配一个逻辑回归模型。
使用 SGDClassifier
和 LogisticRegression
时,不需要把估计器包裹在 OneVsRestClassifier
中——这两个模型默认就支持一对多的训练。
# you'll have to set a few other options to get good estimates,
# in particular n_iterations, but this should get you going
lr = SGDClassifier(loss="log")
接下来,要进行小批量训练,使用 partial_fit
方法,而不是 fit
。第一次使用时,你需要提供一个类别列表,因为并不是每个小批量中都会包含所有类别:
import numpy as np
classes = np.unique(["ham", "spam", "eggs"])
for xs, ys in minibatches:
lr.partial_fit(xs, ys, classes=classes)
(在这里,我为每个小批量传递了 classes
,这不是必须的,但这样做也没坏处,而且可以让代码更简洁。)