在Python中修复NLTK词根的异常情况

顾名思义,词根化是将单词还原为其词根形式的方法。例如,像happiness,happily, 和happier 这样的词都可以分解为词根happy

在Python中,我们可以在Python的NLTK 库提供的各种模块的帮助下做到这一点,但有时,你可能得不到你预期的结果。例如,fairly 被还原为fairli ,而不是fair NLTK 库的PorterStemmer 模块。

这篇文章将讨论为什么会出现这样的差异,以及如何修复它们以获得我们想要的词根。因此,请拿起咖啡,继续阅读!

修复Python中的NLTK 词根异常现象

尽管Python的NLTK 库有几个干系人,但最常用的是PorterStemmer 。下面是一个关于PorterStemmer 的工作原理的例子。

让我们先了解一下这段代码中发生了什么。

我们首先从nltk 库中导入PorterStemmer ,然后创建一个实例。现在,我们可以使用这个实例,在nltk 库中提供的stem() 函数的帮助下,对给定的单词列表进行词干处理。

from nltk.stem import PorterStemmer
p = PorterStemmer()
similar_words = ['act', 'acting', 'acts']
for x in similar_words:
    print(x, "comes from", p.stem(x))

输出:

act comes from act
acting comes from act
acts comes from act

PorterStemmer 模块的帮助下,这个列表上的所有单词都被还原为根词act 。但这并不是这个模块一直以来的工作方式。

下面是另一个例子。

from nltk.stem import PorterStemmer
p = PorterStemmer()
print(p.stem('loudly'))

输出:

'loudli'

你可以看到,这次我们得到的输出是loudli ,而不是loud

不知道为什么会发生这种情况。而且,更重要的是,如何解决这个问题?

修复Python中NLTKPorterStemmer 模块中的词根反常现象

PorterStemmer 模块分五个阶段工作,每个阶段都有自己的规则和程序。此外,它通常给出的结果是基于英语的。

这意味着,即使loudi 这个词不是我们想要的,但按照PorterStemmer 模块的规则,它是正确的词干。

但也有一些好消息–并非所有NLTK 模块的干系人都有类似的工作。这次让我们在SnowballStemmer 的帮助下对loudly 这个词进行干化。

请注意,在这里,我们必须将一种语言作为参数传递给SnowballStemmer() 函数。

from nltk.stem import SnowballStemmer
s = SnowballStemmer('english')
print(s.stem('loudly'))

输出:

'loud'

你可以看到,这次我们得到了所需的输出,因为SnowballStemmer 肯定使用了一套与PorterStemmer 不同的规则。 现在,这里有一些有趣的东西。

试着用这两个模块对actor 这个词进行词干处理。下面就是这样做的。

from nltk.stem import PorterStemmer
p = PorterStemmer()
print(p.stem('actor'))
from nltk.stem import SnowballStemmer
s = SnowballStemmer('english')
print(s.stem('actor'))

输出结果:

'actor'
'actor'

你可以看到,这两个模块都返回相同的输出,actor ,而不是词根act 。现在让我们用另一个名为LancasterStemmer 的词干模块试试。

from nltk.stem import LancasterStemmer
l = LancasterStemmer()
print(l.stem('actor'))

输出:

'act'

你可以看到,这次我们得到了想要的输出act

你看到了不同的干系人对不同的字给出了不同的输出。

我们可以使用其他各种干系人,但由于他们都是基于一些算法,所以总是有机会得不到所需的输出。此外,这些干系人在根据算法砍掉单词方面非常严格。

此外,干化的工作主要是在后缀部分,并没有聪明到通过去除前缀或下缀来解决单词。干化算法甚至不查单词的含义和产生的词根。

请看这个例子。

这里是一串随机的字母,末尾有一个ing ,干系人删除了这个后缀并返回输出。

from nltk.stem import PorterStemmer
p = PorterStemmer()
print(p.stem('wkhfksafking'))

输出:

'wkhfksafk'

因此要解决这个问题,更好的方法是使用词法分析器。让我们详细了解一下词法分析器的工作。

在Python中使用词法分析器而不是词根分析器NLTK

与干系人不同,词法分析器可以对单词进行形态分析,并根据它们的使用环境找到最合适的词法。请注意,词法与词干不同,因为它是其所有形式的基本形式,与词干不同。

让我们看一个例子,看看词法分析器如何比词干分析器更好。

在这里,我们使用PorterStemmer ,对几个词进行干化。

from nltk.stem import PorterStemmer
p = PorterStemmer()
w = ['studies', 'studying', 'study']
for i in w:
    print(p.stem(i))

输出:

studi
studi
studi

你可以看到我们得到的输出不是很有帮助。让我们继续在同一组词上使用一个词法分析器。

我们首先导入WordNetLemmatizer 模块并创建一个实例。然后,我们使用lemmatize() 函数和一个for 循环来找出每个词的词法。

from nltk.stem import WordNetLemmatizer
l = WordNetLemmatizer()
w = ['studies', 'studying', 'study']
for i in w:
    print(l.lemmatize(i))

输出:

study
studying
study

这次我们没有得到荒谬的输出,而且所有的词都有意义。

这就是使用词法分析器比使用词干分析器好的地方。

请参考这个链接,了解更多关于干系人和词法分析器的信息。

总结

这篇文章让我们了解了Python中的干系人和词法分析器NLTK 。我们看到了干系人如何以及为什么有时会给出荒谬的结果,以及我们如何使用词法分析器来获得更好的结果。