转载

R语千寻第三期:张无忌究竟爱谁?

作者:朱雪宁

R语千寻第三期:张无忌究竟爱谁? 金庸的射雕三部曲,我最爱的是收官作《倚天屠龙记》。金老爷子在后记里曾说,三部曲中郭靖诚朴质实,杨过深情狂放,张无忌的个性却比较复杂,也是比较软弱。就我看来,这种软弱的一方面体现在他对爱情的选择困难症上。

幼时蝴蝶谷初遇殷离,便被一见钟情,后有婚诺之约;年少汉水舟中邂逅周芷若,后来互生情愫,几成良缘;光明顶遇小昭,意存怜惜,却终天人永隔;绿柳山庄遇赵敏,针锋相对,但也一生羁绊。张无忌本人态度比较暧昧,可以说是经过朱九真爱情滑铁卢之后一路上运势基本开挂,但他性格里却是拖泥带水,见异思迁,放到现在基本称得上是渣男中的战斗渣。张无忌究竟爱谁?这是一个被争得沸沸扬扬的问题,说实话,有一千个读者,就有一千个最爱。连金老爷子最后也只得承认:恐怕作者也难以说清。但是,真的说不清吗?我心血来潮,拿倚天屠龙记小说做了一把文本分析。

R语千寻第三期:张无忌究竟爱谁?

  1. 数据预处理

想要找倚天屠龙记的文本并不难,直接度娘打死都不能说的“倚天屠龙记 txt”即可【1】。我们先读进R来一探究竟(用readLines):

yitian = readLines("倚天屠龙记.Txt")  yitian[1:10]
##  [1] "                         一   天涯思君不可忘"                                   ##  [2] "    “春游浩荡,是年年寒食,梨花时节。白锦无纹香烂漫,玉树琼苞堆雪。静夜沉沉,"   ##  [3] "浮光霭霭,冷浸溶溶月。人间天上,烂银霞照通彻。浑似姑射真人,天姿灵秀,意气殊高"  ##  [4] "洁。万蕊参差谁信道,不与群芳同列。浩气清英,仙才卓荦,下土难分别。瑶台归去,洞"  ##  [5] "天方看清绝。”"                                                                   ##  [6] "    作这一首《无俗念》词的,乃南宋末年一位武学名家,有道之士。此人姓丘,名处机"  ##  [7] ",道号长春子,名列全真七子之一,是全真教中出类拔萃的人物。《词品》评论此词道:"  ##  [8] "“长春,世之所谓仙人也,而词之清拔如此”。这首词诵的似是梨花,其实词中真意却是"    ##  [9] "赞誉一位身穿白衣的美貌少女,说她“浑似姑射真人,天姿灵秀,意气殊高洁”,又说她"    ## [10] "“浩气清英,仙才卓荦”,“不与群芳同列”。词中所颂这美女,乃古墓派传人小龙女。"

看到这个数据形式小编也有点傻眼,一个自然段原来被分成了好多行存储(例如上图2-5行属于同一自然段),每一行长度也有所差异。鉴于同一自然段的表意比较完整,我们先并行成段。不难注意到每个自然段的开端都有空格,我们可以利用这个特性把每段首行对应的index提出来,据此分段如下,共得到4614段。

