python:如何在scikit learn分类器(SVM等)中使用词性特征
我想用nltk.pos_tag返回的词性(POS)来为sklearn分类器做准备,怎么把它们转换成向量并使用呢?
比如说:
句子 = "这是一个词性示例"
首先,我用nltk.tokenize.word_tokenize把句子分词:
分词结果 = nltk.tokenize.word_tokenize(句子)
接着,我用nltk.pos_tag给每个词标注词性:
词性标注 = nltk.pos_tag(分词结果)
打印出来的结果是:
[('这是', 'DT'), ('一个', 'VBZ'), ('词性', 'NNP'), ('示例', 'NN')]
现在我不知道怎么用scikit-learn里的向量化工具(比如DictVectorizer、FeatureHasher或CountVectorizer)来处理这些词性,以便在分类器中使用。
请给点建议。
4 个回答
我觉得一个更好的方法是:
第一步:为每个文本或句子创建词向量或句子向量。
第二步:计算词性标签。将词性标签作为第一步的输入给嵌入器。
第三步:将这两个向量逐元素相乘。(这样做是为了确保每个句子中的词向量会根据其对应的词性标签进行加权。)
谢谢
可以考虑把单词和它的标签合并成一个形式,比如 'word/tag',然后你可以把这个新的文本数据给一个向量化工具,这个工具会统计单词的出现频率(比如用TF-IDF或者词袋模型),然后为每个单词生成一个特征:
wpt = nltk.WordPunctTokenizer()
text = wpt.tokenize('Someone should have this ring to a volcano')
text_tagged = nltk.pos_tag(text)
new_text = []
for word in text_tagged:
new_text.append(word[0] + "/" + word[1])
doc = ' '.join(new_text)
这个过程的输出是
Someone/NN should/MD have/VB this/DT piece/NN of/IN shit/NN to/TO a/DT volcano/NN
我知道这个回答有点晚,但我还是想在这里补充一下。
根据你想要的功能,你需要以一种合理的方式来编码POST。我的经验是,当我把原句和POST句子结合在一起,形成一个新的句子时,使用n-grams进行SVM分类效果最好,像这样:
word1 word2 word3 ... wordn POST1 POST2 POST3... POSTn
完成这个步骤后,我会把它输入到一个标准的n-gram模型或者其他模型中,然后再输入到SVM里。
这种方法保留了单个单词的信息,同时也保留了POST模式的重要信息,这样当你给系统一些它之前没见过的单词时,系统仍然能利用之前遇到过的标签信息。
如果我理解得没错,这个问题有点复杂。一旦你给文本加上标签,你的句子(或文档,或者其他东西)就不再是由单词组成,而是由(单词 + 标签)这样的组合构成,这样就不太清楚怎么从中提取出最有用的数值向量。
大多数文本向量化工具的做法是统计每个词汇出现的次数,然后为每个词汇创建一个特征:
the: 4, player: 1, bats: 1, well: 2, today: 3,...
接下来的文档可能会有:
the: 0, quick:5, flying:3, bats:1, caught:1, bugs:2
只要你总是把相同的键放在相同的数组元素中,这些都可以存储为整数数组(大多数文档里会有很多零)——或者作为字典。所以一个向量化工具会对许多“文档”进行这样的处理,然后再进行后续操作。
所以你的问题归结起来就是,怎么把一对对的标签和单词转换成一个平坦的列表,方便向量化工具进行统计。
最简单的方法就是把你的数据扁平化成
('This', 'POS_DT', 'is', 'POS_VBZ', 'POS', 'POS_NNP', 'example', 'POS_NN')
这样的话,通常的统计就会得到一个包含8个词汇项的向量,每个词汇项出现一次。我把标签重命名,以确保它们不会和单词混淆。
这样做可以让你开始使用,但可能效果不大。这是因为仅仅知道每种词性在样本中出现的次数,可能无法告诉你你需要的信息——注意,一旦向量化工具进行统计,关于哪些词性和哪些单词相关的概念就消失了。
如果你试图区分某种风格,运行一个分类器可能会有一些价值——比如,小说可能会有更多的形容词,而实验报告可能会有更少的专有名词(也许是这样),等等。
相反,你可以把数据改成
('This_DT', 'is_VBZ', 'POS_NNP', 'example_NN')
这样可以保持每个标签和它对应的单词“绑定”在一起,因此现在向量能够区分“bat”作为动词和作为名词的样本。这会告诉你一些不同的信息——例如,“bat”作为动词在关于棒球的文本中出现的可能性比在关于动物园的文本中要高。
而且你可以做很多其他的排列。
要想在自然语言文本上使用向量方法获得好的结果,你可能需要认真思考(并进行测试)你希望向量化工具生成和使用哪些特征。这很大程度上取决于你最终想要实现的目标。
希望这能帮到你。