添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
python实现英文词频统计【记录】

python实现英文词频统计【记录】

前言

之前遇到一篇很长很长的文档,需要统计一下某一个人物或者某一些词出现的次数,这种情况人力自然是不行。但是可以利用 python 来解决这个问题。例如:我们可以利用 python 统计出《哈姆雷特》或者是《红楼梦》中人物出场的频率。

这篇文章特此用来记录一下,防止自己遗忘。

首先用《哈姆雷特》试一下:

第一步:下载《哈姆雷特》英文版 TXT 文件

第二步:开始编写代码

txt = open("hamlet.txt", "r").read() # 打开文件 r 读权限

1.对打开后的文件进行预处理

for ch in '# $ % & () * + , - . : ; < = > ? @ [\\] ^ {}':
    txt = txt.replace(ch, "") # 文中的特殊字符用空格代替

2.文本分词

txt = txt.lower() # 将所有的字母转化为小写
words = txt.split() # 什么都不填表示用空格来分隔

这是英文文本,单词之间本身就存在空格符,所以是不需要分词的。这一步应该算是文本预处理。但是中文文本词与词之间没有空格符,所以需要使用中文分词工具,例如如下的第三方库:jieba、pkuseg、pynlpir、thulac 等等。

3.词频统计

这就有一个问题,这些词我们预处理已经完成,但是它们应该去哪里呢?

所以我们需要一个存放词的容器——没错,就是字典。因为我们要统计的结果是词+它出现的次数,所以可以看作是字典中键与值之间的关系。

所以,先定义一个存放词的空字典:

counts = {}

然后我们需要把预处理过的词都放入空字典。然后计算就可以了。

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

这样我们就能计算出词出现的次数了,但是这样不够简洁,我们还可以这样写:

for word in words: 
    counts[word] = counts.get(word,0) +1

第二行中的 count[word]是把遍历到的词作为 key,后面的表达式,get 方法去查询 key 出现的次数,出现一次,就+1,如果没有,返回 0。这样,就可以了。

另外,词频统计会统计所有的词出现的次数,但是,我们有时候做分析或者是其他需要的结果中并不需要这么多的词,所以我们可以进一步完善一下代码。

excludes = {"the", "and", "of", "you", "a", "i", "my", "in"} 
for word in excludes: 
    del(counts[word])

这样,我们就把一些冠词、连接词、介词一些我们不太需要的词都排除掉。依然是利用 for 循环去遍历文件中的词,并用 del 方法删去它们。

【上面的排词库可以随着程序的运行一步一步添加词汇,以达到打印对自己有意义的结果的目的】

至此,其实单单是统计词频的工作已经做完了,但是,我们得拿到这个结果,所以,我们定义一个空列表来存储它们。

items = list(counts.items()) 
print(items)

打印出来的结果会是这样:[('tragedy', 3), ...],列表中包含的是字典中所有键值对形成的元组。

emm…但是这个结果依然有点不尽人意。原因是这个结果是把字典中的键值形成的元组,保存到列表里面去,但是字典是无序的,打印出来的结果就仅仅只是一个结果,我们无法统计那个词频率最高,那个最低,当然,数据少了还可以,如果数据一多,拥有庞大数据的列表我们就无从下手了,所以,我们得实现排序。

4.结果排序(这里要用到 sort()和 lambda 函数)

items.sort(key=lambda x: x[1], reverse=True)

这样,就实现了以词出现的次数为条件的降序排序。sort()方法便是以第一列为基准升序排序的。但是我们用 lambda 这个匿名函数就可以了让它以第二列为基准降序排序。

5.输出排序后的结果

因为结果很多,尤其是大文件,我们会得到一个信息量很大的结果,不过呢,我们可以根据自己的需要打印排名前 10 或者前 20 的结果。

for i in range(10): 
     word, count = items[i] 
     print("{0:<10}{1:>5}".format(word, count))

源代码:

txt = open("hamlet.txt", "r").read() # 打开文件 r 读权限 
for ch in '# $ % & () * + , - . : ; < = > ? @ [\\] ^ {}': 
      txt = txt.replace(ch, "") # 文中的特殊字符用空格代替 
txt = txt.lower() # 将所有的字母转化为小写 
words = txt.split() # 什么都不填表示用空格来分隔 
counts = {}
for word in words: 
      counts[word] = counts.get(word,0) +1