解决监督学习文本分类中的同义词

时间:2016-10-07 05:19:01

标签: machine-learning scikit-learn text-classification supervised-learning

我正在使用scikit-learn监督学习方法进行文本分类。我有一个训练数据集,其中包含输入文本字段及其所属的类别。我使用tf-idf,SVM分类器管道来创建模型。该解决方案适用于正常的测试用例。但是如果输入的新文本与训练集中具有synoynmous单词,则解决方案无法正确分类。 例如:单词' run'可能会出现在训练数据中,但如果我使用“短跑”这个词。为了测试,该解决方案无法正确分类。

这里最好的方法是什么?为训练数据集中的所有单词添加所有同义词并不像我的可扩展方法

1 个答案:

答案 0 :(得分:5)

您应该查看单词向量和密集文档嵌入。现在你正在通过scikit-learn一个矩阵X,其中每一行都是数据集中文档的数字表示。您正在使用tf-idf获得此表示,但是您注意到这并没有捕获单词相似性,并且您也遇到了词汇单词的问题。

一种可能的改进是用一个密集的矢量来表示每个单词,比如尺寸300,这样在这个300维空间中具有相似含义的单词就近了。幸运的是,您不需要从头开始构建这些向量(查找gensim word2vec和spacy)。另一个好处是,通过使用在维基百科等大型语料库中预先训练的单词嵌入,您将大量有关世界的语言信息合并到您的算法中,否则您无法从语料库中推断出(就像sprint这样的事实并且运行是同义词)。

一旦你获得了单词的良好和语义数字表示,你需要获得每个文档的向量表示。最简单的方法是平均句子中每个单词的单词向量。

让你开始的伪代码示例:

>>> import spacy

>>> nlp = spacy.load('en')
>>> doc1 = nlp('I had a good run')
>>> doc1.vector
array([  6.17495403e-02,   2.07064897e-02,  -1.56451517e-03,
         1.02607915e-02,  -1.30429687e-02,   1.60102192e-02, ...

现在让我们尝试一下不同的文档:

>>> doc2 = nlp('I had a great sprint')
>>> doc2.vector
array([ 0.02453461, -0.00261007,  0.01455955, -0.01595449, -0.01795897,
   -0.02184369, -0.01654281,  0.01735667,  0.00054854, ...

>>> doc2.similarity(doc1)
0.8820845113100807

注意向量是如何相似的(在余弦相似性意义上),即使单词不同。因为向量是相似的,所以scikit-learn分类器将学习将它们分配到相同的类别。使用tf-idf表示时,情况并非如此。

这是你在scikit-learn中使用这些载体的方法:

X = [nlp(text).vector for text in corpus]
clf.fit(X, y)