数据分析案例-文本挖掘与中文文本的统计分析

article/2025/10/5 7:54:21

 

🤵‍♂️ 个人主页:@艾派森的个人主页

✍🏻作者简介:Python学习者
🐋 希望大家多多支持,我们一起进步!😄
如果文章对你有帮助的话,
欢迎评论 💬点赞👍🏻 收藏 📂加关注+


目录

项目背景介绍 

数据准备

项目流程

1.读取小说内容

2.统计词频

3.去除停用词

4.绘制词云图

5.章回处理


项目背景介绍 

        四大名著,又称四大小说,是汉语文学中不可多得的作品。这四部著作历久不衰,其中的故事、场景,已经深深地影响了国人的思想观念、价值取向。四部著作都有很高的艺术水平,细致的刻画和所蕴含的思想都为历代读者所称道。

        本次将以小说HLM为例,介绍中文文本的统计分析和文本发掘等方面的基本知识。

 数据准备

关于小说内容,读者可自行搜集。

项目流程

1.读取小说内容

# 获取HLM文本数据
with open('HLM.txt','r',encoding='utf-8')as f:text = f.read()

2.统计词频

import jieba# 分词并统计词频
def wordFreq(text,topn):words = jieba.lcut(text.strip()) # 对文本进行分词操作counts = {}for word in words:  # 统计每个词出现的频率,存放在字典counts中if len(word) == 1:  # 如果该词的长度为1,则跳过,不参与统计。continuecounts[word] = counts.get(word,0) + 1items = list(counts.items())items.sort(key=lambda x:x[1],reverse=True)  # 按照词频进行排序f = open('HLM_词频.txt','w',encoding='utf-8')for i in range(topn):  # topn表示要取的词的个数,将频率最高的topn个词及其频率数存放在文件中word,count = items[i]f.writelines("{}\t{}\n".format(word,count))f.close() wordFreq(text,20)  # 这里我们提取出频率最高的前20个词

 出现频率最高的词语是“宝玉”,出现了3772次,宝玉当仁不让的是《HLM》的一号主角。后面紧跟的高频词是“什么”,“一个”,这些也都是无意义的词语,需要我们进一步去除。

3.去除停用词

这里我们只需要加载停用词库,统计词频的时候加上判断即可。

# 分词并统计词频
def wordFreq(text,topn):words = jieba.lcut(text.strip()) # 对文本进行分词操作# 加载停用词库stopwords = [line.strip() for line in open('停用词库.txt','r',encoding='utf-8').readlines()]counts = {}for word in words:  # 统计每个词出现的频率,存放在字典counts中if len(word) == 1:  # 如果该词的长度为1,则跳过,不参与统计。continueelif word not in stopwords:  # 如果该词不在停用词列表stopwords中,才参与统计counts[word] = counts.get(word,0) + 1items = list(counts.items())items.sort(key=lambda x:x[1],reverse=True)  # 按照词频进行排序f = open('HLM_词频.txt','w',encoding='utf-8')for i in range(topn):  # topn表示要取的词的个数,将频率最高的topn个词及其频率数存放在文件中word,count = items[i]f.writelines("{}\t{}\n".format(word,count))f.close() 

 

 观察输出结果,不难发现“凤姐”和“凤姐儿”应该是一个人物,包括后面的“黛玉”和“林黛玉”,“林妹妹”也是一个人,“宝玉”以及“宝二爷”也应该一起统计

所以我们还需要处理小说中同一人物,不同称呼的情况。对上面的代码进行改进。

# 分词并统计词频
def wordFreq(text,topn):words = jieba.lcut(text.strip()) # 对文本进行分词操作# 加载停用词库stopwords = [line.strip() for line in open('停用词库.txt','r',encoding='utf-8').readlines()]counts = {}for word in words:  # 统计每个词出现的频率,存放在字典counts中if len(word) == 1:  # 如果该词的长度为1,则跳过,不参与统计。continueelif word not in stopwords:  # 如果该词不在停用词列表stopwords中,才参与统计if word == '凤姐儿':word = '凤姐'elif word == '林黛玉' or word == '林妹妹':word = '黛玉'elif word == '二爷':word = '宝玉'counts[word] = counts.get(word,0) + 1items = list(counts.items())items.sort(key=lambda x:x[1],reverse=True)  # 按照词频进行排序f = open('HLM_词频.txt','w',encoding='utf-8')for i in range(topn):  # topn表示要取的词的个数,将频率最高的topn个词及其频率数存放在文件中word,count = items[i]f.writelines("{}\t{}\n".format(word,count))f.close() 

