我有一个字符串列表,都是动词。我需要得到每个动词的单词频率,但我想把动词如“想要”,“想要”,“想要”和“想要”作为一个动词。形式上,“动词”被定义为一组4个单词,其形式为{X,Xs,Xed,Xing}或形式为{Xe,Xes,Xed,Xing}。我如何从列表中提取动词,以便得到“X”并计算词干出现的次数?我想我可以以某种方式使用正则表达式,但我是一个正则表达式n00b,我完全迷失了
答案 0 :(得分: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
你可以将它与defaultdict
一起使用来做这样的事情(注意:在Python 2.7+中,Counter
同样有用/更好):
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})
然而,希望它会让你接近你想要的。
答案 1 :(得分: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可能是最好的。可以在循环counts = {}
之前创建一个dict。然后,要为每个单词递增,您可以在每次迭代结束时执行以下操作:
if base in counts:
counts[base] += 1
else:
counts[base] = 1
RocketDonkey在我打字的时候打败了我的答案,他的答案看起来会更好,但我还是在发帖,因为这不需要安装额外的库,如果这对你有价值的话。