帝游网提供最新手游APP下载和游戏攻略!

走进金庸武侠:深度解析笔墨下的恩怨情仇

发布时间:2024-10-20浏览:28

提起中国武侠小说,金庸先生是绕不开的名字,十余年间以汪洋恣肆的想象力,写下15部作品。可用"飞雪连天射白鹿,笑书神侠倚碧鸳"来形容。

这些作品分别是《飞狐外传》(1960年)、《雪山飞狐》(1959年)、《连城诀》(1963年)、《天龙八部》(1963年)、《射雕英雄传》(1957年)、《白马啸西风》(1961年)、《鹿鼎记》(1969年)、《笑傲江湖》(1967年)、《书剑恩仇录》(1955年)、《神雕侠侣》(1959年)、《侠客行》(1965年)、《倚天屠龙记》(1961年)、《碧血剑》(1956年)《鸳鸯刀》(1961年)、《越女剑》(短篇小说)(1970年)。

数据获取

编写简单的爬虫程序获取金庸15本小说,并写入本地txt文件中。爬虫函数不在此展示。

文本处理

分别将小说的人物(names)、功夫(kungfu)、派别(bangs)写入txt文件中,并与小说放在同一个文件夹中。

file='D:/CuteHand/jr_novels/names.txt'   #本地文件夹,根据需要修改#可以使用os模块的添加路径with open(file) as f:    # 去掉结尾的换行符    data = [line.strip() for line in              f.readlines()]novels = data[::2]names = data[1::2]novel_names = {k: v.split() for k, v              in zip(novels, names)}

金庸小说充满恩怨情仇,其中,《倚天屠龙记》中张无忌一生遇到很多女人,如赵敏、周芷若、小昭、蛛儿、朱九真、杨不悔等,到底谁是女主角呢?我们来看下这几位美女在小说中分别出现的次数。

file='D:/CuteHand/jr_novels/倚天屠龙记.txt'with open(file) as f:        data = f.read()Actress=['赵敏','周芷若','小昭','蛛儿',         '朱九真','杨不悔']for name in Actress:    print("%s"% name,data.count(name))赵敏 1240周芷若 819小昭 352蛛儿 231朱九真 141杨不悔 190

将这几位美女在小说中出现的次数进行可视化,可以更直观地看出哪位才是张无忌的归属:

#可视化,重点在于学习使用matplotlib库画图#导入需要的包  import numpy as npimport scipy as spimport matplotlib.pyplot as plt%matplotlib inline#画图正常显示中文from pylab import mpl  mpl.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签 mpl.rcParams['axes.unicode_minus']=False  # 用来正常显示负号actress_data = {'赵敏':1240,'周芷若': 819,                '小昭': 352,'蛛儿': 231,                 '朱九真': 141,'杨不悔': 190}  for a, b in actress_data.items():    plt.text(a, b + 0.05, '%.0f' % b,     ha='center', va='bottom', fontsize=12)      #ha 文字指定在柱体中间,     #va指定文字位置     #fontsize指定文字体大小# 设置X轴Y轴数据,两者都可以是list或者tuplex_axis = tuple(actress_data.keys())y_axis = tuple(actress_data.values())plt.bar(x_axis, y_axis, color='rgbyck')  # 如果不指定color,所有的柱体都会是一个颜色#b: blue g: green r: red c: cyan#m: magenta y: yellow k: black w: whiteplt.xlabel("女角名")  # 指定x轴描述信息plt.ylabel("小说中出现次数")  # 指定y轴描述信息plt.title("谁是女主角?")  # 指定图表描述信息plt.ylim(0, 1400)  # 指定Y轴的高度plt.show()

众所周知,张无忌最终和赵敏在一起了,而与周芷若之间很是坎坷…;小昭挺喜欢的角色,可惜被不可抗拒的外力给分开了;蛛儿,暂且说是女方单恋吧;朱九真只是过客,不过也算是张无忌情窦初开喜欢的一个;杨不悔只能说是玩伴。

文本挖掘

接下来,通过分析小说人物的出场次数来判断小说的主要人物。

#继续挖掘下倚天屠龙记里面人物出现次数排名namelist=[name.strip() for name in           novel_names['倚天屠龙记']]namelist=''.join(namelist)namelist=namelist.split('、')count = []num=10 #统计前10名for name in namelist:    count.append([name, data.count(name)])count.sort(key=lambda x: x[1])_, ax = plt.subplots()numbers = [x[1] for x in count[-num:]]names = [x[0] for x in count[-num:]]ax.barh(range(num), numbers, align='center')ax.set_title('倚天屠龙记', fontsize=14)ax.set_yticks(range(num))ax.set_yticklabels(names, fontsize=10)plt.show()