para_head = grep("//s+", yitian) cut_para1 = cbind(para_head[1:(length(para_head)-1)], para_head[-1]-1) yitian_para = sapply(1:nrow(cut_para1), function(i) paste(yitian[cut_para1[i,1]:cut_para1[i,2]], collapse = "")) yitian_para[1:4]  ## [1] "一   天涯思君不可忘"                                                            ## [2] "“春游浩荡,是年年寒食,梨花时节。白锦无纹香烂漫,玉树琼苞堆雪。静夜沉沉,浮光霭霭,冷浸溶溶月。人间天上,烂银霞照通彻。浑似姑射真人,天姿灵秀,意气殊高洁。万蕊参差谁信道,不与群芳同列。浩气清英,仙才卓荦,下土难分别。瑶台归去,洞天方看清绝。”"                                                                            ## [3] "作这一首《无俗念》词的,乃南宋末年一位武学名家,有道之士。此人姓丘,名处机,道号长春子,名列全真七子之一,是全真教中出类拔萃的人物。《词品》评论此词道:“长春,世之所谓仙人也,而词之清拔如此”。这首词诵的似是梨花,其实词中真意却是赞誉一位身穿白衣的美貌少女,说她“浑似姑射真人,天姿灵秀,意气殊高洁”,又说她“浩气清英,仙才卓荦”,“不与群芳同列”。词中所颂这美女,乃古墓派传人小龙女。她一生爱穿白衣,当真如风拂玉树,雪裹琼苞,兼之生性清冷,实当得起“冷浸溶溶月”的形容,以“无俗念”三字赠之,可说十分贴切。长春子丘处机和她在终南山上比邻而居,当年一见,便写下这首词来。"  ## [4] "这时丘处机逝世已久,小龙女也已嫁与神雕大侠杨过为妻。在河南少室山山道之上,却另有一个少女,正在低低念诵此词。这少女十八九岁年纪,身穿淡黄衣衫,骑着一头青驴,正沿山道缓缓而上,心中默想:“也只有龙姊姊这样的人物,才配得上他。”这一个“他”字,指的自然是神雕大侠杨过了。她也不拉缰绳,任由那青驴信步而行,一路上山。过了良久,她又低声吟道:“欢乐趣,离别苦,就中更有痴儿女。君应有语,渺万里层云,千山暮雪,只影向谁去?”"

单有文本数据还不成,得再把今天的主角列出来(如下),其中每一行代表人物的不同称谓,用同样的方式我们可以读入R环境中。

roles = readLines("主角名单.txt") roles[1:5]   ## [1] "殷离 蛛儿 表妹 丑姑娘 丑八怪"                    ## [2] "周芷若 芷若 周姑娘 周掌门 周师妹 周姊姊 宋夫人"  ## [3] "赵敏 郡主 小妖女 敏妹 敏敏 赵姑娘"               ## [4] "小昭 小丫头"                                     ## [5] "张无忌 无忌 曾阿牛 阿牛哥 公子 张教主"
  1. 人物分析

划分自然段之后,我们可以算算每个角色出现的自然段的数目。这里,我们需要把不同称谓都对应于同一人物(用grep函数进行匹配)。毋庸置疑,正牌男主角张无忌出现的次数最多,后面依次是赵敏、周芷若、殷离、小昭。其中,对于赵敏和周芷若的着墨可以说是难分伯仲。金老爷子对两者的性格塑造也各有不同,一个泼辣浓郁,一个气若仙姝,两者都是绝色美人,都有一定的政治才能,实难抉择。

R语千寻第三期:张无忌究竟爱谁?

roles1 = paste0("(", gsub(" ", ")|(", roles), ")") main_roles = c("殷离","周芷若","赵敏","小昭", "张无忌") role_para = sapply(roles1[1:5], grepl, yitian_para) colnames(role_para) = main_roles  role_count = data.frame(role = factor(colnames(role_para), levels = c("张无忌", "赵敏","周芷若", "殷离","小昭")), count = colSums(role_para))

R语千寻第三期:张无忌究竟爱谁?

我们再来看看出场密度统计。如果我们把每个人物出场的自然段按照顺序排列,那就不难给出每个人物的出场密度估计,为了简单起见,我们这里只给出前面戏份最重的三个主角:张无忌、赵敏、周芷若。可以看出,作者对男主张无忌的着墨算是比较均匀,而对周芷若、赵敏的安排却差别迥异。汉水初遇周芷若,那时他们还是不谙世事的年纪。后来芷若被张三丰送入峨眉门下,多年之后光明顶重逢张无忌,此时她是峨眉名门正徒,他是武当名门之后。可以说,无论从出身、还是从往日旧情、旧义上讲,都是郎才女貌、门当户对的一对儿。而对于赵敏来说,她的出场几乎出在全文的中后期,此时一没有旧情好讲,二没有出身好论,不巧的还是各大门派同仇敌忾的阶级敌人。可以说,她手上的牌不能再糟糕了。

R语千寻第三期:张无忌究竟爱谁? R语千寻第三期:张无忌究竟爱谁?

