2

我有一个字符串列表,这些字符串都是动词。我需要获取每个动词的词频,但我想将“want”、“wants”、“wanting”和“wanted”等动词计为一个动词。形式上,“动词”被定义为一组 4 个单词,其形式为 {X, Xs, Xed, Xing} 或形式为 {X, Xes, Xed, Xing},其中 X 是动词。我将如何从列表中提取动词,以便得到“X”并计算词干出现的次数?我想我可以以某种方式使用正则表达式,但是我是正则表达式的新手,我完全迷路了。

4

2 回答 2

7

有一个名为nltk的库,它具有一系列用于文本处理的疯狂函数。函数的子集之一是stemmers,它只做你想做的事(使用在该领域有丰富经验的人开发的算法/代码)。下面是使用Porter Stemming算法的结果:

In [3]: import nltk

In [4]: verbs = ["want", "wants", "wanting", "wanted"]

In [5]: for verb in verbs:
   ...:     print nltk.stem.porter.PorterStemmer().stem_word(verb)
   ...:     
want
want
want
want

您可以将它与 a 结合使用defaultdict来执行类似的操作(注意:在 Python 2.7+ 中, aCounter将同样有用/更好):

In [2]: from collections import defaultdict

In [3]: from nltk.stem.porter import PorterStemmer

In [4]: verbs = ["want", "wants", "wanting", "wanted", "running", "runs", "run"]

In [5]: freq = defaultdict(int)

In [6]: for verb in verbs:
   ...:     freq[PorterStemmer().stem_word(verb)] += 1
   ...:     

In [7]: freq
Out[7]: defaultdict(<type 'int'>, {'run': 3, 'want': 4})

需要注意的一件事:词干分析器并不完美 - 例如,添加ran到上面会产生以下结果:

defaultdict(<type 'int'>, {'ran': 1, 'run': 3, 'want': 4})

但是希望它能让你接近你想要的。

于 2013-01-23T04:36:37.453 回答
2

要完全通过模式匹配获取基本词,您可以使用以下代码:

import re

for word in verblist:
    mtch = re.match(r"([a-zA-Z]*)((ed)|(ing)|(s))", word)
    if mtch:
        base = mtch.group(1)
    else:
        base = word
    #process the base word here

请记住,这不能很好地处理不规则动词,并且它依赖于仅包含动词的列表。现在,要实际跟踪计数,dict 可能是最好的。可以在循环之前创建一个 dict counts = {}。然后,要为每个单词递增,您可以在每次迭代结束时执行以下操作:

    if base in counts:
        counts[base] += 1
    else:
        counts[base] = 1

RocketDonkey 在我打字的时候打败了我,他的回答看起来会更好,但我还是发布了,因为这不需要安装额外的库,如果这对你有价值的话。

于 2013-01-23T04:52:31.860 回答