不知道这个标题是否有足够的吸引力把你骗进来。如果你认为统计是一个到处充满了期望方差分布回归随机多元和概率的东西,那么……你可能是对的,不过本文想要告诉你的是,你其实还可以用统计来做一些你关心的事情,比如现在,我们既谈风月,也谈统计。:D
相信大家对宋词都不会陌生。无论你是否喜欢,总还是可以吟诵出几句名篇来的。如果你经常找一些宋词来读的话,你可能会发现一个有趣的现象,那就是有些词语或意象似乎特别受到词人的青睐,像是东风,明月,芳草等等。当然,对于这个现象,不同的人有不同的看法。一种观点是这些意象往往具有特定的含义,或是抒发离恨,或是寄托相思,总之是把人们的情感倾注在了这些最常见的事物之中,让人触景生情;而另一种看法则觉得词的雕琢痕迹太明显,内容也相对单调,使得用词容易造成重复。本文当然不是来探讨这些话题的,而是想用统计的方法来给大家展示一下究竟有哪些话语被词人一次一次地书写,被读者一遍一遍地传唱。
从统计的角度来看,上面这个问题其实非常简单,无非就是计算一下宋词之中词语出现的频率,然后做一个排序就可以了。但这个问题对于中文来说恰恰是最难攻克的一个环节。在英语中,词语与词语之间有着天然的分隔符,但对于中文,只有句子之间有标点符号,句子之内只能通过词语的含义来进行辨别。这也就是为什么在文本挖掘领域中,中文的分词依然是一个富有挑战性的任务的原因。
不过好在宋词本身的形式帮了我们很大的忙。首先,宋词的句子一般都非常短,这相当于已经有了一次粗略的词语划分;其次,宋词的用词也很简洁,一个词一般是两个字,偶尔可能有三个字、四个字,超过四个字的词就非常罕见了。于是我们就有一种比较“野蛮”的做法,来对宋词中的用词进行划分。
举个例子来说,《青玉案》中的这句“东风夜放花千树”,如果把所有可能的两个字的组合列出来,就是:
东风 风夜 夜放 放花 花千 千树
如果再把三个字的可能组合列出来,则有:
东风夜 风夜放 夜放花 放花千 花千树
如果不考虑其它的可能,那么总共就有11个词语。当然,这其中会有很多无意义的组合,但是我们可以预想的是,这些无意义的组合将不太可能大规模地重复出现,因此在排序的过程中它们自动地就被排在高频词语之后了。通过这种做法,宋词中的每句话大体都能分成10个左右的词语单位,然后对所有的这些词语单位进行频数统计,就可以得到最终的高频词语列表了。
下面就通过一段R程序来进行一次实际的分析,用到的数据是从网络上整理的《全宋词》电子资料,其中可能有部分字词不正确。完整的程序和数据可以从这里下载。
首先,当然是读取数据。
txt=read.csv("SongPoem.csv",colClasses="character");
接下来提取出宋词的内容,并根据标点符号对句子进行分割。
sentences=strsplit(txt$Sentence,",|。|!|?|、");
sentences=unlist(sentences);
sentences=sentences[sentences!=""];
对句子进行分割后需要检查一遍,如果有些句子的长度超过了15个字,那么很可能是错误的字符,应该剔除掉。
s.len=nchar(sentences);
sentences=sentences[s.len<=15];
s.len=nchar(sentences);
下面的这个函数非常重要,其作用就是按照之前的做法把所有可能的字的组合计算出来。这里只是考虑了两个字的组合。
splitwords=function(x,x.len) substring(x,1:(x.len-1),2:x.len);
接下来就好办了,无非就是应用上面的函数对句子进行拆分,然后统计词频并排序。
words=mapply(splitwords,sentences,s.len,SIMPLIFY=TRUE,USE.NAMES=FALSE);
words=unlist(words);
words.freq=table(words);
words.freq=sort(words.freq,decreasing=TRUE);
words.freq[1:100];
最后的结果如下:
排序 词语 频数 排序 词语 频数
1 □□ 1584 51 匆匆 357
2 东风 1379 52 芙蓉 356
3 何处 1231 53 今日 354
4 人间 1164 54 扁舟 351
5 风流 843 55 西湖 350
6 归去 818 56 憔瘁 349
7 春风 800 57 消息 347
8 西风 782 58 桃花 343
9 归来 768 59 何事 335
10 江南 760 60 一片 333
11 相思 759 61 神仙 332
12 梅花 725 62 一声 331
13 千里 668 63 黄花 330
14 多少 653 64 心事 330
15 回首 649 65 鸳鸯 328
16 如今 647 66 十分 327
17 明月 646 67 人生 324
18 阑干 632 68 断肠 323
19 年年 605 69 佳人 323
20 万里 587 70 长安 321
21 一笑 579 71 东君 319
22 黄昏 561 72 桃李 319
23 当年 537 73 而今 318
24 芳草 533 74 为谁 317
25 天涯 531 75 无情 307
26 相逢 523 76 去年 306
27 尊前 519 77 天气 306
28 一枝 510 78 不是 305
29 风雨 500 79 海棠 305
30 流水 481 80 少年 305
31 风吹 474 81 今夜 304
32 依旧 469 82 不似 303
33 多情 458 83 十年 303
34 风月 452 84 行人 300
35 当时 451 85 谁知 300
36 故人 445 86 寂寞 299
37 斜阳 444 87 肠断 297
38 无人 443 88 江上 297
39 不知 426 89 悠悠 297
40 深处 424 90 富贵 295
41 不见 416 91 时候 295
42 时节 407 92 昨夜 295
43 凄凉 404 93 几度 292
44 平生 394 94 月明 292
45 春色 393 95 何时 291
46 无限 381 96 青山 291
47 一点 374 97 蓬莱 290
48 功名 366 98 往事 290
49 杨柳 363 99 如何 287
50 天上 361 100 惟有 287
需要解释一下的是,排在第一位的方框是词库中的一些出错的字符,直接略去即可。
至此,真相大白。至于这个结果意味着什么,就留给读者自己细细品读吧。
发表/查看评论