不过,尽管如此,wuli敏敏郡主的实力却不容小觑。事实上,上述四位佳人都与男主有过情感纠葛,但程度却难以界定,能不能通过她们与张教主同时出场的次数来刻画亲密程度呢?刚才提到,自然段是表意基本单元,同一自然段意义相近,中心一致。因此,可以定义她们与教主的亲密值:与张教主出现在同一自然段的次数。这个计算非常简单,只需要基本的矩阵运算。结果表明,虽然敏敏郡主出场不利,但是还是制造了更多跟教主亲密接触的机会,可以说是战斗力爆表。

colSums(role_para[,5]*role_para[,1:4]) role_count1 = data.frame(role = factor(colnames(role_para)[1:4]),   count = colSums(role_para[,5]*role_para[,1:4]))

R语千寻第三期:张无忌究竟爱谁?

  1. 称谓变化

从上面的称谓信息上来看,除了小昭的称谓比较单调之外,其他角色都有着不同称谓变化。以殷离为例,我们可以看到她在全书中称谓的变化。殷离刚出场时,金庸对其描述是“面容黝黑,脸上肌肤浮肿,凹凹凸凸,生得极是丑陋”,因此在初期时“丑八怪”是对她的刻画。而后来她的真实身份曝光,才知道她其实是殷野王之女,与张无忌是表妹之亲。因此这也就不难猜到为何在后期“殷离”和“表妹”占主要比例。

R语千寻第三期:张无忌究竟爱谁?

我们再来看看周芷若和赵敏的称谓变化。为了体现她们与张无忌关系中的称谓变化,这里只保留曾出现张无忌的自然段(这并不是一个完美的解决方案,但是是一个凑合的解决方案)。其中,周芷若的称谓变化如下图所示。可以看出,开始 “周姑娘” 和“芷若”前期出现较多,可以说是比较尊敬和亲昵的称谓。而后期随着周芷若为完成师父遗命做出种种(偷倚天剑、屠龙刀,试图杀害殷离并嫁祸赵敏),人设逐步转黑。我们也逐渐看到,更有距离感的称谓,例如周掌门、宋夫人后期频出。这也象征着她与张无忌在后期的人生道路上渐行渐远。

R语千寻第三期:张无忌究竟爱谁?

R语千寻第三期:张无忌究竟爱谁?

我们再来看看赵敏的各个称谓在各自然段分布结果(注意,这里横轴显示的是从赵敏出场开始到结束的分析结果)。可以看到,前期诸如 “赵姑娘”、“赵敏”等尊称占主要部分(注意到,这些称谓是存在心理上的距离感的),而后期来说,比较亲昵的称呼,例如“敏妹”、“敏敏”开始出场较为频繁,其主要原因是两人关系逐渐缓和。赵敏是一个有强烈自我意识的姑娘,为了追求爱情,她可以抛下所有,包括政治立场,家国天下,基本可以总结为疯狂爱爱爱。但是她又不是一个疯狂到冲昏了头脑的人,整个过程中她曾经被诬陷、被误解,但她最过人之处在于,在最糟的情况下仍然保持准确的判断和清醒的决策,这一点从她被周芷若嫁祸后再遇张无忌直至抢亲的一系列表现中可以看出。

R语千寻第三期:张无忌究竟爱谁?

R语千寻第三期:张无忌究竟爱谁?

  1. 人以群分

之前描述分析已经基本反映本书主角之间相爱相杀的关系,那么,我们能不能用语义模型做一些分析呢。为此,我选择了这两年比较火的“词向量”模型,简而言之,该模型通过对语料进行神经网络的训练,可以把每个词映射到低维向量空间,词语之间的相近关系可以用向量的cosine夹角表示。其模型推演及训练的科普帖请见【2】。前两年谷歌公开了通过神经网络训练词向量的开源工具word2vec【3】,并被多种语言版本实现【4】,我在此使用的是R语言封装的版本wordVectors包【5】。

由于中文的特殊性(不像英文一样词语之间以空格分隔),训练词向量需要先对文本进行分词。在分词的过程中,我们需要去除停用词(比如“的”、“了”等表意特征不明显的词)。R语言中的分词墙裂推荐使用jiebaR包【6】,几乎是其他分词R包效率的5-20倍。同时,此包支持用户自己添加词典,我们可以将人名等专有名词添加到词库中。

library(jiebaR) cutter = worker(bylines = TRUE, stop_word = "stop.txt") new_user_word(cutter, unlist(rolesl), rep("n", length(unlist(rolesl)))) ### insert new words  yitian_words = cutter[yitian_para] yitian_split = sapply(yitian_words, paste, collapse = " ") writeLines(yitian_split, "yitian_split.txt")

