大多数人终生追逐的那些希望和努力是毫无价值的。每个人只是因为有个胃,就注定要参与这种追逐。而且由于参与这种追逐,他的胃是可能得到满足的,但是,一个有思想、有感情的人却不能由此得到满足。——爱因斯坦

用perl实现宋词词频统计——东风何处是人间

最近,发现 yixuan 对全宋词做了个词频分析,结果吸引了广大人民群众的做词热情:“理科宅男们消灭文科生的日子到来了!拿起你的计算器,消灭文艺青年吧!” ^_^  作为一个perl爱好者,不免想用perl实现试试,毕竟perl在处理文本方面是行家。

 

代码基本原理还是参照yixuan,但少量地方做了修改,根据维基百科中关于词的介绍:按长短规模分,词大致可分小令(58字以内)、中调(59一90字)和长调(91字以上,最长的词达240字)。所以最长设置为500是合理的,因为一个汉字是2个字节。宋词词牌名典型的长度是3个汉字:比如 永遇乐 阳关曲 江南忆等,但也有长达6个以上的词牌,比如:江南上云乐,潇湘逢故人慢,凤凰台上忆吹箫等,所以为了去掉作者名字和词牌名,设置了最小长度限制20. 同时由于数据源中有些词牌名还加了括号别名,比如:满庭芳(寿黄状元·三月初八),长度已经超过20,所以需要特别去掉这样的词牌名。

 

所有代码如下:

 1 #!/usr/bin/perl -w
2 use strict;
3
4 my $in = "全宋词.txt";
5 open (IN, "<$in") || die "Cannot open file: $in";
6 my $out = "freq.list";
7 open (OUT, ">$out") || die "Cannot open file: $out";
8
9 my %phrase;
10
11 while (<IN>) {
12 chomp;
13 if (( length($_) > 20 ) && ( length($_) < 500 ) && ($_ !~ /(/)) { #1 chinese = 2 bytes
14 my @sentences = split /,|。|?|、|!/;
15 foreach (@sentences) {
16 s/\s+//g; #delete all SPACES if any
17 my @words = split //; #split sentence into char, that is half chinese.
18 my $i = 0;
19 while (defined $words[$i+3] ) {
20 $phrase{$words[$i] . $words[$i+1] . $words[$i+2] . $words[$i+3]} ++;
21 $i += 2; }
22 }
23 }
24 }
25
26 #词频降序排列,若相同,则按照汉字拼音字母排序
27 my @words_freq = sort { $phrase{$b} <=> $phrase{$a} or $a cmp $b } keys %phrase;
28 foreach (@words_freq) {
29 print OUT "$_\t" . "$phrase{$_}\n";
30 }
31
32 close (IN);
33 close (OUT);

 

得出结果和yixuan的相类似,但在个别的词排序上有差别,可能是数据来源有区别,我只是临时从网上下载的。排在第一位的是无效字符□□,这是由于数据源的问题,下载的全宋词里面就有很所这种字符,应该是由于很多古体字打不出来,用□来代替的。如下是perl程序得到的排在出现频率前100的词组。 

词频统计
  1 □□    1492
2 东风 1321
3 何处 1178
4 人间 1147
5 风流 805
6 归去 788
7 春风 770
8 西风 755
9 归来 735
10 相思 725
11 江南 701
12 梅花 681
13 千里 648
14 回首 632
15 明月 622
16 如今 621
17 多少 620
18 阑干 597
19 万里 572
20 年年 566
21 一笑 565
22 天涯 518
23 相逢 516
24 芳草 511
25 当年 501
26 黄昏 493
27 尊前 491
28 风雨 488
29 流水 463
30 风吹 450
31 依旧 449
32 当时 439
33 风月 433
34 多情 432
35 斜阳 429
36 一枝 423
37 故人 421
38 不见 420
39 无人 420
40 不知 415
41 深处 390
42 凄凉 379
43 时节 376
44 匆匆 374
45 平生 374
46 春色 371
47 无限 371
48 功名 359
49 扁舟 350
50 杨柳 347
51 西湖 344
52 天上 342
53 一点 341
54 今日 337
55 桃花 335
56 憔悴 333
57 何事 332
58 芙蓉 322
59 黄花 321
60 心事 315
61 人生 313
62 消息 312
63 一片 312
64 十分 310
65 长安 307
66 神仙 307
67 一声 307
68 十年 305
69 佳人 302
70 桃李 302
71 断肠 300
72 而今 300
73 鸳鸯 299
74 去年 295
75 肠断 294
76 少年 294
77 为谁 293
78 江上 292
79 不是 289
80 今夜 289
81 无情 287
82 往事 286
83 海棠 285
84 何时 284
85 谁知 284
86 不似 283
87 青山 283
88 时候 283
89 悠悠 282
90 寂寞 281
91 蓬莱 281
92 惟有 279
93 行人 279
94 落花 276
95 如何 276
96 燕子 275
97 一曲 275
98 几度 274
99 月明 274
100 富贵 273

 

从这个统计我们可以看出一些有趣的事实:

出现频率最高的是:“东风” "何处" 是 "人间",分列第2,3,4名。

古人对江南的确是情有独钟,不光词牌名有很多,比如:《忆江南》《江南忆》《江南好》《江南春》《江南柳》等,连词中统计出现“江南”的数目也是很庞大,占据了第11名。大部分词都是表达相思之苦(思故人,思情人,思故乡等等),比如占据前列的有:归去(6),归来(9),相思(10),千里(13),阑干(18),万里(19),天涯(22),相逢(23),故人(37)等等,真的是“为赋新词强说愁”啊。

 

参考:

http://yixuan.cos.name/cn/2011/03/text-mining-of-song-poems/

http://www.cnbeta.com/articles/164096.htm

 

posted @ 2011-12-03 18:51 东去春来 阅读(...) 评论(...) 编辑 收藏