最近,发现 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
|
请发表评论