作为我的python入门的一个小实验之一,我早在六月份的时候就进行了md笔记的编写,没有发布在博客上,这次,它将作为我在博客的第一篇。

我们知道,生活中的一些文本是嘈杂的,它可能含有很多的噪声数据,所以我们需要对其进行数据清洗处理,拿到我们想要的数据,词频统计就是其中一个获取文本价值信息的一种方式。

在学习了Python的字典和文件处理后,我们就可以对这个例子进行一个具体的实现了。

我将写入两个例子对其进行展示,因为搬运的是我初学时的笔记,所以如有错误请评论指正~

一、Hamlet词频统计

https://python123.io/resources/pye/hamlet.txt

以上为hamlet英文版文本的获取路径,下载完成后保存到工程路径下。

二、数据预处理

像以上提到的,我们的文本中含有标点和字符的噪声数据,所以要进行数据的清洗,将文档全部处理为只有我们需要的字母类型(为方便操作,用空格替换噪声数据,将文档全部转化为小写字母)

打开文件,进行读取,清洗数据,数据归档。

定义为函数处理

def getText():
    txt = open("hamlet.txt","r").read()
    txt = txt.lower()
    for ch in '!@#$%^&*()_/*-~':
        txt = txt.replace(ch," ")
    return txt

三、数值统计

因为这里我们要找出出现次数最多的词组,所以要进行存储比较它们的出现次数,这里显然是一种映射的关系,所以我们采取字典的方式对数据进行存储。

具体使用到字典的get函数实现

hamlet = getText()
words = hamlet.split()
counts = {}
for word in words:
    counts[word] = counts.get(word,0) + 1

四、转换处理

到这一步,我们就将所有在文档中出现的词组和其对应个数存入字典counts中了,因为字典是无序的,所以我们采取对其进行转化列表,利用列表的有序性进行排序。

sort函数中,reverse默认为False(从小到大),这里我们将值设为True(从大到小)排序。这样就会生成一个我们需要的序列了。

items = list(counts.items())
items.sort(key= lambda x:x[1],reverse=True)
for i in range(10):
    word, count = items[i]
    print("{0:<10}{1:>5}".format(word,count))

输出结果:

四、三国演义人物出场频数

明白了上面的操作,我们也很容易的对中文文本进行操作了

利用jieba库,进行中文分词,将其存入列表words中,遍历,将词组和词频作为键值对存入列表counts中,利用列表的有序性,进行排序,然后输出

https://python123.io/resources/pye/threekingdoms.txt

以上为三国演义中文版文本获取链接,下载后保存到工程路径下

利用jieba库,

import jieba
txt = open("threekingdoms.txt","r",encoding="utf-8").read()
counts = {}
words = jieba.lcut(txt)
for word in words:
    if len(word) == 1:
        continue
    else:
        counts[word] = counts.get(word,0) + 1
items = list(counts.items())
items.sort(key = lambda x:x[1] , reverse=True)
for i in range(15):
    word , count = items[i]
    print("{0:<10}{1:>5}".format(word,count))

该实验较于哈姆雷特版简单,不用去处理字符类噪声数据,这也得益于jieba库的简易操作。

但随之带来的是词频的模糊,因为jieba库的特性,导致不是人名的词组也被统计了进来。

如结果中的“二人”、”孔明曰“,这些都是冗余和词组问题的错误。

所以我们应该还需要进行进一步的处理,让词频统计人物的名字次数

经过前几步的操作,我们输出了出现频率最高的15给词组,可我们如果想要人物的出场频率呢? 这就需要对原文件进行过滤,把我们不需要的输出删除。

因为之前的输出可以简单的获取到出现频率高但不是人名的词组,所以我们这里把它们储存到一个集合中,遍历并删除原文件中存在的这些词组。

excludes = {"将军","却说","二人","不可","荆州","不能","如此","商议","如何","主公","军士","左右","军马"}
for i in excludes:
    del counts[i]

冗余处理:把出现频率高的相同人物别名进行统一

  elif word == "诸葛亮" or word == "孔明曰":
        rword = "孔明"
    elif word == "关公" or word == "云长":
        rword = "关羽"
    elif word == "玄德" or word == "玄德曰":
        rword = "刘备"
    elif word == "孟德" or word ==  "丞相":
        rword = "曹操"

 反复的经过这些处理,我们可以得到我们想要的输出

import jieba
txt = open("threekingdoms.txt","r",encoding="utf-8").read()
counts = {}
excludes = {"将军","却说","二人","不可","荆州","不能","如此","商议","如何","主公","军士","左右","军马"}
words = jieba.lcut(txt)
for word in words:
    if len(word) == 1:
        continue
    elif word == "诸葛亮" or word == "孔明曰":
        rword = "孔明"
    elif word == "关公" or word == "云长":
        rword = "关羽"
    elif word == "玄德" or word == "玄德曰":
        rword = "刘备"
    elif word == "孟德" or word ==  "丞相":
        rword = "曹操"
    else:
        rword = word
    counts[rword] = counts.get(rword,0) + 1
for i in excludes:
    del counts[i]
items = list(counts.items())
items.sort(key = lambda x:x[1] , reverse=True)
for i in range(7):
    word,count = items[i]
    print("{0:<10}{1:>5}".format(word,count))

 

以上就是我对三国演义中文文档的人物出场词频统计笔记。

至此,还可以对各类报告、报道等进行词频统计,以找出其重点内容。

以上为hamlet英文文档及三国演义人物出场词频统计的实现。

欢迎大家留言讨论~~

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