使用python统计《三国演义》人物词频,看看罗贯中笔下谁的出场次数最多

“滚滚长江东逝水,浪花淘尽英雄”。近来读《三国演义》,忽然想看看到底哪位英雄在书中提到的最多,于是就想用分词算法实现一下。
网上也确实有相关的案例,作为参考,自己又重写并优化了一遍。

思路

  • 下载《三国演义》txt文档
  • 使用jieba分词算法对文档进行分词处理
  • 将分词结果踢除停用词、标点符合、非人名等
  • 词频统计、并排序
  • 可视化展示

问题

按照上面的思路进行简单实施时,查看结果会发现几个问题

  • 名字
    • 三国人物有名、字、号等,还有其他的一些别称,如“相父”“曹阿瞒“刘皇叔”,要想办法统一成一个人
  • 词性
    • 比如“曰”、“大胜”等非人名的词不是我们需要统计的
  • 分词
    • 一些如“孔明曰”、“玄德问”、“操大怒”之类的词没有被分割开
  • 干扰词
    • 分词后会出现像“诸公”、“齐声”、“班师回”等明显,但是算法无法判断的非人名词语,干扰排序结果

所以对这些情况要进行特殊处理。
在这里插入图片描述

优化

  • 针对名、字、号的问题进行枚举判断。网上的案例中大多采用如 w.word == '玄德' 这种等号判断,但对于 “玄德遂”、“操乃”等分词不准确情况枚举不足。比如我们在文本里统计“操”字有2800多个,基本都是指代曹操,而用阿瞒、孟德、曹丞相等枚举等号判断时,最终统计的“曹操”词频只有1000多个,所以我采用的是包含判断,即 '操' in w.word'孟德' in w.word
  • 词性踢除。通过w.flag将nr(人名)外的其他词性踢除掉,这一步很多案例中是放在人物名字号的判断前,但是“玄德”会被当成x(未知词性),这样就会少算很多姓名,所以我放在了人物名字判断后,再踢除无关词性。
  • 对于词性为nr但是非人名的词,则需要在停用词的基础上,增加一张踢除干扰词的自定义文件
    在这里插入图片描述

结果

经过以上处理后,基本排除了干扰,最后就是激动人心的时刻,那么谁才是罗贯中心中的南波万呢?
当当当当,那就是这位“可爱的奸雄”——曹操。

曹操:3014
刘备:2689
诸葛亮:2103
关羽:1047
吕布:868
周瑜:660
司马懿:643
袁绍:544
张飞:505
鲁肃:465
赵子龙:433
马超:358
孙权:351
董卓:342
魏延:322
姜维:302
黄忠:190
刘表:156
庞德:122
张辽:117

三国人物出场词频

再来一张拉风的三国词云
三国人物词云
说明:该处理结果只对排名靠前的刘备、诸葛亮、曹操、关羽、张飞、吕布、司马懿等人物的分词结果进行了优化(见代码),其他诸如魏延、庞统、庞德等不影响第一排名的人物,名、字、号问题未进行详细处理。

附代码

import jieba.posseg as pseg
import jieba
import re
import matplotlib.pyplot as plt
import codecs

# 词云
import wordcloud
import imageio



# 定义主要人物的个数
keshihuaTop=10  # 可视化人物图人数
mainTop = 100  # 人物词云图人物数
peopleTop=10  # 人物关系图

# 获取图书数据
def get_book(file_path):
    fn = open(file_path,encoding='utf-8')
    stringdata =  fn.read()
    fn.close()
    return stringdata

# 文本处理
def bookdata_process(bookdata):
    pattern = re.compile(u'\t|\n|\.|-|:|;|\)|\(|\?|"')
    book_str = re.sub(pattern,'',bookdata)
    print('文本预处理完成')
    return book_str

# 获取停用词
def stop_word_list(file_path):
    stopwords = [line.strip() for line in open(file_path,'r',encoding='utf-8').readlines()]
    return stopwords

# 获取词频
count = {
   }
# 获取词频
def get
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值