我正在尝试使用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')]