热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

自然语言处理实战:小说读取及分析(附代码)

自然语言处理实战:小说读取及分析———本文来自于萌新的小作业目录自然语言处理实战:小说读取及分析前言一、自然语言处理是什么?1、概念2、应

自然语言处理实战:小说读取及分析


——— 本文来自于萌新的小作业



目录

  • 自然语言处理实战:小说读取及分析
  • 前言
  • 一、自然语言处理是什么?
    • 1、概念
    • 2、应用
  • 二、准备工作
    • 1、学习目标
    • 2、库的引入
  • 三、数据读取与分析
    • 1、学习目标
    • 2、数据读取
    • 3、数据分析
  • 三、总结




前言

根据自然语言处理,请选择一本你喜欢的小说,对该小说进行分析。比如分析该小说的分词,词频,词性,小说人物出场次数排序,小说中食物排序(这个得有,我喜欢吃),小说人物关系等等。




一、自然语言处理是什么?


1、概念


  • 自然语言处理是计算机科学领域与人工智能领域中的一个重要方向。
  • 它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。
  • 自然语言处理是一门融语言学、计算机科学、数学于一体的科学。

2、应用


  • 拼写检查, 关键词提取&搜索,同义词查找&替换。
  • 从网页中提取有用的信息例如产品价格,日期,地址,人名或公司名等分类,例如对教科书的文本进行分级,对长文本进行正负情绪判断。
  • 机器翻译。
  • 口语对话系统。
  • 复杂的问答系统。

二、准备工作


1、学习目标


  • 深入对networkx,matplotlib包的使用
  • 学会引入词性标注接口

2、库的引入


代码如下:


import re
import networkx as nx
import matplotlib.pyplot as plt
import jieba.posseg as pseg # 引入词性标注接口
# 导入random包
import random
import codecs
# 导入pyecharts
from pyecharts import options as opts
# pyecharts 柱状图
from pyecharts.charts import Bar
# pyecharts 词云图
from pyecharts.charts import WordCloud
# 词云
import wordcloud
import imageio

三、数据读取与分析


1、学习目标


  • 掌握对词云和柱状图的创建与绘制
  • 深入对结巴分词的使用

2、数据读取

1. 文本读取


读取整本小说并转换为utf-8,代码如下:


# 定义主要人物的个数
keshihuaTop=10 # 可视化人物图人数
mainTop = 100 # 人物词云图人物数
peopleTop=10 # 人物关系图# 获取小说文本
# 读取文件
fn = open('prepare/天龙八部.txt', encoding="utf-8")
string_data = fn.read() # 读出整个文件
fn.close() # 关闭文件

2.文本预处理


利用正则表达式除去换行等字符,代码如下:


# 文本预处理
pattern = re.compile(u'\t|\n|\.|-|:|;|\)|\(|\?|"') # 定义正则表达式匹配模式
txt = re.sub(pattern, '', string_data) # 将符合模式的字符去除
print('预处理完毕')

3、数据分析

1. 词性分析
利用停用词文档分词,通过键值对的形式存储词语并且统计出现次数,以高到低排序生成词频文档

# 停词文档
def stopwordslist(filepath):stopwords = [line.strip() for line in open(filepath, 'r', encoding='utf-8').readlines()]return stopwordsstopwords = stopwordslist('prepare/tingyong.txt')# 通过键值对的形式存储词语及其出现的次数
counts1 = {} # 存放词性词频
counts2={} #存放人物词频
# # 生成词频词性文件
def getWordTimes1():cutFinal = pseg.cut(txt)for w in cutFinal:if w.word in stopwords or w.word == None:continueelse:real_word = w.word+'_'+w.flagcounts1[real_word] = counts1.get(real_word, 0) + 1getWordTimes1()items1 = list(counts1.items())
# 进行降序排列 根据词语出现的次数进行从大到小排序
items1.sort(key=lambda x: x[1], reverse=True)# 导出数据
# 分词生成人物词频(写入文档)
def wordFreq1(filepath, topn1):with codecs.open(filepath, "w", "utf-8") as f:for i in range(topn1):word, count = items1[i]f.write("{}:{}\n".format(word, count))# 生成词频文件
wordFreq1("output/天龙八部词频词性.txt", 300)

输出结果如下:



先将text数据转换为字典形式,提取字典中的数据用bar函数绘制柱状图,调用render函数生成html。