网上收集了下金庸小说的功夫和门派种类,分别写入kungfu.txt和bangs.txt中,其中武功246种,门派120个。

#加入功夫和门派数据file='D:/CuteHand/jr_novels/'with open(file+"kungfu.txt") as f:    kungfu_names = [line.strip()         for line in f.readlines()]with open(file+"bangs.txt") as f:    bang_names = [line.strip()         for line in f.readlines()]#编写文本挖掘可视化函数#寻找小说出现最多的十大人物def find_main_characters(novel):    file='D:/CuteHand/jr_novels/'    with open(file+'names.txt') as f:        df = [line.strip() for               line in f.readlines()]    novels = df[::2]    names = df[1::2]    novel_names = {k: v.split() for           k, v in zip(novels, names)}    with open(file+'{}.txt'.format(novel)) as f:        data = f.read()    count = []    namelist=[name.strip() for name          in novel_names[novel]]    namelist=''.join(namelist)    namelist=namelist.split('、')    for name in namelist:        count.append([name, data.count(name)])    count.sort(key=lambda x: x[1])    _, ax = plt.subplots()    num=10    numbers = [x[1] for x in count[-num:]]    names = [x[0] for x in count[-num:]]    ax.barh(range(num), numbers, align='center')     ax.set_title(novel+"出现最多的十大人物",            fontsize=16)    ax.set_yticks(range(num))    ax.set_yticklabels(names, fontsize=14)#寻找小说出现最多的十大武功def kungfu(novel):    file='D:/CuteHand/jr_novels/'    with open(file+'{}.txt'.format(novel)) as f:        df = f.read()    namelist=kungfu_names    count = []    num=10 #统计前10名    for name in namelist:        count.append([name, df.count(name)])    count.sort(key=lambda x: x[1])    _, ax = plt.subplots()    numbers = [x[1] for x in count[-num:]]    names = [x[0] for x in count[-num:]]    ax.barh(range(num), numbers, align='center')    ax.set_title(novel+"出现最多的十大武功",            fontsize=16)    ax.set_yticks(range(num))    ax.set_yticklabels(names, fontsize=14)#寻找小说出现最多的十大门派def bang(novel):    file='D:/CuteHand/jr_novels/'    with open(file+'{}.txt'.format(novel)) as f:        df = f.read()    namelist=bang_names    count = []    num=10 #统计前10名    for name in namelist:        count.append([name, df.count(name)])    count.sort(key=lambda x: x[1])    _, ax = plt.subplots()    numbers = [x[1] for x in count[-num:]]    names = [x[0] for x in count[-num:]]    ax.barh(range(num), numbers, align='center')    ax.set_title(novel+"出现最多的十大门派",             fontsize=16)    ax.set_yticks(range(num))    ax.set_yticklabels(names, fontsize=14)#将三个函数合成一个主函数def main(novel):    find_main_characters(novel)    bang(novel)    kungfu(novel)main('倚天屠龙记')

main('天龙八部')

main('神雕侠侣')

main('笑傲江湖')

寻找人物关系

使用gensim和jieba包对文本做进一步挖掘,寻找人物之间的关系。一般要先安装相应的包,只要在Anaconda Prompt上输入pip install gensim和pip install jieba进行安装即可。

import gensimimport warningswarnings.filterwarnings(action='ignore',  category=UserWarning,module='gensim')warnings.filterwarnings(action='ignore',  category=FutureWarning,module='gensim')import jiebafor _, names in novel_names.items():    for name in names:        jieba.add_word(name)file='D:/CuteHand/jr_novels/'with open(file+"kungfu.txt") as f:    kungfu_names = [line.strip()          for line in f.readlines()]with open(file+"bangs.txt") as f:    bang_names = [line.strip()          for line in f.readlines()]for name in kungfu_names:    jieba.add_word(name)for name in bang_names:    jieba.add_word(name)books = ['天龙八部','鹿鼎记','神雕侠侣','笑傲江湖',     '碧血剑','倚天屠龙记','飞狐外传','书剑恩仇录',     '侠客行','鸳鸯刀','白马啸西风','雪山飞狐']sentences = []for novel in books:    print ("处理:{}".format(novel))    with open(file+'{}.txt'.format(novel)) as f:        data = [line.strip()                 for line in f.readlines()                 if line.strip()]    for line in data:        words = list(jieba.cut(line))        sentences.append(words)model = gensim.models.Word2Vec(sentences,         size=100,window=5, min_count=5, workers=4)

