本节书摘来异步社区《NLTK基础教程——用NLTK和Python库构建机器学习应用》一书中的第2章,第2.5节,作者:Nitin Hardeniya,更多章节内容可以访问云栖社区“异步社区”公众号查看。
2.5 词干提取
所谓词干提取(stemming),顾名思义就是一个修剪枝叶的过程。这是很有效的方法,通过运用一些基本规则,我们可以在修剪枝叶的过程中得到所有的分词。词干提取是一种较为粗糙的规则处理过程,我们希望用它来取得相关分词的各种变化。例如eat这个单词就会有像eating、eaten、eats等变化。在某些应用中,我们是没有必要区分eat和eaten之间的区别的,所以通常会用词干提取的方式将这种语法上的变化归结为相同的词根。由此可以看出,我们之所以会用词干提取方法,就是因为它的简单,而对于更复杂的语言案例或更复杂的NLP任务,我们就必须要改用词形还原(lemmatization)的方法了。词形还原是一种更为健全、也更有条理的方法,以便用于应对相关词根的各种语法上的变化。
下面,我们就来看一段词干提取的具体过程:
>>>from nltk.stem import PorterStemmer # import Porter stemmer
>>>from nltk.stem.lancaster import LancasterStemmer
>>>from nltk.stem.Snowball import SnowballStemmer
>>>pst = PorterStemmer() # create obj of the PorterStemmer
>>>lst = LancasterStemmer() # create obj of LancasterStemmer
>>>lst.stem("eating")
eat
>>>pst.stem("shopping")
shop
一个拥有基本规则的词干提取器,在像移除-s/es、-ing或-ed这类事情上都可以达到70%以上的精确度,而Porter词干提取器使用了更多的规则,自然在执行上会得到很不错的精确度。
我们创建了不同的词干提取器对象,并在相关字符串上调用了 stem()方法。结果如你所见,当用一个简单实例来查看时,它们之间并没有太大的差别,但当多种词干提取算法介入时,就会看到它们在精准度和性能上的差异了。关于这方面的更多细节,你可以去看看 http://www.nltk. org/api/nltk.stem.html
页面上的相关信息。通常情况下,我们使用的是Porter词干提取器,如果是在英语环境中工作,这个提取器已经够用了。当然,还有Snowball提取器这一整个提取器家族,可分别用于处理荷兰语、英语、法语、德语、意大利语、葡萄牙语、罗马尼亚语和俄语等语言。特别地,我也曾经遇到过可用来处理印地文的轻量级词干提取器:http://research.variancia.com/hindi_stemmer
。
注意 小技巧:
我们会建议那些希望对词干提取进行更深入研究的人去看看关于所有词干提取器的相关研究http://en.wikipedia. org/wiki/Stemming[2]
。
但是,对大多数用户而言,Porter和Snowball这两种词干提取器就足以应付大量的相关用例了。在现代的NLP应用中,人们有时候会将词干提取当作是一种预处理步骤从而将其忽略掉,因此这往往取决于我们所面对的具体领域和应用。在这里,我们想告诉你一个事实,即如果你希望用到某些NLP标注器,如词性标注(POS)、NER或某种依赖性解析器中的某些部分,那么就应该避免进行词干提取操作,因为词干提取会对相关分词进行修改,这有可能会导致不同的结果。
当讨论到一般标注器时,我们还会进一步对此展开讨论。