我们是否需要在POS标记之前使用停用词过滤?

时间:2016-10-20 02:32:44

标签: nlp text-mining pos-tagger

我是文本挖掘和NLP相关内容的新手。我正在开发一个小项目,我试图从一些文档中提取信息。我基本上做了一个pos标记然后使用chunker来找出基于标记词的模式。在进行此POS标记之前,我是否需要使用停用词?使用停用词会影响我的POS标记的准确性吗?

3 个答案:

答案 0 :(得分:4)

让我们使用this作为训练/测试标记器的示例:

首先获取语料库和停止列表

>>> import nltk
>>> nltk.download('stopwords')
>>> nltk.download('cess_esp')

将包装器加载到NLTK

>>> from nltk.corpus import cess_esp as cess
>>> from nltk.corpus import stopwords

# Import the function to train a tagger.
>>> from nltk import UnigramTagger, BigramTagger
# Load the Spanish stopwords
>>> stoplist = stopwords.words('spanish')
# Load the Spanish tagger
>>> cess_sents = cess.tagged_sents()

将语料库拆分为训练/测试集

>>> len(cess_sents)
6030
>>> test_set = cess_sents[-int(6030/10):]
>>> train_set = cess_sents[:-int(6030/10)]
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(10)[-2:]
[8, 9]
>>> range(10)[:-2]
[0, 1, 2, 3, 4, 5, 6, 7]

创建一个没有停用词的备用train_set。

>>> train_set_nostop = [[(word,tag) for word, tag in sent if word.lower() not in stoplist] for sent in train_set]

看到区别:

>>> train_set[0]
[(u'El', u'da0ms0'), (u'grupo', u'ncms000'), (u'estatal', u'aq0cs0'), (u'Electricit\xe9_de_France', u'np00000'), (u'-Fpa-', u'Fpa'), (u'EDF', u'np00000'), (u'-Fpt-', u'Fpt'), (u'anunci\xf3', u'vmis3s0'), (u'hoy', u'rg'), (u',', u'Fc'), (u'jueves', u'W'), (u',', u'Fc'), (u'la', u'da0fs0'), (u'compra', u'ncfs000'), (u'del', u'spcms'), (u'51_por_ciento', u'Zp'), (u'de', u'sps00'), (u'la', u'da0fs0'), (u'empresa', u'ncfs000'), (u'mexicana', u'aq0fs0'), (u'Electricidad_\xc1guila_de_Altamira', u'np00000'), (u'-Fpa-', u'Fpa'), (u'EAA', u'np00000'), (u'-Fpt-', u'Fpt'), (u',', u'Fc'), (u'creada', u'aq0fsp'), (u'por', u'sps00'), (u'el', u'da0ms0'), (u'japon\xe9s', u'aq0ms0'), (u'Mitsubishi_Corporation', u'np00000'), (u'para', u'sps00'), (u'poner_en_marcha', u'vmn0000'), (u'una', u'di0fs0'), (u'central', u'ncfs000'), (u'de', u'sps00'), (u'gas', u'ncms000'), (u'de', u'sps00'), (u'495', u'Z'), (u'megavatios', u'ncmp000'), (u'.', u'Fp')]
>>> train_set_nostop[0]
[(u'grupo', u'ncms000'), (u'estatal', u'aq0cs0'), (u'Electricit\xe9_de_France', u'np00000'), (u'-Fpa-', u'Fpa'), (u'EDF', u'np00000'), (u'-Fpt-', u'Fpt'), (u'anunci\xf3', u'vmis3s0'), (u'hoy', u'rg'), (u',', u'Fc'), (u'jueves', u'W'), (u',', u'Fc'), (u'compra', u'ncfs000'), (u'51_por_ciento', u'Zp'), (u'empresa', u'ncfs000'), (u'mexicana', u'aq0fs0'), (u'Electricidad_\xc1guila_de_Altamira', u'np00000'), (u'-Fpa-', u'Fpa'), (u'EAA', u'np00000'), (u'-Fpt-', u'Fpt'), (u',', u'Fc'), (u'creada', u'aq0fsp'), (u'japon\xe9s', u'aq0ms0'), (u'Mitsubishi_Corporation', u'np00000'), (u'poner_en_marcha', u'vmn0000'), (u'central', u'ncfs000'), (u'gas', u'ncms000'), (u'495', u'Z'), (u'megavatios', u'ncmp000'), (u'.', u'Fp')]
>>>

训练一个标记器:

>>> uni_tag = UnigramTagger(train_set)

使用没有停用词的语料库训练标记器:

>>> uni_tag_nostop = UnigramTagger(train_set_nostop)

将test_set拆分为单词和标签:

>>> test_words, test_tags = zip(*[zip(*sent) for sent in test_set])

标记测试句子:

>>> uni_tag.tag_sents(test_words)
>>> uni_tag_nostop.tag_sents(test_words)

评估准确性(现在让我们做正面的事实):

>>> sum([ sum(1 for (word,pred_tag), (word, gold_tag) in zip(pred,gold) if pred_tag==gold_tag) for pred, gold in zip(tagged_sents, test_set)])
11266
>>> sum([ sum(1 for (word,pred_tag), (word, gold_tag) in zip(pred,gold) if pred_tag==gold_tag) for pred, gold in zip(tagged_sents_nostop, test_set)])
5963

请注意,在训练标记器之前删除停用词时,有许多不公平的事情,而不是详尽无遗:

  • 你的训练组自然会变小。删除停用词后,句子中的单词会更小

  • 标记器不会学习停用词的标签,因此会为所有停用词返回“无”,从而降低了标记器的准确性,因为测试集包含停用词

  • 当训练一个更高阶的ngram,没有停用词时,它根本没有任何意义。并不是语法或敏感性就是准确性(特别是今天的NLP)。对于例如,"猫在桌子上" - > "猫咪桌"没有停用词。

但正如@alexia指出的那样,对于基于词袋的矢量空间模型(也称为分布式模型,又名。"你可以通过它的邻居知道一个单词" model,aka。non神经预测嵌入模型),删除停用词可能会给你带来一些准确性的里程。但至于TF-IDF,(统计上)神奇的事情是,停用词将自动具有较低的TF-IDF分数,因为它们在大多数文档中显得过于频繁,并且不会使它们具有较少的歧视性属性。使每个文件都不同(因此它们并不那么重要,它是那些正在做魔术的IDF部分。)

答案 1 :(得分:1)

@lenz说的话。不要在标记之前或之前删除停用词,除非正在训练一个chunker并且你决定在清理过的文本上训练它(然后使用它)。但我也不建议这样做。对于像TF-IDF这样的词语过程,删除词是适当的,但是像确定词和介词这样的常用词提供了关于句子结构的重要线索,因此也提供了词性。如果要检测句子单位,请不要删除它们。

但为什么要相信我的话呢?您可以通过获取一些标记数据并使用和不使用停用词删除来评估您的标记器和块,轻松地自行检查。无论如何,我建议你为其余的管道做这件事。

答案 2 :(得分:0)

我建议您在删除停用词之前使用POS标记器,因为POS标记是作为序列分类执行的,因此通过删除停用词来更改序列很可能会影响其余词的POS标签。