分词后,我们将词语以空格分隔输入到txt文档,并用word2vec进行训练。我们可以看看跟几个主角关系最近的都有什么词语。尽管小编对有一些词语结果也是不明觉厉,不过从中我们可以看到几个主角的大名和人物关系,例如,赵敏的另外称谓是郡主,一开始范遥是她的随从;周芷若属于峨眉一派,其师为灭绝师太。

library(wordVectors) model = train_word2vec("yitian_split.txt", output="yitian_split.bin",   threads = 3, vectors = 100, window=12, force = T) vec = read.vectors("yitian_split.bin")  nearest_to(model,model[["张无忌"]]) nearest_to(model,model[["赵敏"]]) nearest_to(model,model[["周芷若"]])

R语千寻第三期:张无忌究竟爱谁? 进一步我们可以利用词向量结果来进行聚类(此处选择层次聚类),聚类结果有点意思,可以说表征了小说中主要的人物关系。比如说,张翠山夫妇与谢逊曾一同共处冰火岛;左边的张三丰一支为武当派主要人物;金花婆婆的女儿为小昭,徒儿是殷离;灭绝师太一支主要是峨眉派代表;中间殷天正一支为明教核心首领;而最右边为郡主府的主要随从。从这幅图上来看,虽然张无忌、赵敏、周芷若同属一支,但是张无忌与赵敏的关系却更为亲密,这也印证了他在全文终时对芷若妹子说的话:

“芷若,我对你一向敬重,我对殷家表妹心生感激,对小昭是意存怜惜,可是我对赵敏却是刻骨铭心的相爱!”

rr = sapply(rolesl, function(x) x[1]) cos_dist = cosineDist(vec[rr],vec[rr]) hc = hclust(as.dist(cos_dist), method = "average") plot(hc)

R语千寻第三期:张无忌究竟爱谁?

R语千寻第三期:张无忌究竟爱谁?

  • http://vdisk.weibo.com/s/BDfQaBrpWWbtV
  • http://licstar.net/archives/328
  • https://code.google.com/archive/p/word2vec/
  • https://en.wikipedia.org/wiki/Word2vec
  • https://github.com/bmschmidt/wordVectors
  • https://github.com/qinwf/jiebaR

后记:这篇文章用到的自然语言处理手段比较生硬,也比较初级。其实,文学的美是很难用简单粗暴的手段得到一个完美的解释的,有时候,相似的表意,读者所感受到的却是各有不同。在这里,我也放出倚天中的两段文字供大家赏鉴吧:

一是赵敏抢亲之时:

杨逍和范遥对望一眼,知她今日是存心前来搅局,无论如何要立时阻止,免得将一场喜庆大事闹得尴尬狼狈,满堂不欢。杨逍踏上两步,说道:“咱们今日宾主尽礼,赵姑娘务请自重。”他已打定了主意,赵敏若要捣乱,只有迅速出手点她穴道,制住她再说。赵敏向范遥道:“苦大师,人家要对我动手,你帮不帮我?”范遥眉头一皱,说道:“郡主,世上不如意事十居八九,既已如此,也是勉强不来了。”

赵敏道:“我偏要勉强。”

二是张无忌邀周芷若共同对战之时:

周芷若冷笑道:“咱们从前曾有婚姻之约,我丈夫此刻却是命在垂危,加之今日我没伤你性命,旁人定然说我对你旧情犹存。若再邀你相助,天下英雄人人要骂我不知廉耻、水性杨花。”张无忌急道:“咱们只须问心无愧,旁人言语,理他作甚?”周芷若道:“倘若我问心有愧呢?”张无忌一呆,接不上口,只道:“你……你……”

周芷若道:“张教主,咱二人孤男寡女,深宵共处,难免要惹物议。你快请罢!”

原文 链接 。

Code链接: https://github.com/BearAcademy/R-Tutorial/tree/master/Lecture3

如果您对我们的内容感兴趣,请关注微信公众号“狗熊会”,或扫描下方二维码

R语千寻第三期:张无忌究竟爱谁?

原文  http://cos.name/2016/06/r语千寻第三期:张无忌究竟爱谁?/
正文到此结束
Loading...