可扩展或在线的核外多标签分类器

Gau*_*mar 12 classification machine-learning document-classification scikit-learn text-classification

在这个问题上,过去2-3周我一直在绞尽脑汁.我有一个多标签(不是多级)的问题,每个样品可以属于多个标签的.

我有大约450万个文本文档作为训练数据,大约100万个作为测试数据.标签大约35K.

我正在使用scikit-learn.对于特征提取我以前使用TfidfVectorizer它没有规模可言,我现在用的HashVectorizer这是更好的,但不是可扩展鉴于我有文件的数量.

vect = HashingVectorizer(strip_accents='ascii', analyzer='word', stop_words='english', n_features=(2 ** 10))
Run Code Online (Sandbox Code Playgroud)

SKlearn提供OneVsRestClassifier,我可以在其中提供任何估算器.对于多标签,我发现LinearSVC和SGDClassifier只能正常工作.根据我的基准,SGD在内存和时间方面都优于LinearSVC.所以,我有这样的事情

clf = OneVsRestClassifier(SGDClassifier(loss='log', penalty='l2', n_jobs=-1), n_jobs=-1)
Run Code Online (Sandbox Code Playgroud)

但是这有一些严重的问题:

  1. OneVsRest没有partial_fit方法,这使得无法进行核外学习.那有什么替代品吗?
  2. HashingVectorizer/Tfidf都可以在单个核心上运行,并且没有任何n_jobs参数.散列文档需要花费太多时间.任何替代/建议?n_features的值是否正确?
  3. 我测试了100万份文件.Hashing需要15分钟,当涉及到clf.fit(X,y)时,我收到一个MemoryError,因为OvR内部使用LabelBinarizer并且它试图分配一个维度矩阵(yx类),这是不可能分配的.我该怎么办?
  4. 还有其他任何具有可靠和可扩展的多标签算法的库吗?我知道genism和mahout但他们两个都没有任何多标签情况?

And*_*ler 8

我会手工做多标签部分.无论如何,OneVsRestClassifier将它们视为独立问题.您可以创建n_labels许多分类器,然后在它们上调用partial_fit.如果你只想要哈希一次(我建议),你不能使用管道.不确定加速哈希矢量化器.你得问@Larsmans和@ogrisel;)

partial_fit上OneVsRestClassifier将是一个很好的补充,我看不出它一个特别的问题,其实.您也可以尝试自己实现并发送PR.

  • 您可以尝试将"SGDClassifier"和"PassiveAggressiveClassifier"的独立实例以及"MultinomialNB"作为二元分类器(每个标签一个)进行训练.然后,您可以根据"predict_proba"或"decision_function"的值对最高预测进行排名,并采用前5个标签(如果预测低于0.5 proba或否定决策函数,则为更少).您还可以训练第二个回归模型,该模型采用二元分类模型的概率,并预测每个实例保留的正标签的预期数量(前k中k的值). (3认同)

Fre*_*Foo 8

  1. OneVsRestClassifier实现的算法非常简单:当有K类时,它只适合K二元分类器.您可以在自己的代码中执行此操作,而不是依赖于此.您也可以并行处理最多K个核心:只运行K个进程.如果您的机器中有多个类而不是处理器,则可以使用GNU parallel等工具安排培训.OneVsRestClassifier
  2. scikit-learn中的多核支持正在进行中; Python中的细粒度并行编程非常棘手.有潜在的优化HashingVectorizer,但我(其中一个散列码的作者)还没有完成它.
  3. 如果你按照我(和安德烈亚斯)的建议做自己的一对一休息,这应该不再是问题了.
  4. (1.)中的技巧适用于任何分类算法.

至于功能的数量,它取决于问题,但对于大规模的文本分类2 ^ 10 = 1024似乎非常小.我会尝试2 ^ 18 - 2 ^ 22左右的东西.如果训练具有L1惩罚的模型,则可以调用sparsify训练模型将其权重矩阵转换为更节省空间的格式.

  • 如果您有35K二进制分类器具有2**18个功能,则只需存储73GB即可存储聚合模型.一旦在预测时学习了权重以节省内存,就有可能对模型进行稀疏化,但是在scikit-learn中尚未实现AFAIK.您可以使用`safe_sparse_dot`手动实现`decision_function`来执行此操作. (2认同)
  • @ogrisel:线性分类器有一个`sparsify`方法,可以将`coef_`转换为稀疏矩阵格式(CSR). (2认同)