旗下导航:搜·么
当前位置:网站首页 > Python教程 > 正文

意见意义玩转——用python剖析《三国演义》中的交际收集【Python教程】,Python

作者:搜教程发布时间:2019-11-27分类:Python教程浏览:62评论:0


导读:一直以来对自然语言处置惩罚和交际收集剖析都很感兴趣,前者能协助我们从文本中取得许多发明,而后者能够让我们对人们和各个事物之间普遍存在的收集般的联络有更多熟悉。当两者连系,又会有如何...
一直以来对自然语言处置惩罚和交际收集剖析都很感兴趣,前者能协助我们从文本中取得许多发明,而后者能够让我们对人们和各个事物之间普遍存在的收集般的联络有更多熟悉。当两者连系,又会有如何的魔力呢?作为一个三国迷,我就有了如许的主意:能不能用文本处置惩罚的要领,获得《三国演义》中的人物交际收集,再举行剖析呢?python中有许多好东西能够协助我实践我猎奇的主意,如今就最先动手吧。

准备工作

取得《三国演义》的文本

chapters = get_sanguo()                 # 文本列表,每一个元素为一章的文本print(chapters[0][:106])第一回 宴桃园好汉三结义 斩黄巾好汉首建功滔滔长江东逝水,浪花淘尽好汉。是非成败回头空。青山依旧在,几度夕阳红。白发渔樵江渚上,惯看秋月春风。一壶浊酒喜相逢。古今若干事,都付笑谈中

《三国演义》并非很轻易处置惩罚的文本,它靠近古文,我们会面临昔人的字号等一系列别号。比方电脑怎样晓得“玄德”指的就是“刘备”呢?那就要我们给它一些学问。我们人经由过程进修晓得“玄德”是刘备的字,电脑也能够用相似的要领完成这个观点的衔接。我们须要通知电脑,“刘备”是实体(相似于一个对象的规范名),而“玄德”则是“刘备”的一个指称,通知的体式格局,就是供应电脑一个学问库。