首先,来看下《倚天屠龙记》里张无忌与哪位女角的关系最紧密。

Actress=['赵敏','周芷若','小昭','蛛儿',         '朱九真','杨不悔']for a in Actress:    print("张无忌与%s的相关度" % a,model.          wv.similarity('张无忌',a)) 

结果如下:

张无忌与赵敏的相关度 0.7922112张无忌与周芷若的相关度 0.7983359张无忌与小昭的相关度 0.60103273张无忌与蛛儿的相关度 0.7526051张无忌与朱九真的相关度 0.5569755张无忌与杨不悔的相关度 0.5574214

从文本挖掘上看,张无忌似乎与周芷若“关系”更加紧密。不过,周芷若与赵敏的相关度非常接近。

其次,运用12部小说(其中,射雕英雄传、越女剑和连城诀可能存在非法字符,读不出来)交叉判断人物之间的关系。

def find_relationship(a, b, c):    """    返回 d     a与b的关系,跟c与d的关系一样        """    d, _ = model.wv.most_similar([c, b], [a])[0]    print ("给定“{}”与“{}”,“{}”和“{}”有类似的关系".          format(a, b, c, d))find_relationship('小龙女','杨过' ,'黄蓉')

输出结果(Interesting!):

给定“小龙女”与“杨过”,“黄蓉”和“郭襄”有类似的关系

词云

通过对小说文本中出现频率较高的“关键词”予以视觉上的突出,形成“关键词云层”或“关键词渲染”,过滤掉大量的文本信息,可以试着通过关键词来自行串起故事的梗概和判断人物的关系。

#引入需要的包import jiebaimport jieba.analyseimport numpy as npimport codecsimport pandas as pdfrom wordcloud import WordCloud, STOPWORDS, ImageColorGenerator#读入《倚天屠龙记》文本内容text=codecs.open('D:/CuteHand/jr_novels/倚天屠龙记.txt',                 'rb','gbk').read()tags=jieba.analyse.extract_tags(text,topK=100,      withWeight=True)tf=dict((a[0],a[1]) for a in tags)#识别中文文本wc=WordCloud(font_path='C:WindowsFontsSTZHONGS.TTF')wc=wc.generate_from_frequencies(tf)plt.figure(num=None,figsize=(12,10),facecolor='w',edgecolor='k')plt.imshow(wc)plt.axis('off')plt.show()

生成特定形状的词云

backgroud_Image = plt.imread('D:/CuteHand/jr_novels/地图.jpg')#可以自己找适合的图片做背景,最后是背景白色wc = WordCloud(    background_color='white',    # 设置背景颜色    mask=backgroud_Image,    # 设置背景图片    font_path='C:WindowsFontsSTZHONGS.TTF',      # 若是有中文的话,这句代码必须添加    max_words=2000, # 设置最大现实的字数    stopwords=STOPWORDS,# 设置停用词    max_font_size=150,# 设置字体最大值    random_state=30    # 设置有多少种随机生成状态,即有多少种配色方案)wc.generate_from_frequencies(tf)#img_colors = ImageColorGenerator(backgroud_Image)#字体颜色为背景图片的颜色#wc.recolor(color_func=img_colors)plt.figure(num=None,figsize(12,10),     facecolor='w',edgecolor='k')plt.imshow(wc)# 是否显示x轴、y轴下标plt.axis('off')plt.show()

将上述过程包装成函数,方便批量处理

def jr_cloud(novel,file):    import jieba    import jieba.analyse    import numpy as np    import codecs    import pandas as pd    from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator      text=codecs.open(file+'{}.txt'.format(novel),                       'rb','gbk').read()    tags=jieba.analyse.extract_tags(text,topK=50,withWeight=True)    tf=dict((a[0],a[1]) for a in tags)    wc=WordCloud(font_path='c:windowsontssimsun.ttc',        background_color='white')    wc=wc.generate_from_frequencies(tf)    plt.figure(num=None,figsize=(12,10),                facecolor='w',edgecolor='k')    plt.title(novel,fontsize=18)    plt.imshow(wc)    plt.axis('off')    plt.show()file='D:/CuteHand/jr_novels/'novels = ['天龙八部','鹿鼎记','神雕侠侣','笑傲江湖',         '碧血剑','倚天屠龙记','飞狐外传','书剑恩仇录',        '侠客行','鸳鸯刀','白马啸西风','雪山飞狐']jr_cloud(novels[0],file)

#鹿鼎记词云jr_cloud(novels[1],file)

#笑傲江湖词云jr_cloud(novels[3],file)

人物关系网络分析