4.绘制词云图

 这里我们调用获取词频函数,获取TOP500,最后绘制词云图

# 绘制词云
import matplotlib.pyplot as plt
import wordcloud
import imageio
wordFreq(text,500)  # 获取TOP500的词频
word_cloud_text = open('HLM_词频.txt','r',encoding='utf-8').read()
bg_pic = imageio.imread('star.jpg') # 读入形状图片
wc = wordcloud.WordCloud(font_path=r'C:\Windows\Fonts\simhei.ttf',background_color='white',width=1000,max_words=200,mask=bg_pic,  # mask参数设置词云形状height=860,margin=2).generate(word_cloud_text)
wc.to_file('HLMcloud_star.png')  # 保存图片

5.章回处理

导入Python中的正则表达式(re模块)通过正则匹配,找到文中所有“第**回”形式的字符。“\u4e00”和“\u9fa5”是unicode编码,并且正好是中文编码的开始和结束的两个值,所以这个正则表达式可以用来判断字符串中是否包含中文。

# 章回处理
import re
chapter = re.findall('第[\u4e00-\u9fa5]+回',text)
lst_chapter = []
for x in chapter:  # 去除重复的章节if x not in lst_chapter and len(x)<=5:lst_chapter.append(x)
print(lst_chapter)

 获取每一回起始和结束数据

lst_start_chapterIndex = []
for x in lst_chapter:  # 找出每一回在原文中的起始位置lst_start_chapterIndex.append(text.index(x))lst_end_chapterIndex = lst_start_chapterIndex[1:]+[len(text)]  # 找出每一回在原文中的结束位置,本回的结束位置就是下一回的起始位置。最后一回的结束位置就是全文的结束。zip将每一回的起始和结束位置拼成一个元组,存放在lst_chapterindex列表中。
lst_chapterIndex = list(zip(lst_start_chapterIndex,lst_end_chapterIndex))
print(lst_chapterIndex)

5.1HLM之“刘姥姥三进荣国府” 

统计在每一回中刘姥姥的出场次数并用折线图可视化。

# 统计刘姥姥出现的次数
cnt_liulaolao = []
for i in range(120):start = lst_chapterIndex[i][0]end = lst_chapterIndex[i][1]cnt_liulaolao.append(text[start:end].count('刘姥姥'))
plt.rcParams['font.sans-serif'] = ['SimHei'] #解决中文显示
plt.rcParams['axes.unicode_minus'] = False   #解决符号无法显示
plt.figure(figsize=(15,6))
plt.plot(range(120),cnt_liulaolao,label='刘姥姥出场次数')
plt.title('《HLM》——刘姥姥三进荣国府',fontdict={'fontsize':14})
plt.xlabel('章节数',fontdict={'fontsize':14})
plt.ylabel('出现次数',fontdict={'fontsize':14})
plt.legend()
plt.show()

5.2HLM之“哭说笑闹总关情”  

        我们尝试分析一下在小说的每一回里,“笑”和“喜”,“哭”与“悲”分别出现的次数,能不能通过这样一个小小的切入点,看一看贾府的兴衰与荣辱变化。统计每一回中“笑”和“喜”,“哭”与“悲”的出现次数。 并用折线图可视化。

# 统计情绪次数
cnt_laugh = []
cnt_cry = []
for i in range(120):start = lst_chapterIndex[i][0]end = lst_chapterIndex[i][1]cnt_laugh.append(text[start:end].count('笑')+text[start:end].count('喜'))cnt_cry.append(text[start:end].count('哭')+text[start:end].count('悲'))
# 可视化
plt.figure(figsize=(15,6))
plt.plot(range(120),cnt_laugh,label='笑和喜')
plt.plot(range(120),cnt_cry,label='哭和悲')
plt.title('《HLM》120回悲喜变化图',fontdict={'fontsize':14})
plt.xlabel('章节数',fontdict={'fontsize':14})
plt.ylabel('出现次数',fontdict={'fontsize':14})
plt.legend()
plt.show()

 5.3HLM之平均段落数与字数

统计每一章段落数和字数并可视化。

cnt_chap = []  # 存放每一回的段落数
cnt_word = []  # 存放每一回的字符总数
for i in range(120):start = lst_chapterIndex[i][0]end = lst_chapterIndex[i][1]cnt_chap.append(text[start:end].count('\n'))cnt_word.append(len(text[start:end]))# 可视化
plt.figure(figsize=(15,8))
plt.scatter(cnt_chap,cnt_word)
for i in range(120):plt.text(cnt_chap[i]-2,cnt_word[i]+100,lst_chapter[i],size=7)
plt.xlabel('章节段数',fontdict={'fontsize':14})
plt.ylabel('章节字数',fontdict={'fontsize':14})
plt.title('《HLM》120回',fontdict={'fontsize':14})
plt.show()

 5.4HLM之人物社交关系网络

提取小说中的人名

分析人物关系,首先我们需要将书中涉及到的人物姓名提取出来。我们利用在之前生成的词频文件,抽取排名靠前的二十四个人物,研究他们之间的社交关系情况。简便起见,将这些人物名称存放在列表Names中。 

Names=['宝玉','凤姐','贾母','黛玉','王夫人','老太太','袭人','贾琏','平儿','宝钗','薛姨妈','探春','鸳鸯','贾政','晴雯','湘云','刘姥姥','邢夫人','贾珍','紫鹃','香菱','尤氏','薛蟠','贾赦']

基于共现关系获取人物关系权重

一般我们认为,在一篇文章中的同一段出现的两个人物之间,一定具有某种关联,因此我们将每一段中的人物角色抽取出来,然后以段落为单位,统计两个角色同时出现的共现次数,并把结果存在一个二维矩阵之中。

Names=['宝玉','凤姐','贾母','黛玉','王夫人','老太太','袭人','贾琏','平儿','宝钗','薛姨妈','探春','鸳鸯','贾政','晴雯','湘云','刘姥姥','邢夫人','贾珍','紫鹃','香菱','尤氏','薛蟠','贾赦']
relations = {}
lst_para = text.split('\n')  # 按段落划分,假设在同一段落中出现的人物具有共现关系
for t in lst_para:for name1 in Names:if name1 in t:for name2 in Names:if name2 in t and name1 != name2 and (name2,name1) not in relations:relations[(name1,name2)] = relations.get((name1,name2),0)+1
print(relations.items())

接下来对权重值做归一化操作,找到共现次数的最大值,然后将所有的共现次数映射到0-1之间。

maxRela = max([v for k,v in relations.items()])
relations = {k:v/maxRela for k,v in relations.items()}
print(relations)

 绘制人物社交网络图

使用networkx库,绘制人物社交网络图。

import networkx as nx
plt.figure(figsize=(12,12))
G= nx.Graph()
# 根据relations的数据向G中添加边
for k,v in relations.items():G.add_edge(k[0],k[1],weight=v)
elarge = [(u,v)for (u,v,d) in G.edges(data=True) if d['weight']>0.6]
emidle = [(u,v)for (u,v,d) in G.edges(data=True) if (d['weight']>0.3)&(d['weight']<=0.6)]
esmall = [(u,v)for (u,v,d) in G.edges(data=True) if d['weight']<=0.3]
# 设置图形布局
pos = nx.spring_layout(G)
# 设置节点样式
nx.draw_networkx_nodes(G,pos,alpha=0.8,node_size=800)
nx.draw_networkx_edges(G,pos,edgelist=elarge,width=2.5,alpha=0.9,edge_color='g')
nx.draw_networkx_edges(G,pos,edgelist=emidle,width=1.5,alpha=0.6,edge_color='r')
nx.draw_networkx_edges(G,pos,edgelist=esmall,width=1,alpha=0.4,edge_color='b',style='dashed')
nx.draw_networkx_labels(G,pos,font_size=12)
plt.axis('off')
plt.title('《HLM》主要人物社交关系网络图')
plt.show()

 emmm,这个风格好像有点不太好看,我们换个风格。

plt.figure(figsize=(8,6))
pos = nx.circular_layout(G)
# 设置节点样式
nx.draw_networkx_nodes(G,pos,alpha=0.6,node_size=800)
nx.draw_networkx_edges(G,pos,edgelist=elarge,width=2.5,alpha=0.9,edge_color='g')
nx.draw_networkx_edges(G,pos,edgelist=emidle,width=1.5,alpha=0.6,edge_color='r')
nx.draw_networkx_edges(G,pos,edgelist=esmall,width=1,alpha=0.2,edge_color='b',style='dashed')
nx.draw_networkx_labels(G,pos,font_size=12)
plt.axis('off')
plt.title('《HLM》主要人物社交关系网络图')
plt.show()

绿色权值最大,代表关系越深;红色权值处于中间,关系一般;蓝色权值最低,关系较弱。 

 从关系图中,我们可以看出贾宝玉社交关系又多又深,不愧是小说中的主角,社交广泛。

好了,以上就是本次分享的项目案例,如果对读者有所帮助,那就留下你的三连吧。


http://chatgpt.dhexx.cn/article/J1umEOPX.shtml

相关文章

Python数据挖掘-NLTK文本分析+jieba中文文本挖掘

一、NLTK介绍及安装 &#xff08;注&#xff1a;更多资源及软件请W信关注“学娱汇聚门”&#xff09; 1.1 NLTK安装 NLTK的全称是natural language toolkit&#xff0c;是一套基于python的自然语言处理工具集。 nltk的安装十分便捷&#xff0c;只需要pip就可以。相对Python2…

文本挖掘详解

一、文本挖掘概念 在现实世界中&#xff0c;可获取的大部信息是以文本形式存储在文本数据库中的&#xff0c;由来自各种数据源的大量文档组成&#xff0c;如新闻文档、研究论文、书籍、数字图书馆、电子邮件和Web页面。由于电子形式的文本信息飞速增涨&#xff0c;文本挖掘已经…

什么是文本挖掘 ?

什么是文本挖掘   文本挖掘是抽取有效、新颖、有用、可理解的、散布在文本文件中的有价值知识&#xff0c;并且利用这些知识更好地组织信息的过程。1998年底&#xff0c;国家重点研究发展规划首批实施项目中明确指出&#xff0c;文本挖掘是“图像、语言、自然语言理解与知识…

文本数据分析:文本挖掘还是自然语言处理?

数据分析师Seth Grimes曾指出“80%的商业信息来自非结构化数据&#xff0c;主要是文本数据”&#xff0c;这一表述可能夸大了文本数据在商业数据中的占比&#xff0c;但是文本数据的蕴含的信息价值毋庸置疑。KDnuggets的编辑、机器学习研究者和数据科学家Matthew Mayo就在网站上…

Python数据挖掘-文本挖掘

文本挖掘概要 搞什么的&#xff1f; 从大量文本数据中&#xff0c;抽取出有价值的知识&#xff0c;并且利用这些知识更好的组织信息的过程。 目的是什么&#xff1f; 把文本信息转化为人们可利用的知识。 举例来说&#xff0c;下面的图表利用文本挖掘技术对库克iphoneX 发…

Python数据挖掘——文本分析

一、 一、定义&#xff1a; 文本挖掘&#xff1a;从大量文本数据中抽取出有价值的知识&#xff0c;并且利用这些知识重新组织信息的过程。 二、语料库&#xff08;Corpus&#xff09; 语料库是我们要分析的所有文档的集合。 import os import os.pathfilePaths [] #定义…

文本数据挖掘----数据预处理

一、数据预处理简介 1、为什么要进行数据预处理 一开始拿到的数据在数据的质量方面或多或少有一些问题&#xff0c;即在数据的准确性、完整性、一 致性、合时性&#xff08;实时性&#xff09;、可信性、解释性等方面可能存在问题&#xff0c;所以需要数据预处理来提高数据 …

文本数据挖掘----初识数据挖掘

一、数据挖掘的内容 1、关联规则挖掘 &#xff08;1&#xff09;关联规则挖掘工作内容 关联规则挖掘是指寻找给定数据集中项之间的有趣关联或相关联系&#xff08;频繁出现的项集模式知 识&#xff09;&#xff1b;可以帮助许多决策的制定。 2、非监督式机器学习-聚类 &am…

文本数据挖掘(Text Mining)

文本数据挖掘是利用某些方法比如自然语言处理&#xff08;Natural language processing (NLP)&#xff09;技术把一堆没有结构的数据而处理成有结构的数据的一种人工智能技术&#xff0c;而处理后的这些有结构的数据可以作为机器学习和深度学习模型的输入&#xff0c;也可以直接…

基于Python数据挖掘的文本数据的分类与分析

目录 数据获取 2数据预处理 2建立词典 4生成词向量 6贝叶斯分类器 7SVM 10逻辑回归 12实验总结与反思 14 实验一 文本数据的分类与分析 【实验目的】 1.掌握数据预处理的方法&#xff0c;对训练集数据进行预处理&#xff1b; 2.掌握文本建模的方法&#xff0c;对语料库的文档进…

使用VS2015编译JSBSim

1.说明 最近在研究JSBSim的代码&#xff0c;首先百度了一些JSBSim相关的文档和教程&#xff0c;有一篇《Building_JSBSim_with_Visual_Cpp_2010》讲了如何利用VS2010编译JSBSim&#xff0c;参考这个教程编译完成了一个JSBSim工程。但是这个工程是好多年以前的了&#xff0c;在…

C++学习 | VS2015下配置FFTW3库的方法,亲测实用

笔者是C的初学者&#xff0c;也是VS2015的初学者&#xff0c;最近的编程内容涉及到了傅里叶变换&#xff0c;于是查阅了很多资料&#xff0c;得知有FFTW这个十分强大的库&#xff0c;下面从下载到安装详细介绍。 一、FFTW简介 FFTW ( the Faster Fourier Transform in the W…

vs2015环境配置android,Visual Studio 2015环境搭建教程

当微软发布了Visual Studio 2015 Preview支持了wp&#xff0c;ios&#xff0c;android三大系统手机开发&#xff0c;相信也有不少朋友想迫不及待的使用这款Visual Studio 2015&#xff0c;下面小编就为大家介绍一下。 Visual Studio 2015环境搭建教程 1、安装之前先要看看自己的…

OpenCV+VS2015的详细配置(小白教程)

OpenCVVS2015的详细配置&#xff08;小白教程&#xff09; 一&#xff1a;下载安装OpenCV和VS2015配置环境变量VS2015中配置OpenCV 一&#xff1a;下载安装OpenCV和VS2015 1.下载OpenCV 进入OpenCV官网&#xff0c;下载自己想要版本。这里注意&#xff1a;OpenCV3.0是一个分界…

vs2015中用python编写程序

转载请注明出处&#xff1a;https://mp.csdn.net/postedit/81508867 python功能强大&#xff0c;但是没有专门的编写器&#xff0c;为了避免安装过多软件。在vs2015上配置使用&#xff0c;vs2015安装时直接选中python插件。本文配置中所用电脑型号是win7|64位&#xff0c;参考文…

VS2015镜像安装教程

为了更好地支持 Win10 程序的开发&#xff0c;微软发布了 VS2015。VS2015 支持开发人员编写跨平台的应用程序&#xff0c;从 Windows 到 Mac、Linux、甚至是编写 iOS 和 Android 代码&#xff01; VS2015 共有三个版本&#xff0c;分别是&#xff1a; 社区版&#xff08;Commu…

VS2015编译使用Boost库遇到的问题及正确编译使用教程

目录 背景&#xff1a; 一、VS2015Boost1.79.0时出现的问题情况 1、前言 2、问题发现 3、排查找原因 二、VS2015Boost1.69.0正确编译使用 1、执行bat文件 2、运行exe文件&#xff0c;编译lib库 3、VS2015包含库使用 背景&#xff1a; 本机电脑window10上已经安装过VS2…

VS2015 tfs的使用教程

本人文章陆续转向本人微信公账号发布 公众号&#xff1a;搬砖码农SmallNNN&#xff0c;期望您要是搬砖码农&#xff0c;一起学习探讨。 由于最新新换了工作环境&#xff0c;点击打开链接&#xff0c;看了这个文章的人大家都知道&#xff0c; 上家用的是git,这个有的教程了&am…

vs2015使用教程

一、启动 visual studio 2015 稍等片刻&#xff0c;你就会看到这个界面&#xff1a; 点击菜单&#xff1a;”文件”-“新建”-“项目”&#xff0c;会出现这个窗口&#xff1a; 选择左侧的”Visual C”下面的“win32”之后&#xff0c;选择右侧的”win32控制台应用程序”&#…

【VSCode常用插件】Path Autocomplete(@路径提示的插件)

前言❤️ 在路上&#xff0c;见识世界&#xff1b;在途中&#xff0c;认清自己 ❤️ 【VSCode常用插件】Path Autocomplete&#xff08;路径提示的插件&#xff09; 一、安装教程二、设置教程&#xff08;1&#xff09;在vscode设置打开 settings.json&#xff08;2&#xff09…