# 将txt文本里的数据转换为字典形式
fr1 = open('output/天龙八部词频词性.txt', 'r', encoding='utf-8')
dic1 = {}
keys1 = [] # 用来存储读取的顺序
for line in fr1:# 去空白,并用split()方法返回列表v1 = line.strip().split(':')dic1[v1[0]] = v1[1]keys1.append(v1[0])
fr1.close()list_name1 = list(dic1.keys()) # 人名
list_name_times1 = list(dic1.values()) # 提取字典里的数据作为绘图数据
def create_wordproperties():bar1 = Bar()bar1.add_xaxis(list_name1[0:keshihuaTop])bar1.add_yaxis("词语出现次数", list_name_times1,color='blue')bar1.set_global_opts(title_opts=opts.TitleOpts(title="词频词性可视化图", subtitle="词频词性top10"),xaxis_opts=opts.AxisOpts(axislabel_opts={"rotate": 45}))bar1.set_series_opts(label_opts=opts.LabelOpts(position="top"))# 生成 html 文件bar1.render("output/天龙八部词频词性可视化图.html")

如图所示,显然可见大部分词频在2000左右,最高词频为8651


在这里插入图片描述


同样利用jieba分词,排除长度小于2或该词词性不为nr的词,对出现次数排序并写入文档,代码如下:


# 得到 分词和出现次数
def getWordTimes2():# 分词&#xff0c;返回词性poss &#61; pseg.cut(txt)for w in poss:if w.flag !&#61; &#39;nr&#39; or len(w.word) < 2:continue # 当分词长度小于2或该词词性不为nr&#xff08;人名&#xff09;时认为该词不为人名else:real_word &#61; w.wordcounts2[real_word] &#61; counts2.get(real_word, 0) &#43; 1getWordTimes2()
items2 &#61; list(counts2.items())
# 进行降序排列 根据词语出现的次数进行从大到小排序
items2.sort(key&#61;lambda x: x[1], reverse&#61;True)# 导出数据
# 分词生成人物词频&#xff08;写入文档&#xff09;
def wordFreq2(filepath, topn):with codecs.open(filepath, "w", "utf-8") as f:for i in range(topn):word, count &#61; items2[i]f.write("{}:{}\n".format(word, count))# 生成词频文件
wordFreq2("output/天龙八部词频_人名.txt", 300)

输出结果如下&#xff1a;
在这里插入图片描述


与词频方法相同可视化人物人名出场次数&#xff0c;最终生成html



# 将txt文本里的数据转换为字典形式
fr &#61; open(&#39;output/天龙八部词频_人名.txt&#39;, &#39;r&#39;, encoding&#61;&#39;utf-8&#39;)
dic &#61; {}
keys &#61; [] # 用来存储读取的顺序
for line in fr:# 去空白,并用split()方法返回列表v &#61; line.strip().split(&#39;:&#39;)dic[v[0]] &#61; v[1]keys.append(v[0])
fr.close()
# 输出前几个的键值对
print("人物出现次数TOP", mainTop)
print(list(dic.items())[:mainTop])#  绘图
# 人名列表 (用于人物关系图,pyecharts人物出场次数图)
list_name &#61; list(dic.keys()) # 人名
list_name_times &#61; list(dic.values()) # 提取字典里的数据作为绘图数据# 可视化人物出场次数
def creat_people_view():bar &#61; Bar()bar.add_xaxis(list_name[0:keshihuaTop])bar.add_yaxis("人物出场次数", list_name_times,color&#61;&#39;blue&#39;)bar.set_global_opts(title_opts&#61;opts.TitleOpts(title&#61;"人物出场次数可视化图", subtitle&#61;"天龙八部人物TOP10"),xaxis_opts&#61;opts.AxisOpts(axislabel_opts&#61;{"rotate": 45}))bar.set_series_opts(label_opts&#61;opts.LabelOpts(position&#61;"top"))# bar.render_notebook() # 在 notebook 中展示# make_snapshot(snapshot, bar.render(), "bar.png")# 生成 html 文件bar.render("output/天龙八部人物出场次数可视化图.html")

在这里插入图片描述由柱状图可见段誉出场次数最多&#xff0c;阿紫出场次数最少

2.词云及人物关系


根据单词频率创建词云&#xff0c;生成词云图片&#xff0c;用pyecharts 生成词云&#xff0c;返回html,如下图所示&#xff1a;


# 生成词云
def creat_wordcloud():bg_pic &#61; imageio.imread(&#39;prepare/img.png&#39;)wc &#61; wordcloud.WordCloud(font_path&#61;&#39;c:\Windows\Fonts\simhei.ttf&#39;,background_color&#61;&#39;white&#39;,width&#61;1000, height&#61;800,max_words&#61;500,mask&#61;bg_pic # mask参数设置词云形状)# 从单词和频率创建词云wc.generate_from_frequencies(counts2)# generate(text) 根据文本生成词云# wc.generate(txt)# 保存图片wc.to_file(&#39;output/天龙八部词云_人名.png&#39;)# 显示词云图片plt.imshow(wc)plt.axis(&#39;off&#39;)plt.show()# 使用pyecharts 的方法生成词云
def creat_wordcloud_pyecharts():wordsAndTimes &#61; list(dic.items())(WordCloud().add(series_name&#61;"人物次数", data_pair&#61;wordsAndTimes,word_size_range&#61;[20, 100], textstyle_opts&#61;opts.TextStyleOpts(font_family&#61;"cursive"), ).set_global_opts(title_opts&#61;opts.TitleOpts(title&#61;"天龙八部词云")).render("output/天龙八部词云_人名.html"))# 颜色生成
colorNum &#61; len(list_name[0:peopleTop])# print(&#39;颜色数&#39;,colorNum)
def randomcolor():colorArr &#61; [&#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;, &#39;5&#39;, &#39;6&#39;, &#39;7&#39;, &#39;8&#39;, &#39;9&#39;, &#39;A&#39;, &#39;B&#39;, &#39;C&#39;, &#39;D&#39;, &#39;E&#39;, &#39;F&#39;]color &#61; ""for i in range(6):color &#43;&#61; colorArr[random.randint(0, 14)]return "#" &#43; colordef color_list():colorList &#61; []for i in range(colorNum):colorList.append(randomcolor())return colorList# 解决中文乱码
plt.rcParams[&#39;font.sans-serif&#39;] &#61; [&#39;SimHei&#39;] # 用来正常显示中文标签

在这里插入图片描述
在这里插入图片描述这俩张图展示了由人名构成的不同形状的词云&#xff0c;字体越大表现人物出场次数越多。


用Fruchterman-Reingold算法排列节点&#xff0c;根据每一段出现共现关系创建无向图绘制人物关系图



# 生成人物关系图
def creat_relationship():# 人物节点颜色colors &#61; color_list()Names &#61; list_name[0:peopleTop]relations &#61; {}# 按段落划分&#xff0c;假设在同一段落中出现的人物具有共现关系lst_para &#61; (txt).split(&#39;\n&#39;) # lst_para是每一段for text in lst_para:for name_0 in Names:if name_0 in text:for name_1 in Names:if name_1 in text and name_0 !&#61; name_1 and (name_1, name_0) not in relations:relations[(name_0, name_1)] &#61; relations.get((name_0, name_1), 0) &#43; 1maxRela &#61; max([v for k, v in relations.items()])relations &#61; {k: v / maxRela for k, v in relations.items()}# return relationsplt.figure(figsize&#61;(15, 15))# 创建无多重边无向图G &#61; nx.Graph()for k, v in relations.items():G.add_edge(k[0], k[1], weight&#61;v)# 筛选权重大于0.6的边elarge &#61; [(u, v) for (u, v, d) in G.edges(data&#61;True) if d[&#39;weight&#39;] > 0.6]# 筛选权重大于0.3小于0.6的边emidle &#61; [(u, v) for (u, v, d) in G.edges(data&#61;True) if (d[&#39;weight&#39;] > 0.3) & (d[&#39;weight&#39;] <&#61; 0.6)]# 筛选权重小于0.3的边esmall &#61; [(u, v) for (u, v, d) in G.edges(data&#61;True) if d[&#39;weight&#39;] <&#61; 0.3]# 设置图形布局pos &#61; nx.spring_layout(G) # 用Fruchterman-Reingold算法排列节点&#xff08;样子类似多中心放射状&#xff09;# 设置节点样式nx.draw_networkx_nodes(G, pos, alpha&#61;0.8, node_size&#61;1300, node_color&#61;colors)# 设置大于0.6的边的样式nx.draw_networkx_edges(G, pos, edgelist&#61;elarge, width&#61;2.5, alpha&#61;0.9, edge_color&#61;&#39;g&#39;)# 0.3~0.6nx.draw_networkx_edges(G, pos, edgelist&#61;emidle, width&#61;1.5, alpha&#61;0.6, edge_color&#61;&#39;y&#39;)# <0.3nx.draw_networkx_edges(G, pos, edgelist&#61;esmall, width&#61;1, alpha&#61;0.4, edge_color&#61;&#39;b&#39;, style&#61;&#39;dashed&#39;)nx.draw_networkx_labels(G, pos, font_size&#61;14)plt.title("《天龙八部》主要人物社交关系网络图")# 关闭坐标轴plt.axis(&#39;off&#39;)# 保存图表plt.savefig(&#39;output/《天龙八部》主要人物社交关系网络图.png&#39;, bbox_inches&#61;&#39;tight&#39;)plt.show()def main():#生成词频词性文件create_wordproperties()# 人物出场次数可视化图creat_people_view()# 词云图creat_wordcloud()creat_wordcloud_pyecharts()# 人物关系图creat_relationship()

在这里插入图片描述


三、总结

自然语言处理就是通过用计算机来处理人类的语言、文字&#xff0c;从而可以代替人类做一些文书类的工作&#xff0c;例如咨询、售后、海量数据处理以及公文阅读与处理等。基于此&#xff0c;NLP领域延基于此&#xff0c;NLP领域延伸处理种类繁多的任务。通过本次作业学会了分词的技术及关键词的提取&#xff0c;同时也会生成词云和柱状图的绘制&#xff0c;奇怪的知识又增加了不少。

jieba分词特点&#xff1a;


  • 支持三种分词模式&#xff1a;

    • 精确模式&#xff0c;试图将句子最精确地切开&#xff0c;适合文本分析&#xff1b;

    • 全模式&#xff0c;把句子中所有的可以成词的词语都扫描出来, 速度非常快&#xff0c;但是不能解决歧义&#xff1b;

    • 搜索引擎模式&#xff0c;在精确模式的基础上&#xff0c;对长词再次切分&#xff0c;提高召回率&#xff0c;适合用于搜索引擎分词。

  • 支持繁体分词

  • 支持自定义词典

  • MIT 授权协议

算法&#xff1a;


  • 基于前缀词典实现高效的词图扫描&#xff0c;生成句子中汉字所有可能成词情况所构成的有向无环图 (DAG)

  • 采用了动态规划查找最大概率路径, 找出基于词频的最大切分组合

  • 对于未登录词&#xff0c;采用了基于汉字成词能力的 HMM 模型&#xff0c;使用了 Viterbi 算法


推荐阅读
  • Python爬虫中使用正则表达式的方法和注意事项
    本文介绍了在Python爬虫中使用正则表达式的方法和注意事项。首先解释了爬虫的四个主要步骤,并强调了正则表达式在数据处理中的重要性。然后详细介绍了正则表达式的概念和用法,包括检索、替换和过滤文本的功能。同时提到了re模块是Python内置的用于处理正则表达式的模块,并给出了使用正则表达式时需要注意的特殊字符转义和原始字符串的用法。通过本文的学习,读者可以掌握在Python爬虫中使用正则表达式的技巧和方法。 ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了新款奇骏的两个让人上瘾的功能,分别是智能互联系统和BOSE音响。通过对新款奇骏的配置和功能进行评测,探讨了这两个新增功能的使用体验和优势。此外,还介绍了新款奇骏的其他配置和改进,如增加的座椅和驾驶辅助系统,以及内饰的舒适性提升。对于喜欢音响的消费者来说,BOSE音响的升级也是一个亮点。最后,文章提到了BOSE音响的数字还原能力,以及7座版无法配备BOSE音响的原因。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 本文讨论了Kotlin中扩展函数的一些惯用用法以及其合理性。作者认为在某些情况下,定义扩展函数没有意义,但官方的编码约定支持这种方式。文章还介绍了在类之外定义扩展函数的具体用法,并讨论了避免使用扩展函数的边缘情况。作者提出了对于扩展函数的合理性的质疑,并给出了自己的反驳。最后,文章强调了在编写Kotlin代码时可以自由地使用扩展函数的重要性。 ... [详细]
  • OO第一单元自白:简单多项式导函数的设计与bug分析
    本文介绍了作者在学习OO的第一次作业中所遇到的问题及其解决方案。作者通过建立Multinomial和Monomial两个类来实现多项式和单项式,并通过append方法将单项式组合为多项式,并在此过程中合并同类项。作者还介绍了单项式和多项式的求导方法,并解释了如何利用正则表达式提取各个单项式并进行求导。同时,作者还对自己在输入合法性判断上的不足进行了bug分析,指出了自己在处理指数情况时出现的问题,并总结了被hack的原因。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • 背景应用安全领域,各类攻击长久以来都危害着互联网上的应用,在web应用安全风险中,各类注入、跨站等攻击仍然占据着较前的位置。WAF(Web应用防火墙)正是为防御和阻断这类攻击而存在 ... [详细]
  • Java SE从入门到放弃(三)的逻辑运算符详解
    本文详细介绍了Java SE中的逻辑运算符,包括逻辑运算符的操作和运算结果,以及与运算符的不同之处。通过代码演示,展示了逻辑运算符的使用方法和注意事项。文章以Java SE从入门到放弃(三)为背景,对逻辑运算符进行了深入的解析。 ... [详细]
author-avatar
路很长别太狂_297
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有