用Python统计瓦尔登湖的词频

系统 1746 0

在文本处理中,我们经常需要对文本中的单词出现频率做一个统计,本文以英文小说《瓦尔登湖》为例,统计一下作者最喜欢用什么单词,他们各自的出现频率如何。

首先需要《瓦尔登湖》的文本:点击下载《瓦尔登湖》(https://pan.baidu.com/s/1o75GKZ4)


思路分析:

  1. 首先,要打开文件,把里面的内容写到字符串里面。
  2. 接着,要对字符串进行分词,分割成独立的单词。
  3. 最后,根据每个单词进行词频统计。

把下载好的“Walden.txt”放到桌面,复制一下完整的路径名,特别注意:

Windows系统下,默认的文件名路径子级和父级之间可能是用反斜杠“ \ ”表示的,而在Python中,子级和父级之间用正斜杠“ / ”表示。

文件打开的时候,如果出现以下错误:

            
              UnicodeDecodeError: 'gbk' codec can't decode byte 0xbf in position 2: illegal multibyte sequence
            
          

说明文件编码格式异常,解决办法:在文件打开的语句中添加 encoding = ' utf-8 ',注意添加在open( )函数的最后。

            
              with open(path,'r') as text:
# 添加utf-8编码支持,原语句改为:
with open(path,'r',encoding='utf-8') as text:
            
          

使用stringlist.split()函数进行分词,使用stringlist.count()函数进行统计词频

代码如下:

            
              path = 'C:/Users/xiaokai/Desktop/Walden.txt'

with open(path,'r',encoding='utf-8') as text:    # 读入文本
    words = text.read().split()                  # 开始分词
    print(words)
    for word in words:
        print('{}--{} times'.format(word,words.count(word)))    # 把单词和词频分别打印出来
            
          

 运行结果

            
              tried.--1 times
Whatever--4 times
have--660 times
been--167 times
thy--23 times
failures--3 times
hitherto,--1 times
"be--1 times
            
          

分析问题:

发现输出有点怪异,出现了 “tried. ”,“hitherto,” 这样的单词,还有更多的问题:

  1. 单词前后跟了“,”,“.”,“?”等各种各样的符号。
  2. 有许多单词被重复统计了。
  3. 有一些单词,例如‘“Some”和“some”是同一个单词,但是因为“Some”首字母大写也被认为是两个单词。

因此作出更多的改进:

  1. 去掉首尾连在一起的字符串,并且全部转换成小写字母。
  2. 创建一个单词集合,集合的性质保证了不会出现重复的单词,确保不会出现重复统计单词的现象。
  3. 创建一个字典,key为文本里出现的单词,value为单词在文本中出现的频率。
  4. 在字典中,根据词频顺序打印键值对。

改进之后的代码如下:

            
              import string

with open(path,'r',encoding='utf-8') as text:

    # 1. 首先进行分词
    raw_words = text.read().split()

    # 2. 把每个单词首尾连在一起的符号去掉,大写字母统一成小写
    words_list = [word.strip(string.punctuation).lower() for word in raw_words]

    # 3. 数据结构转换成集合,这里重复的单词会被自动丢弃
    words_set = set(words_list)

    # 4. 创建字典键值对:key为单词,value为单词出现的频率
    # 冒号左边为单词,冒号右边为词频
    words_dict = {keyword:words_list.count(keyword) for keyword in words_set}

# 5. 根据words_dict中value的值对字典进行排序输出

# 这里采用了lambda表达式,lambda word: word[1]表示输入一个word词条,返回word[1](词频)
# word是一个词条,word[0]是单词,word[1]是单词出现的频率

for word in sorted(words_dict.items(), key = lambda word: word[1], reverse = True):
    print('{}--{} times'.format(word[0],word[1]))
            
          

代码解释:

  • strip()函数的作用是去除单词首尾的符号,其中string.punctuation就是一个字符集,包含!@#¥%&*等符号,使用strip(string.punctuation)可以去除首尾的这些符号。
  • word.lower()函数把字母全部转换成小写。
  • sorted()函数对字典进行排序,默认对key进行排序,但这里对value进行排序,所以这里使用lambda表达式,在key = lambda word: word[1]中,返回值是word[1],也就是words_dict中的value。

参考博客:

Python strip()方法 | 菜鸟教程
http://www.runoob.com/python/att-string-strip.html

python字典按照value进行排序 - ketchup_酱 - 博客园
https://www.cnblogs.com/timtike/p/6562402.html


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论