最后运用网络分析法,将小说中的人物关系用图形展示出来。

import networkx as nximport matplotlib.pyplot as pltimport jiebaimport codecsimport jieba.posseg as psegnames = {}          # 姓名字典relationships = {}  # 关系字典lineNames = []      # 每段内人物关系# count namesjieba.load_userdict(novel_names['倚天屠龙记'])     with codecs.open("D:/CuteHand/jr_novels/       倚天屠龙记.txt", "r") as f:    for line in f.readlines():        poss = pseg.cut(line)               # 分词并返回该词词性        lineNames.append([])                # 为新读入的一段添加人物名称列表        for w in poss:            if w.flag != "nr" or len(w.word) < 2:                continue            # 当分词长度小于2或该词词性不为nr时认为该词不为人名            lineNames[-1].append(w.word)        # 为当前段的环境增加一个人物            if names.get(w.word) is None:                names[w.word] = 0                relationships[w.word] = {}            names[w.word] += 1                  # 该人物出现次数加 1# explore relationshipsfor line in lineNames:                  # 对于每一段    for name1 in line:                          for name2 in line:              # 每段中的任意两个人            if name1 == name2:                continue            if relationships[name1].get(name2) is None:     # 若两人尚未同时出现则新建项                relationships[name1][name2]= 1            else:                relationships[name1][name2] =                   relationships[name1][name2]+ 1        # 两人共同出现次数加 1with codecs.open("D:/CuteHand/jr_novels/person_edge.txt",                  "a+", "utf-8") as f:    for name, edges in relationships.items():        for v, w in edges.items():            if w >500:                f.write(name + " " + v + "                      " + str(w) + "")a = []f = open('D:/CuteHand/jr_novels/person_edge.txt',     'r',encoding='utf-8')line = f.readline()while line:    a.append(line.split())   #保存文件是以空格分离的    line = f.readline()f.close()#画图G = nx.Graph()G.add_weighted_edges_from(a)nx.draw(G,with_labels=True,font_size=9,        node_size=800,node_color='r')plt.show()

最终呈现:

用户评论

像从了良

这个游戏主题真是太棒了!我是金庸笔迷,一直想知道剧情背后那些隐藏的故事。

    有15位网友表示赞同!

凉城°

终于能深入了解主角们的内心想法,看清他们之间的纠葛。

    有19位网友表示赞同!

不浪漫罪名

期待游戏能够捕捉到金庸小说原著的细腻情感描写和刀光剑影。

    有20位网友表示赞同!

一笑抵千言

文本挖掘这个玩法听起来很有趣!希望能有互动式的剧情和解谜环节。

    有6位网友表示赞同!

纯真ブ已不复存在

如果能通过游戏体验不同角色的角度,那该有多震撼!

    有18位网友表示赞同!

冷嘲热讽i

希望游戏能够呈现出金庸小说中侠义精神的魅力。

    有16位网友表示赞同!

西瓜贩子

我喜欢探索隐藏故事的感觉,感觉这次会玩很久很沉浸。

    有12位网友表示赞同!

爱你心口难开

看金庸小说的时候一直觉得人物关系复杂,现在能用游戏的方式深入了解真是太棒了!

    有5位网友表示赞同!

青墨断笺み

期待游戏的画面和音乐能够营造出侠客情深的氛围。

    有9位网友表示赞同!

浅笑√倾城

我以前也玩过一些文本冒险游戏,这个主题真的很吸引人。

    有17位网友表示赞同!

余温散尽ぺ

希望游戏能够照顾到不同玩家的喜好,提供多种玩法选择。

    有6位网友表示赞同!

冷青裳

感觉可以结合AR技术的互动体验会更有趣!

    有5位网友表示赞同!

心贝

期待这款游戏的推出,一定会成为金庸爱好者的必玩之作。

    有15位网友表示赞同!

龙卷风卷走爱情

这个题材非常独特,我相信游戏肯定会带来不一样的体验!

    有20位网友表示赞同!

追忆思域。

希望能看到更多不同金庸小说的人物和故事的融入。

    有14位网友表示赞同!

漫长の人生

真替那些喜欢解谜的小伙伴开心!相信文本挖掘的游戏机制会很考思辨能力。

    有18位网友表示赞同!

喜欢梅西

期待游戏能够在剧情上和玩法上都给我惊喜!

    有17位网友表示赞同!

久爱不厌

希望以后还能开发其他基于文学作品的文本冒险游戏,这真是个好主意!

    有14位网友表示赞同!

花海

金庸小说的主题非常适合做成游戏,这个题材有很大的潜力。

    有7位网友表示赞同!

热点资讯