entity_mention_dict, entity_type_dict = get_sanguo_entity_dict()
print("刘备的指称有:",entity_mention_dict["刘备"]

刘备的指称有: [ 刘备 , 刘玄德 , 玄德 , 使君 ]

除了人的实体和指称之外,我们也能够包含三国权势等别的范例的指称,比方“蜀”又能够叫“蜀汉”,所以学问库里还能够包含实体的范例信息来加以辨别。

print("刘备的范例为",entity_type_dict["刘备"])
print("蜀的范例为",entity_type_dict["蜀"])
print("蜀的指称有",entity_mention_dict["蜀"])

刘备的范例为 人名
蜀的范例为 权势
蜀的指称有 [ 蜀 , 蜀汉 ]

有了这些学问,理论上我们就能够编程联络起实体的各个外号啦。不过如果要从头做起的话,个中还会有不少的工作量。而HarvestText[1]是一个封装了这些步骤的文本处置惩罚库,能够协助我们轻松完成这个使命。

ht = HarvestText()ht.add_entities(entity_mention_dict, entity_type_dict)      # 加载模子print(ht.seg("誓毕,拜玄德为兄,关羽次之,张飞为弟。",standard_name=True))[ 誓毕 , , , 拜 , 刘备 , 为兄 , , , 关羽 , 次之 , , , 张飞 , 为弟 , 。 ]

交际收集竖立

成功地把指称统一到规范的实体名今后,我们就能够动手发掘三国的交际收集了。细致的竖立体式格局是应用相近共现关联。每当一对实体在两句话内同时涌现,就给它们加一条边。那末竖立收集的全部流程就如同下图所示:

我们能够运用HarvestText供应的函数直接完成这个流程,让我们先在第一章的小文本上实践一下:

# 准备工作
doc = chapters[0].replace("操","曹操")                                  # 因为偶然运用缩写,这里做一个微调
ch1_sentences = ht.cut_sentences(doc)     # 分句
doc_ch01 = [ch1_sentences[i]+ch1_sentences[i+1] for i in range(len(ch1_sentences)-1)]  #取得一切的二连句
ht.set_linking_strategy("freq")

# 竖立收集
G = ht.build_entity_graph(doc_ch01, used_types=["人名"])              # 对一切人物竖立收集,即交际收集

# 遴选主要人物绘图
important_nodes = [node for node in G.nodes if G.degree[node]>=5]
G_sub = G.subgraph(important_nodes).copy()
draw_graph(G_sub,alpha=0.5,node_scale=30,figsize=(6,4))

他们之间细致有什么关联呢?我们能够应用文本择要获得本章的细致内容:

stopwords = get_baidu_stopwords()    #过滤停用词以进步质量for i,doc in enumerate(ht.get_summary(doc_ch01, topK=3, stopwords=stopwords)): print(i,doc)玄德见皇甫嵩、朱儁,具道卢植之意。嵩曰:“张梁、张宝势穷力乏,必投广宗去依张角。时张角贼众十五万,植兵五万,相拒于广宗,未见输赢。植谓玄德曰:“我今围贼在此,贼弟张梁、张宝在颍川,与皇甫嵩、朱儁对垒。越日,于桃园中,备下乌牛白马祭礼等项,三人焚香再拜而说誓曰:“念刘备、关羽、张飞,虽然异姓,既结为兄弟,则同心同德,

本章的主要内容,看来就是刘关张桃园三结义,而且共抗黄巾贼的故事。

三国全收集绘制

有了小范围实践的基本,我们就能够用一样的要领,整合每一个章节的内容,画出一张横跨三国各代的大图。

G_chapters = []

全部交际收集有1290个人那末多,另有上万条边!那末我们要把它画出来几乎是不可能的,那末我们就遴选个中的症结人物来画出一个子集吧。

important_nodes = [node for node in G_global.nodes if G_global.degree[node]>=30]

用pyecharts举行可视化

from pyecharts import Graph

博客上不能显现交互式图表,这里就给出截图:显现了刘备的毗邻结点

全部收集扑朔迷离,背地是三国故事中无数的南征北伐、离心离德。不过有了计算机的壮大算力,我们依旧能够从中梳理出某些症结线索,比方:

人物排名-主要性

对这个题目,我们能够用收集中的排序算法处理。PageRank就是如许的一个典范要领,它本来是搜刮引擎应用网站之间的联络对搜刮效果举行排序的要领,不过对人物之间的联络也是同理。让我们取得最主要的20大人物:

page_ranks = pd.Series(nx.algorithms.pagerank(G_global)).sort_values()
page_ranks.tail(20).plot(kind="barh")
plt.show()

效果确实和上面的排序有所不同,我们看到刘备、曹操、孙权、袁绍等主公都首屈一指。而另一个风趣的发明是,司马懿、司马昭、司马师父子三人一样榜上有名,而曹氏的其他后嗣则不见其名,可见司马氏之权倾朝野。司马氏之心,好像就如许被大数据展现了出来!

社群发明

人物关联有亲疏远近,因而往往会构成一些团体。交际收集剖析里的社区发明算法就能够让我们发明这些团体,让我运用community库[2]中的供应的算法来展现这些关联吧。

import community                                    # python-louvainpartition = community.best_partition(G_main)         # Louvain算法分别社区comm_dict = defaultdict(list)for person in partition:   comm_dict[partition[person]].append(person)

在下面3个社区里,我们看到的主如果魏蜀吴三国重臣们。(只要一些小“题目”,风趣的是,电脑并不晓得他们的所属权势,只是运用算法。)

draw_community(2)
ommunity 2: 张辽 曹仁 夏侯惇 徐晃 曹洪 夏侯渊 张郃 许褚 乐进 李典 于禁 荀彧 刘晔 郭嘉 满宠 程昱 荀攸 吕虔 典韦 文聘 董昭 毛玠
draw_community(4)
community 4: 曹操 诸葛亮 刘备 关羽 赵云 张飞 马超 黄忠 许昌 孟达[魏] 孙乾
曹安民 刘璋 关平 庞德 法正 伊籍 张鲁 刘封 庞统 孟获 严颜 马良 简雍 蔡瑁 
陶谦 孔融 刘琮[刘表子] 刘望之 夏侯楙 周仓 陈登
draw_community(3)
community 3: 孙权 孙策 周瑜 陆逊 吕蒙 丁奉 周泰 程普 韩当 徐盛 张昭[吴] 马相 黄盖[吴] 潘璋 甘宁 鲁肃 凌统 太史慈 诸葛瑾 韩吴郡 蒋钦 黄祖 阚泽 朱桓 陈武 吕范
draw_community(0)
community 0: 袁绍 吕布 刘表 袁术 董卓 李傕 贾诩 审配 孙坚 郭汜 陈宫 马腾 
袁尚 韩遂 公孙瓒 高顺 许攸[袁绍] 臧霸 沮授 郭图 颜良 杨奉 张绣 袁谭 董承 
文丑 何进 张邈[魏] 袁熙

另有一些其他社区。比方在这里,我们看到三国前期,孙坚、袁绍、董卓等主公们群雄逐鹿,好不热烈。

draw_community(1)
community 1: 司马懿 魏延 姜维 张翼 马岱 廖化 吴懿 司马昭 关兴 吴班 王平 
邓芝 邓艾 张苞[蜀] 马忠[吴] 费祎 谯周 马谡 曹真 曹丕 李恢 黄权 钟会 蒋琬
司马师 刘巴[蜀] 张嶷 杨洪 许靖 费诗 李严 郭淮 曹休 樊建 秦宓 夏侯霸 杨仪
 高翔 张南[魏] 华歆 曹爽 郤正 许允[魏] 王朗[司徒] 董厥 杜琼 霍峻 胡济 贾充
  彭羕 吴兰 诸葛诞 雷铜 孙綝 卓膺 费观 杜义 阎晏 盛勃 刘敏 刘琰 杜祺 上官雝 
  丁咸 爨习 樊岐 曹芳 周群

这个社区是三国后期的主要人物了。这个收集背地的故事,是司马氏两代三人打败姜维带领的蜀汉群雄,又扫除了曹魏内部的曹家权势,终究登上权利的巅峰。

动态收集

研讨交际收集随时候的变化,是个很有意义的使命。而《三国演义》大抵根据时候线叙说,且有着极长的时候跨度,顺着故事线往下走,交际收集会发作什么样的变化呢?

这里,我取10章的文本作为跨度,每5章纪录一次当前跨度中的交际收集,就相当于留下一张快照,把这些快照衔接起来,我们就能够看到一个交际收集变化的动画。快照照样用networkx获得,而制造动画,我们能够用moviepy。

江山代有才人出,让我们看看在故事生长的各个阶段,都是哪一群人活泼在舞台中心呢?

import moviepy.editor as mpy
from moviepy.video.io.bindings import mplfig_to_npimage
width, step = 10,5
range0 = range(0,len(G_chapters)-width+1,step)
numFrame, fps = len(range0), 1
duration = numFrame/fps
pos_global = nx.spring_layout(G_main)

def make_frame_mpl(t):
   i = step*int(t*fps)
   G_part = nx.Graph()
   for G0 in G_chapters[i:i+width]:
       for (u,v) in G0.edges:
           if G_part.has_edge(u,v):
               G_part[u][v]["weight"] += G0[u][v]["weight"]
           else:
               G_part.add_edge(u,v,weight=G0[u][v]["weight"])
   largest_comp = max(nx.connected_components(G_part), key=len)
   used_nodes = set(largest_comp) & set(G_main.nodes)
   G = G_part.subgraph(used_nodes)
   fig = plt.figure(figsize=(12,8),dpi=100)
   nx.draw_networkx_nodes(G,pos_global,node_size=[G.degree[x]*10 for x in G.nodes])
#     nx.draw_networkx_edges(G,pos_global)
   nx.draw_networkx_labels(G,pos_global)
   plt.xlim([-1,1])
   plt.ylim([-1,1])
   plt.axis("off")
   plt.title(f"第{i+1}到第{i+width+1}章的交际收集")
   return mplfig_to_npimage(fig)
animation = mpy.VideoClip(make_frame_mpl, duration=duration)

animation.write_gif("./images/三国交际收集变化.gif", fps=fps)

雅观起见,动画中省略了收集中的边。

跟着时候的变化,曾站在历史舞台中心的人们也逐渐地会逐渐脱离,让人不禁欷歔叹息。正如《三国演义》开篇所言:

古今若干事,都付笑谈中。

本日,小辈应用python做的一番笑谈也就到此结束吧……

【引荐课程:Python视频教程】

以上就是意见意义玩转——用python剖析《三国演义》中的交际收集的细致内容,更多请关注ki4网别的相干文章!

标签:Python


欢迎 发表评论: