sklearn中的SVM支持增量(在线)学习吗?

59

我目前正在设计一个文本文章推荐系统(二进制分类为“有趣”或“不有趣”)。我的要求之一是它应该持续更新以适应变化的趋势。

据我所知,实现这个功能的最佳方法是利用支持增量/在线学习的机器学习算法。

感知器和Winnow等算法支持在线学习,但我不完全确定支持向量机是否也支持。scikit-learn Python库是否支持在线学习,如果支持,支持向量机是否可以利用它?

显然,我并不完全依赖使用支持向量机,但由于其全面的性能,通常会选择它作为二元分类的默认算法。最终我愿意改用任何最合适的算法。


我会担心过度拟合和反馈问题。如果你的机器学习算法倾向于将某些相空间区域标记为“有趣”,那么这些区域就会更加突出,你会在那里得到更多的元素,从而增加数据点的数量......你可以随时积累一批数据点并重新训练机器学习模型;如果你的初始步骤与上次相同,那么速度应该很快。 - Davidmh
Michael Aquilina:我正在处理类似的问题。你能分享一下你解决该问题时的见解吗? - Anuj Gupta
6个回答

44
虽然存在用于SVM的在线算法,但现在需要指定您是否想要核SVM还是线性SVM,因为已经为线性SVM的特殊情况开发了许多有效的算法。
对于线性情况,如果您使用scikit-learn中的SGD分类器,并使用铰链损失和L2正则化,您将获得一个可以在线/增量更新的SVM。您可以将其与近似核的特征变换相结合,以获得类似于在线核SVM的结果。
“其中之一的规格是它应该不断更新以适应变化的趋势。”这被称为概念漂移,简单的在线SVM无法很好地处理它。使用PassiveAggresive分类器可能会给您更好的结果,因为它的学习率不会随时间而减少。
假设您在训练/运行时得到反馈,您可以尝试检测准确率随时间下降,并在准确率开始下降时开始训练新模型(并在您认为它变得更加准确时切换到新模型)。JSAT有两种漂移检测方法(请参见jsat.driftdetectors),可用于跟踪准确性并在其发生变化时提醒您。

它还具有更多的在线线性和核方法。

(偏见声明:我是JSAT的作者)。


32

也许我太天真了,但我认为值得提一下如何在逐步呈现数据时更新科学工具箱SGD分类器

clf = linear_model.SGDClassifier()
x1 = some_new_data
y1 = the_labels
clf.partial_fit(x1,y1)
x2 = some_newer_data
y2 = the_labels
clf.partial_fit(x2,y2)

3
我刚刚在查看网站的缓存版本时发现一个重要的实施提示:就分类而言,需要注意的是,虽然无状态特征提取例程可能能够处理新/未见过的属性,但增量学习器本身可能无法处理新/未见过的目标类。在这种情况下,您必须使用“classes=”参数将所有可能的类传递给第一个partial_fit调用。 - Jariani
1
是的,sgdclassifier无法进行增量学习。如果我们在fit()之前提供所有新数据,那么使用partial_fit()的目的是什么?在您的IDE中运行此代码https://ideone.com/SFwdI5。我可以在没有partial_fit的情况下进行预测。如果我在初始fit()之前提供所有数据,我只需从头开始训练所有数据。您指定的方式对我来说并没有按照增量更新已经通过fit()训练的预先存在的模型的意义而起作用。使用scikit是否可以加载使用fit()生成的预先训练的模型,并使用partial_fit更新它以及新样本? - user1
2
这个答案可能有助于解决这些问题。使用warm_start=True来结合fit()partial_fit(): https://stackoverflow.com/questions/49208617/sklearn-partial-fit-not-showing-accurate-results-as-fit/51027226#51027226 - eddy85br

14

技术方面

简短的回答是不支持。Sklearn的实现(以及大部分现有的其他实现)都不支持在线SVM训练。虽然可以通过增量方式来训练SVM,但这并不是一件容易的事情。

如果您想限制自己只使用线性情况,那么答案是是的,因为Sklearn提供了随机梯度下降(SGD),它具有最小化SVM标准的选项。

您还可以尝试使用支持在线SVM训练的pegasos库。

理论方面

趋势适应问题目前在机器学习社区中非常流行。正如@Raff所述,它被称为概念漂移,并且有许多方法,通常是元模型,它们分析“趋势的行为方式”并更改底层机器学习模型(例如强制其在数据子集上重新训练)。因此,您在这里有两个独立的问题:

  • 在线培训问题,这是纯技术问题,可以通过SGD或其他库来解决,而不是使用Sklearn。
  • 概念漂移,这是当前热门话题,没有“只需有效”的答案。有许多可能性、假设和概念证明,而目前没有一种普遍接受的处理此现象的方式,事实上,许多机器学习博士论文目前都基于这个问题。

5

对于批处理学习任务,SGD通常具有递减的学习速率,并多次遍历训练集。因此,对于纯在线学习,请确保在sklearn.linear_model.SGDClassifier()中将learning_rate设置为'constant',并设置eta0= 0.1或任何所需值。因此,操作步骤如下:

clf= sklearn.linear_model.SGDClassifier(learning_rate = 'constant', eta0 = 0.1, shuffle = False, n_iter = 1)
# get x1, y1 as a new instance
clf.partial_fit(x1, y1)
# get x2, y2
# update accuracy if needed
clf.partial_fit(x2, y2)

请问您能解释一下如何添加x2,y2吗?我收到了一个错误提示,说SGDClassifier的所有类标签都必须在第一次partial_fit()之前包含。请在您的IDE中运行此代码:https://ideone.com/qtGpnY。结果发现,在在线学习方面,partial_fit没有用处。对于流数据,不可能在第一次initial_fit()之前就知道标签。请问您能否添加一些虚拟数据,并提供一个可工作的代码示例? - user1
这取决于你如何读取数据,或者你是否从数据流中获取数据点。x2和y2是你的第二个训练实例。 - Alaleh Rz

4
一种扩展 SVM 的方法是将大型数据集分成可以被 SVM 算法安全处理的批次,然后分别为每个批次找到支持向量,最后在由所有批次中找到的支持向量组成的数据集上构建结果 SVM 模型。
更新到趋势可以通过在每次运行训练管道时维护一个时间窗口来实现。例如,如果您每天进行一次训练,并且一个月的历史数据中有足够的信息,那么请从最近 30 天获取的历史数据创建您的训练数据集。

是说所有批次拟合的模型的集合吗? - CutePoison

3

如果您对概念漂移的在线学习感兴趣,这里有一些先前的工作。

  1. 概念漂移学习:综述https://arxiv.org/pdf/1010.4784.pdf

  2. 概念漂移问题:定义和相关工作http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.58.9085&rep=rep1&type=pdf

  3. 概念漂移适应的调查http://www.win.tue.nl/~mpechen/publications/pubs/Gama_ACMCS_AdaptationCD_accepted.pdf

  4. 流数据的MOA概念漂移主动学习策略http://videolectures.net/wapa2011_bifet_moa/

  5. 概念漂移算法流http://people.cs.georgetown.edu/~maloof/pubs/maloof.heilbronn12.handout.pdf

  6. 使用概念漂移挖掘数据流http://www.cs.put.poznan.pl/dbrzezinski/publications/ConceptDrift.pdf

  7. 使用流处理和机器学习分析时间序列数据http://www.ibmbigdatahub.com/blog/analyzing-time-series-data-stream-processing-and-machine-learning


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接