Scikit-learn 朴素贝叶斯在稀疏字符串分类中的莫名其妙的结果

我正在尝试使用scikit-learn模块进行文本分类。这是一个包含大量独特词汇的数据集,其性质可以从下面的例子中看出,

train_counts = count_vect.fit_transform(data)train_counts.shapeprint len(range(len(data)-1)) clf = MultinomialNB(alpha=1).fit(train_counts, range(len(data)) )docs_new = ['Modern Warfare 2', 'Modern Warfare 3', 'Modern Warfare 1', 'Modern Warfare 4', 'Modern Warfare', 'Mahjong Kakutou Club', 'Mass Effect 2']new_counts = count_vect.transform(docs_new)predicted = clf.predict(new_counts)for doc, category in zip(docs_new, predicted):    print '%r => %s' % (doc, target_names[category])

输出看起来像这样。

763'Modern Warfare 2' => Call of Duty: Modern Warfare 3'Modern Warfare 3' => Call of Duty: Modern Warfare 3'Modern Warfare 1' => Call of Duty: Modern Warfare 3'Modern Warfare 4' => Call of Duty: Modern Warfare 3'Modern Warfare' => Call of Duty: Modern Warfare 3'Mahjong Kakutou Club' => Mahjong Kakutou Club'Mass Effect 2' => Mass Effect 2

这是一个多项式示例,但我使用伯努利示例时得到相同的结果。我尝试了从0到1000000的alpha值。谁能解释这是为什么?

编辑:我应该说明一下,存在以下类别:Call of Duty: Modern Warfare, Call of Duty: Modern Warfare 2… 以及其他大多数游戏,所有PlayStation游戏的列表是从维基百科获取的。

此外,使用完整版本,例如以“Call of Duty: Modern Warfare 2”作为测试字符串,会产生相同的结果。

我最初使用的是NLTK分类器,但由于某种原因,它对像“Kakutou”这样的词语不重视,这些词语在其他例子中不存在。(显然Scikit的分类器会重视)它没有像Scikit分类器那样对数字有问题。

任何指导或信息在这里都将非常宝贵。

谢谢

编辑:数据集来自这里 http://en.wikipedia.org/wiki/List_of_PlayStation_3_games 这是第一列,每个例子都有一个标签和内容,它们是相同的


回答:

代码没有显示count_vect是如何构建的,但如果它只是一个默认初始化的CountVectorizer,那么它会忽略字符标记(即系列号),使得所有“Modern Warfare…”标题的标记化与“Modern Warfare”相同:

>>> from sklearn.feature_extraction.text import CountVectorizer as CV>>> count_vect=CV()>>> docs_new = ['Modern Warfare 2', 'Modern Warfare 3', 'Modern Warfare 1', 'Modern Warfare 4', 'Modern Warfare A', 'Modern Warfare 44', 'Modern Warfare AA', 'Modern Warfare', 'Mahjong Kakutou Club', 'Mass Effect 2']>>> new_counts = count_vect.fit_transform(docs_new)>>> count_vect.inverse_transform(new_counts)[array([u'modern', u'warfare'],       dtype='<U7'), array([u'modern', u'warfare'],       dtype='<U7'), array([u'modern', u'warfare'],       dtype='<U7'), array([u'modern', u'warfare'],       dtype='<U7'), array([u'modern', u'warfare'],       dtype='<U7'), array([u'44', u'modern', u'warfare'],       dtype='<U7'), array([u'aa', u'modern', u'warfare'],       dtype='<U7'), array([u'modern', u'warfare'],       dtype='<U7'), array([u'club', u'kakutou', u'mahjong'],       dtype='<U7'), array([u'effect', u'mass'],       dtype='<U7')]

这是因为scikit向量化器的默认设置是token_pattern=r'(?u)\b\w\w+\b'模型只是任意地打破了这些标题之间的联系,因为训练和预测都没有看到这些标题之间的任何区别。你可以通过使用token_pattern=r'(?u)\b\w+\b'来解决这个问题

>>> from sklearn.feature_extraction.text import CountVectorizer as CV>>> count_vect=CV(token_pattern=r'(?u)\b\w+\b')>>> docs_new = ['Modern Warfare 2', 'Modern Warfare 3', 'Modern Warfare 1', 'Modern Warfare 4', 'Modern Warfare A', 'Modern Warfare 44', 'Modern Warfare AA', 'Modern Warfare', 'Mahjong Kakutou Club', 'Mass Effect 2']>>> new_counts = count_vect.fit_transform(docs_new)>>> count_vect.inverse_transform(new_counts)[array([u'2', u'modern', u'warfare'],       dtype='<U7'), array([u'3', u'modern', u'warfare'],       dtype='<U7'), array([u'1', u'modern', u'warfare'],       dtype='<U7'), array([u'4', u'modern', u'warfare'],       dtype='<U7'), array([u'a', u'modern', u'warfare'],       dtype='<U7'), array([u'44', u'modern', u'warfare'],       dtype='<U7'), array([u'aa', u'modern', u'warfare'],       dtype='<U7'), array([u'modern', u'warfare'],       dtype='<U7'), array([u'club', u'kakutou', u'mahjong'],       dtype='<U7'), array([u'2', u'effect', u'mass'],       dtype='<U7')]

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注