对于一篇待研究的文章,我们想要获取出最能反映文章主题和风格的单词,单纯的看高频词并不能解决问题,因为一篇文章中频率最高的用词往往是“管道”单词:
import nltk
fdist1 = FreqDist(text1)
fdist1.most_common(50)
选择满足一定粒度和出现次数的单词,这里的粒度指的是单词长度,可以看到,稍微有那么点意思了:
fdist1 = FreqDist(text1)
sorted(w for w in set(text1) if len(w)>7 and fdist1[w]> 7)
当仅考虑单词难以反映文章主旨和风格时,可以从文章的用词搭配着手,而搭配可以理解为频繁出现的双连词,注意《python自然语言处理》书上有一个翻译错误:“搭配是不经常一起出现的词序列”,原文是“A collocation is a sequence of words that occur together unusually often.”,强调的是一起出现的频率异乎寻常。搭配中的单词不能被类似的词置换。例如:当我们表示红酒时,red wine是正确的搭配,而maroon wine则不是,即便它的字面意思也是红色的酒。
计算连词的函数为bigrams是binary+grams的缩写,类似的组合词还要后面用的非常多的ngrams模型。
>>> list(bigrams(['more', 'is', 'said', 'than', 'done']))
[('more', 'is'), ('is', 'said'), ('said', 'than'), ('than', 'done')]
可以使用bigrams+频率统计的方式获取到“搭配”,更方便的是使用 nltk 提供的collocation_list()函数(这里文档上用的是collocations(),但是实际让代码运行时,collocations函数会报错,具体原因我暂时还没有找到):
text1.collocation_list()
还可以站在词长的角度看文章,可以看到,text1中词长为3的单词最多
>>> fdist = FreqDist(len(w) for w in text1)
>>> fdist
FreqDist({3: 50223, 1: 47933, 4: 42345, 2: 38513, 5: 26597, 6: 17111, 7: 14399,
8: 9966, 9: 6428, 10: 3528, ...})
最后附上的是用于频率统计和单词比较的两个表:
NLTK 频率分布类中定义的函数
示例 | 描述 |
fdist = FreqDist(samples) | 创建包含给定样本的频率分布 |
fdist[sample] += 1 | 增加样本的数目 |
fdist['monstrous'] | 计数给定样本出现的次数 |
fdist.freq('monstrous') | 给定样本的频率 |
fdist.N() | 样本总数 |
fdist.most_common(n) | 最常见的n 个样本和它们的频率 |
for sample in fdist: | 遍历样本 |
fdist.max() | 数值最大的样本 |
fdist.tabulate() | 绘制频率分布表 |
fdist.plot() | 绘制频率分布图 |
fdist.plot(cumulative=True) | 绘制累积频率分布图 |
fdist1 |= fdist2 | 使用fdist2 更新fdist1 中的数目 |
fdist1 < fdist2 | 测试样本在fdist1 中出现的频率是否小于fdist2 |
一些词比较运算符
函数 | 含义 |
s.startswith(t) | 测试s是否以t 开头 |
s.endswith(t) | 测试s是否以t 结尾 |
t in s | 测试t是否是s的子串 |
s.islower() | 测试s中所有字符是否包含大小有区别的字符,且都是小写 |
s.isupper() | 测试s中所有字符是否包含大小有区别的字符,且都是大写 |
s.isalpha() | 测试s是否非空,且s中的所有字符是字母 |
s.isalnum() | 测试s是否非空,且s中的所有字符是字母或数字 |
s.isdigit() | 测试s是否非空,且s 中的所有字符都是数字 |
s.istitle() | 测试s是否包含大小有区别的字符,且首字母大写(即,s中所有的词都首字母大写) |