作者:刘程浩 广州CPDA11期学员 经济学硕士擅长通过数据对业务流程进行分析和优化。
十多年前吧,我们几个小伙伴还是一起组队参赛“挑战杯”的时候,我们队里面有个统计系的前辈跟我们分享了一个关于统计学应用在文学中的一个案例。
这个是关于通过统计学判断《红楼梦》的两个作者是谁的事情。
我们都在读书的时候学过《红楼梦》的作者有两个!曹雪芹写了前80回,高鹗续写了后40回。不过我读书那会儿从来就没怀疑过,因为老师说的都是权威的嘛。然而,红学上关于《红楼梦》的作者争议一直很大,存在着很多种版本。
话说回来,我相信读过《红楼梦》的人可能都感觉的出,前80回和后40回从文笔上是有些差距的,但这种差距也不至于是狗尾续貂。而我在写本文而收集素材的时候,不停的复制+粘贴电子版的红楼梦各章节时,也发觉越到后面的章节,诗词越少甚至没有了。因此,直观上也感觉有那么一点意思。
统计学家则不是依靠直觉做判断。曾经有统计学家试图从一个作家的虚词使用分布上去做甄别《红楼梦》的作者。首先,统计学家通过虚词的分布,证明了前80回和后40回是存在显著性差异的,说明确实是来自于两个不同的作者。然后,再通过曹雪芹和高鹗在出版《红楼梦》相关章节之前和之后的文章的虚词分布做比对,发现最终在统计上能说明《红楼梦》是曹雪芹和高鹗两个作者。
但是前辈和我们说,从后40回的详细分析来看,统计学家还发现可能还不止高鹗一个人写的,或许存在第3个作者!
前辈的这个案例的分享,在当时无疑对我增添对统计学的兴趣爱好之熊熊烈火火,又加了一把干柴。
时光荏苒,时隔多年我在知乎上又看到了这个老话题。
不过知乎上涉及的内容,得益于现在数据分析方法工具的日益丰富,有好多人用更多的新方法例如主成分分析法,用SVM,用聚类分析都做了相似的研究。
看到大家都那么有热情用数据分析的工具来搞搞小研究,正好挠到我的痒处!我也打算尝试过下小瘾,我也来试试看,《红楼梦》的作者通过数据分析的方法能不能用识别出来到底是多少个人。
首先第一步,你得有一个电子版的,可用于分析的《红楼梦》。于是我就上网从电子书下载的网站上,找一篇下载量比较靠前的TXT格式的《红楼梦》。这个电子版红楼梦我试着读了几个章节,没有那种劣质读本错别字、漏字语句不顺的现象。而且和1982年经典版本的《红楼梦》总字数非常接近。算是没有糟蹋这次的研究吧。
接下来要做的事情并不是说马上去做分析研究,而是要认真想一想前人他们做研究时的一个假设,到底是不是有道理。什么假设呢?那就是“作家的作品中,虚词分布有其独特性,是相当难模仿出来的,因此可以作为分辨作者身份的参照物(或者说文学指纹)”。
我发现在知乎里面,这个假设几乎是所有分析的人都默认的,然而就是没有人能够站出来说这个假设是合理的。
那虚词是啥,就是区别于实词的。搜了一下资料,大众对虚词的认识有2个共同点:一是虚词必须依附于实词或语句,来表达或丰富语法意义;二是虚词不能单独成句,不能单独作句法成分。
由于我不是学语言文学的,所以我也没办法从汉语言文学的理论角度上去证明这个假设。不过我就想尝试着从逻辑上,从现实的感知上看能不能说得过去。因为“每个作家作品中虚词使用是有其独特性”的这个假设,那么多的人都认为它有道理,我想必然有他合理的地方。我归纳了一下,大致原因有3个:
1. 每个作家都是生长在一个独特的环境的,这种环境对作家语言的影响是非常的深远,因此形成的虚词使用习惯也非常独特。
最具典型的特点就是方言环境,让虚词对语句的影响最明显。举个例子,普通话里面“看完报纸后他挺难过的”, “挺”这个时候就是虚词,作为副词用,表示“非常地”。要是这句话换成东北小品的作品的话,就会变成“看完报纸后他老难过了”,这个时候东北方言“老”代替了“挺”;而要是作者是个广西人,那么可能这句话就变成了“看完报纸后他蛮难过的”,此时“蛮”代替了“挺”;若作者是个广东人,那么就会变成“看完报纸后他几难过”,此时“几”就替代了“挺”……,例子太多了。
而且,同一个作家即便写作对象变了,虚词的使用习惯和很难改变。例如还是刚才的例子,那个广西的作家即便是将句子换成“看完报纸后他蛮高兴的”,或者“看完电影后他蛮多牢骚的”,“看完广告后他蛮……的”,“蛮”这个虚词是很难从他的用词习惯中甩掉的。
虚词除了选择有独特性外,虚词在句子中使用的位置每个人都不一样。比方说, “他时不时用手擦擦汗”和“他用手时不时擦擦汗”,意思就是一样的,但“时不时”的位置就不一样。不同人写作习惯不同,对虚词的位置使用习惯也是不同的。
除去刚才所说的作家生长语言环境的独特性外,再加上每个作家所处的时代、本身的阅历、受教育程度、人生重要事件经历又各自不同,因此其使用虚词的习惯必然是独特的,也是很难模仿的。
2.虚词不受情节的影响,这点是和实词相比最大的优势。写一本小说,如果我们统计实词的话,很容易被情节所干扰,因为实词构成了情节。比方说《水浒传》里面,武松因为打过老虎,因此在写关于他在景阳冈的那段情节中,“大虫”这个实词就会出现的比较多;但如果写到其他情节时,甚至些其他章节时,因为情节没有打虎的需要了,“大虫”这个实词又不见了,或者很少出现。顶多被“母大虫”这个绰号中的“大虫”给统计进去。
这样一来,在某些实词构成的情节中,其频率就会高发,反之就几乎统计不到,容易产生一个窘境:同一个作家,因为不同的章节和不同的小说情节差异大,相同的实词分布也就会差异很大。这样一来非常难判断出这篇文章到底是不是这个作者写的。
而虚词则不同,无论情节如何发展,作者都必然的要用他习惯的虚词来表述或补充人物或事件的一些行为、思想和事件的发展。而虚词又只是补充或修饰实词的,它们如果丢失或取消掉,对情节的事实或主干影响很小,有时候微乎其微。
举个最简单的例子,佛教禅宗六祖慧能在评价2个和尚“风动还是幡动”争论时,说的“既不是风动,也不是幡动,而是你们的心动罢了”这句话中,我们去掉“而”、“罢了”这2个虚词,原句的意思没受半点影响。
3.虚词数比实词数量少很多,统计起来工作量小。在文言文中,虚词常用的有18-20个,常用实词超过120个;现代汉语中(算上白话文这个近亲吧),根据1998年上海辞书出版社出版的《现代汉语虚词词典》来统计的话,约800多个。而实词如果我们做个不太精确的估算,按商务印书馆2012年出版的《现代汉语词典第六版》收录6.9万个词来算,减去800多个虚词,也就是说实词就超过6.8万个!因此,虚词的分布对统计计算而言,大大减少了计算量。
以上虚词的3个特点,也被前人用来做过对照实验,发现对于甄别作者来说效果不错。比方说李贤平就试过将《儿女英雄传》的某些章节混进《红楼梦》的部分章节中,结果一统计虚词的分布,就分析出这些章节不是同一个作者。
好,刚才我们分析完了“每个作家作品中虚词使用是有其独特性”的这个假设,发现从逻辑上和实际感知上都是很合理的,或者说没有很大的反对意见的话,接下来我们就要选择要分析的虚词了。
《红楼梦》是诞生于雍正时期,从文风上来看算不上很文言文,初中生都能读的了。但和现代汉语的小说比起来,又没那么“现代化”,也有很多之乎者也。因此,我们姑且先把其当成一个白话文来对待,先按文言文常用的虚词外加白话文中常见的虚词来做下尝试。
常用的文言虚词包括:于、也、而、乎、以、所、与、者、何、为、因、乃、则、其、若、之、焉、然、矣。
而白话文中常用的虚词有或、亦、方、即、皆、仍、故、尚、呀、吗、咧、罢、么、呢、让、向、往、就、但、越、再、更、很、偏等等。
确定了要分析对象后,接下来,从“简书”网站上下载了一个可以统计字、词的小工具软件,然后老老实实的将电子版的《红楼梦》按照120回进行切割,切割成了120个独立的txt文档。然后将这120回分别用这个小工具统计了这些虚词在每个章节出现的频率。
一、基础统计的分析
刚刚把这些虚词统计完的时候,我粗略的浏览了下,有个比较极端的情况出现了:“吗”和“咧”这2个做句尾修饰语气的虚词,居然几乎只出现在80回之后!
当然啦,极端不代表全貌嘛!我先将全文分成2类,前80回和后40回;以及前40回、中40回、后40回两种场景。由于这些虚词我用正态性检验检查过,1/3的虚词在全文的分布都不是正态总体,因此用均值和标准差来做分析不适合,于是我通过非参数检验来做一下探索。
对于第一种分类场景,采用Mann-whiney U 检验,对于第二种分类场景,采用Kruskal-Wallis检验和Mann-whiney U 检验,分析的结果如下
前80回&后40回 Mann-whiney U 检验
两部分的分布差异显著
(α=0.1)
但、而、方、更、故、何、很、或、即、皆、么、乃、呢、偏、其、且、让、仍、尚、所、往、向、亦、因、于、与、越、再、则、之
两部分的分布差异不显著
罢、乎、就、然、若、为、呀、焉、也、以、矣、者
前40回&中40回 Mann-whiney U 检验
两部分的分布差异显著
(α=0.1)
而、皆、就、乃、且、然、若、所、也、以、与、再
两部分的分布差异不显著
但、方、更、故、么、何、呢、偏、其、很、或、即、罢、乎、为、呀、焉、矣、者、让、仍、尚、往、向、亦、因、于、越、则、之
前40回&中40回 &后40回 Kruskal-Wallis检验
三部分的分布差异显著
(α=0.1)
但、而、方、更、故、何、很、或、即、皆、么、乃、呢、其、且、让、仍、所、往、向、也、亦、因、于、与、越、再、则、之、就、然、吗、咧
三部分的分布差异不显著
罢、偏、乎、尚、若、为、呀、焉、以、矣、者
非参数检验的结果我们看到,后40回无论是和前80回做比较,还是和1-40回,41至80回做比较,只有30%不到的虚词分布差异不显著,而更多虚词都指向了差异显著的结论。所以在这里可以推断,最后的40回应该是一个独立的作者。
那前80回分拆成2部分来看,1-40和41-80回并没有多少虚词支持差异显著。可以说明前80回是另一个作者完整写完的。因此《红楼梦》由2个作者写成的结论,从非参数检验来看是可以成立的。
二、聚类分析
聚类分析我用的纯探索式聚类。因为我也不知道最终哪些章节会明显的聚集在一起。
原理思路简介如下:
44个不同虚词,可以作为识别各个章节是否属于某一个作者的44个判断维度;
而不同虚词在每个章节的频数,就成为每个章节的各个特征指标。
因此,我的数据表的列向量,表示的是每个虚词在120个章节的出现频数,故我采用的是聚类分析中是对各个章节为个案的“个案”聚类。或者叫做Q型聚类。
我按照欧式距离、欧式距离平方、夹角余弦三种聚类法来试试,同时也对原数据按不处理、以及0-1归一化处理分别来尝试。因为谱系图太大了,不好全部都粘贴过来,因此我总结一下分析的结果。
总的来说呢,一百个人看莎士比亚,就会有100个哈姆雷特。从这些谱系图来看,你可以按照先入为主的观点来解读,也可以按一些新的观点来解读。但我发现都能说得过去。
首先,我实在是没办法不按既有观点来看这个分析结果,因为在脑海里都20年的灌输结果,不这么想还真感觉不太自然哩,呵呵。因此,三种聚类法显示1-80回和81-120回之间确实有比较清晰的界限。也就是说前80回的章节会比较少地和后40回的章节聚成一类。往往都是前80回的章节聚成几个小类,后40回的章节聚成几个小类。
无论是原始数据还是做0-1归一化处理,结论和上面差不多。唯一的差别就是用0-1归一化后,聚类的效果更明显,聚类的层次要少一些;用原始数据聚类,更多的先聚成很多小类,然后才慢慢汇聚成大类,聚类的层次要多一些。某些章节的聚类归属也有些许差异。
其次,让我说说新的观点,就是《红楼梦》可能是若干作者共同修改或编纂的。这个观点其实是参考李贤平的观点。
因为从谱系图来看,并没有展现出我们想看到的那种,前80回的章节呼的一声像听到哨子立刻就集合在了一起,后40回也在听到哨声后马上站成一堆。而是若干不同的章节先汇聚成一些小类,然后这些小类再汇聚成中等的类簇。这个过程还比较长,至少在第8次聚类的时候才明显看出某些类簇比较集中。
到了第20次的时候,这些聚类才汇集成少数几个大类。李贤平的观点是说,正因为作者很多,所以才会出现这样的层次聚类过程。当然了,他还列举了其他考证的证据来支持他的观点。
但尽管如此,不知道是否凑巧,偏偏前80回的章节和后40回的章节,他们确实比较少有交集。
下面我就随便选一个夹角余弦做聚类的方法,0-1归一化的谱系图给大家解解馋。其中图中的C119,代表的是章节119。大家看看,自己心中的“哈姆雷特”是长啥样吧!
三、主成分分析
说到主成分分析法在这方面的应用,其实一开始我看到前人有人拿来用,我内心还是有些犯嘀咕的。因为用主成分的原理,是各个章节的虚词的出现频率有相关性。这样,才有可能将有相关关系的几个章节变成一个主成分。
但是前面已经说过了,虚词有个优势就是它的出现和情节无关,那么随着小说情节的变化,它的出现频率应该是比较稳定的或变化小的。这样一来,不同章节之间的虚词出现的频率不就是没啥相关性了吗?
可我看到知乎和一些论文里面,强调说主成分分析法分析到不同作者之间的虚词差异,那到底他们是如何办到的呢?于是我就用这些虚词在各章节的出现频率使用了一把。
同样还是探索式的分析,我把所有章节作为变量进行主成分分析来看,信息比较集中在2-3个主成分上。前2个主成分能解释86%以上的信息;为了进一步分析主成分,我将主成分的轴进行旋转后,发现3个主成分,能解释88%的信息,并且每个主成分的特征值突变的没那么严重了。
解释的总方差
成份
初始特征值
旋转平方和载入
合计
方差的 %
累积 %
合计
方差的 %
累积 %
1
92.568
77.140
77.140
59.983
49.986
49.986
2
11.010
9.175
86.315
24.108
20.090
70.075
3
2.941
2.451
88.766
21.595
17.996
88.072
4
2.353
1.961
90.727
2.097
1.747
89.819
5
1.402
1.169
91.896
1.978
1.649
91.468
6
1.060
.883
92.779
1.573
1.311
92.779
从以上的计算来说,《红楼梦》所有章节,大致可以分成2大类和3大类,换句话是说作者可能是2个或3个。那这些作者是写了那些章节呢,当我们打开各主成分来看,得到的结论和聚类分析还是有比较大的差异。
PS: 我采用的旋转法是Kaiser 标准化的正交旋转法。每个主成分里面各个变量(章节)之间的荷载,我按照>0.6 才认为是显著荷载,并将之进行归类。
具体的计算结果如下:
分2类
第1类的章节
6-16、19-52、 54-77、 79-120
第2类的章节
1、2、3、4、5、17、18、53、78
分3类
第1类的章节
82、101、113、81、85、110、88、67、26、96、103、28、94、31、108、32、104、117、86、97、114、92、109、20
、112、107、87、39、40、90、119、120、83、27、89、84
、35、118、93、99、45、24、30、111、46、34、7、47、116
、100、11、21、61、95、36、115、25、59、91、52、19
、102、29、57、44、10、80、43、16、6、8、55、60、62
、72、105、106、98、49
第2类的章节
50、38、42、12、70、58、41、48、37、76、54、15、51、77、56、74、65
第3类的章节
、18、1、2、4、5、3、78、79、66、53、69、17、、14、63
、13、64、75
从上面的分析来看:如果按未旋转前的主成分来看,前2个类的章节,只有少数几个属前80回的章节属于于第二类外,绝大部分章节属于第一类。
而观察旋转了主成分轴之后,第2类和第3类的章节,都在前80回里,而第一类的章节涵盖了全文几乎70%。
这么说来,推论得到《红楼梦》应该还是有一个主要的作者,其他的作者要么补充,要么改编、修订、增补。
这个结论倒是和高鹗自己在《兰墅序跋》和《新镌全部绣像红楼梦》萃文书屋乾隆辛亥刊本卷首中所说的那样有些能说得通:
“予闻《红楼梦》脍炙人口者,几廿余年,然无全璧,无定本。……书中前八十回钞本,各家互异;今广集核勘,准情酌理,补遗订讹。”
……书中后四十回,系就历年所得,集腋成裘,更无它本可考。惟按其前后关照者,略为修辑,使其有应接而无矛盾。
那这个主要的作者是谁呢?应该还是曹雪芹,但高鹗,他(或许是他召集众人)对全文做了收集、校勘、整理。后面对负责编纂时自己又对部分的章节做了修订。才会有《红楼梦》的全文面世
呵呵,是不是我自己又多刻画了一个“哈姆雷特”呢?!
四、神经网络分析
上面几个方法,都是传统的偏统计领域的方法,都还是可以解释的。但是神经网络则没那么容易被解释。不过在很多非线性的仿真来看,效果又比较好。
所以本次我还是尝试使用了一下。我采用的是多层感知器来做分析,也就是通过神经网络对各个章节进行训练,看看能否在既定的分类基础上,支持2个作者分别撰写前80回和后40回的猜想。因为分类这种分析方法用于做探索分析不太合适,或者说做不了。
多层感知器的参数设计简单介绍下:
1、将前80回的章节标记为1,后40回章章节标记为2
2、然后将80回和后40回的章节顺序打乱,同步的这些虚词在这些章节里面的频数也跟着走,并且对虚词频数进行标准化。
3、抽取70%的章节做训练,30%的章节做测试,目的就是要看测试的那部分章节判断,和已有认识是否相同。比方说测试集那部分的章节的既定分类,和训练出的结果一致的话,那么说明这前80回和后40回的观点,还是真的能成立。
4、激活函数,隐藏层和输出层我分别采用双曲正切,softmax,以及sigmoid函数,反正都尝试了一下;
5、分别误差平方和,交叉熵作分别为监督学习的原则
6、训练方法采用批处理法;
7、分别尝试采用梯度下降法和共轭梯度下降来处理梯度优化;
8、初始学习率为0.1,0.2……0.6都尝试一下;
然后,机器就开始训练了……,不停的调参也开始了
最终训练的结果最好的情况下,参数如下:
隐藏层数为1层,隐藏层中有3个神经元;隐藏层的激活函数是双曲正切;
输出层的激活函数是softmax,采用交叉熵最小原则。
不过,神经网络训练的结果有个特点,就是不稳定。例如,隐藏层的神经元的权值只要达到阈值就可以往下传递,那么这个“达到阈值”可不是每次的情况都一样的。比方说这次比阈值高5%,下次比阈值高3%,都能往后传递。因此同样参数设定下,每次的结果都不能重复。只能说稳定保持在某个水平左右。
那么在我保持上面参数不变的情况,多层感知器训练结果就是稳定在93%-98%之间,最终朝着97%-98%左右收敛。
同时,我还是好奇的做了3个作者的假设验证,看看多层感知器能否通过学习,进行识别。我假设前40回、中40回和后40回为3个作者,然后将数据表的章节顺序打乱,同样的按照2个作者的训练方式设计参数,于是机器通过学习之后,得到的训练测试精度,一开始在75%-87%左右震荡,慢慢的一度达到了91%。但是这些训练稳定性没有2个作者验证时那么高,后来又陆续掉到60%-80%。总的来看,测试精度不算高,差不多在80%左右。
所以,按照97%-98%左右这个测试精度来看的话,看来前80回和后40回作者是2个人的猜想还是很能站得住。这个和文章第一种方法的基础统计分析还是一致的。
下图是包含1层隐藏层的网络图。
五、SVM分析
支持向量机技术和神经网络的多层感知器一样,本身做分类研究的话比较难有探索性的收获。毕竟你训练出一个超平面,只能将已有的样本进行既定类别的分类,而不能去发现样本以外的类别。
因此我还是用来对其做前80回和后40回作者是否一个人的验证。
我用MATLAB里面自带的SVM工具包来做的实验,简单介绍下操作的思路:
首先在MATLAB中要把待测试的虚词的各章节出现的频数、每个章节预先设定好的类别设定好变量,我命名是sample和type;
其次编写代码
>> train=[(sample(1:50,:));(sample(81:100,:))];
>> test=[( sample (51:80,:));( sample(101:120,:))];
>> group=[(type(1:50,:));( type (81:100,:))];
>>svmMODEL=svmtrain(train,group,'kernel_function','linear');
>>classfication=svmclassify(svmMODEL,test)
不过分析的结果发现,测试集的50个章节中,只有3个章节的分类和既定分类不一致,分类精度达到了94%!
由此看来,前80回和后40回作者是2个人的猜想也还是很能站得住滴。
由于44个虚词代表了44个维度,这里就没办法画出图来了。
小结:
基础统计分析、神经网络、SVM技术的分析结果,是支持《红楼梦》的作者为2个人的;
“聚类分析”的结果比较开放,关键看你怎么解读。它既可以支持2个作者,也可以支持多个作者,所以想用这种分析工具来做研究的话,还是得钻研下原著才行滴。
“主成分分析法”,对作者人数的判定,介于2人至3人之间。和聚类分析一样,想用这种分析工具来做研究的话,还是得钻研下原著才行滴。
后面的花絮:
说实话,如果要认真的用虚词来做技术分析,识别《红楼梦》的作者的话,还真缺少一个重要的环节。那就是曹雪芹的其他作品。也只有通过他的其他作品的虚词使用情况,来对比《红楼梦》的虚词使用情况,才能够确定红楼梦是否曹雪芹的作品。
然而,据说曹雪芹一生中流传下来的作品,除了《红楼梦》之外,还有就是《废艺斋集稿》。但是这个手稿现在找不到了,被一个金田的日本古董商人从前清的礼亲王府重金购走了,并且也在民国时期吧,几个学者费了很大的劲儿誊抄了其中一个部分做风筝的章节。结果后来那个叫金田的古董商人在日本消失了,找到找不到。
屋漏偏逢连夜雨,后来那个做风筝的章节据说在誊抄的时候由于时间很赶,后来发现有很多地方抄的不太准。所以,想要靠虚词分布的数据分析技术来鉴别曹雪芹是否原作者,还真的有很大的难题要攻克。
( “金田”是不是“金田一耕助”的亲戚啊?我禁不住暗暗思量,“金田一耕助”这哥们儿侦查的案子几乎都会有人失踪或狗带的,嘿嘿嘿)
末了,这次我作分析的过程,时间关系吧,感觉还是有些小瑕疵待完善:
首先,就是电子版的《红楼梦》和经典的1982版到底有多一致,这个我还真没来得及细读;
其次,就是统计虚词时,有些虚词可能存在实词化的场景。例如“于”可能是人名,那个时候就是实词了;“之”有可能是代词时……等。这些只有人读的时候才能够识别的。但是我用的是一个词频统计工具软件,它可分不出哪个是实词哪个是虚词,我就一股脑全当成虚词了。
假以时日,如果有足够的时间和资源,或许这篇文章能够写得再细致些。
末了,我就不去找高鹗的其他文章来跟《红楼梦》的后40回做对比了,因为我发现真的做理工男更适合我,搞文学研究真的很烧脑。