星期六, 十二月 03, 2011

杂议文化与宗教

世界末日
2012年快到了,受到电影《2012》的影响,世界末日又成了大伙茶余饭后的谈资。回想起来,不算太久的一段时间内,我们已经面对了若干个“世界末日”了:1982年的九星连珠,1999年的行星大十字,2012年的玛雅预言。似乎每隔十来年,就有一个“末日”诞生,好让大家津津乐道。这不得不让人好奇,到底是什么让人相信世界末日的存在呢?
那些末日预言大部分来自西方,我们也能很自然地联想到基督教中的末日审判:在未来的某一天,世界发生灾难,基督再临,信神的人得到救赎,其他人受到惩罚。其实不光基督教,众多宗教教义中都有世界末日说:犹太教中弥赛亚再临,拯救上帝的选民;伊斯兰教中死者复活,接受真主的审判;佛教中弥勒佛降世,度化信众脱离生死轮回。末日审判是基督教,犹太教,伊斯兰教的基本教义,信徒在末日恐惧中期盼神的帮助,深化对神的景仰。这些教义大都把世界末日描述得极其惨烈,唯有神能拯救人类于水火,神也一定会拯救信仰祂的人。信徒在神那里获得了希望,神在信徒那里巩固了地位。所以,一旦有任何关于世界末日的蛛丝马迹,信徒们自然不会错过。

中国的传统宗教
影响古代中国两大宗教就是佛教和道教了。佛教是印度的舶来品,道教则是由道家思想衍生的本土宗教。这两门宗教各自成体系,在发展中又彼此交融,在民间又有很多传说和故事把它们联系在一起。在《西游记》里面,孙悟空本是道教出身,大闹了道教玉皇大帝的天宫,玉皇大帝向释迦佛祖求援,悟空被佛祖压在五行山下五百年后,拜唐僧入佛门,取真经后成佛。故事中唐僧师徒遇难时,佛门道门都来帮忙,亲如一家。这就让人不禁要问,为啥在西方不同宗教冲突不断,在中国宗教却能彼此交融?
首先要指出的是,在中国皇权最大,皇权不需要借助宗教力量打击异己。宗教为了发展必须迎合皇权,谁要在下面惹事,皇帝肯定不干。其次,大部分中国老百姓信奉实用主义,即便有意识形态的纷争,也是谁上台,支持谁。中国历史上时而兴佛,时而兴道,人们信着信着也就弄混了。第三,佛教和道教代表的两类希望并不冲突,恰好互补:有能力的人,像皇帝,显贵从道教炼丹,求长生不老;没能力的老百姓,失意人士从佛教,求来生多福。有能力的和没能力的互相流动,所以佛教和道教都有受众,可以互通有无。

中国传统文化和世界末日
前面说过,佛教里面也有弥勒拯世的末日说,但算不上基本教义(佛教的基本教义是因果报应,六道轮回),而且预言的还是五十六亿年后的事情。似乎中国传统文化中少有末世的危机感,我猜可能有这么两个原因。一个是中国文化核心区少有火山爆发,海啸,大洪水这类自然灾害,老百姓对“世界末日”的直观印象不多。另一个是中国皇权至上,会杜绝下面的“妖言惑众”。实际上,在中国历史上,皇权不稳,乃至朝代更迭的时候,不乏有人宣称自己是“救世主”,比如陈胜吴广的“大楚兴陈胜王”揭开了秦帝国灭亡的序幕;元末明初,白莲教宣称“弥勒降生,明王出世”造就了朱元璋的“明”帝国。但是在国家强盛的时候则鲜有末世说。朱元璋当了天子后就取缔了白莲教。
在西方,由于教会势力强大,没有人敢触碰末世说这一基本教义,导致了隔三差五就会有人预言世界末日的现象。而人们对末日英雄的盼望兴许也是西方个人英雄主义的来由吧。

星期五, 十月 28, 2011

训练英语Wikipedia的语言模型

Wikipedia是一个非常有价值的语言资源,许多人都根据自己的需要,对其加工整理。这里要介绍的是我用英文Wikipedia训练语言模型的经历。
网上有人做过类似的事情,正好拿来借鉴一下。

第一步
下载Wikipedia的压缩数据,并解压
http://download.wikimedia.org/enwiki/latest/enwiki-latest-pages-articles.xml.bz2
第二步
从xml格式的数据中抽取正文。
网上可用的抽取Wikipedia正文的工具有很多,我也尝试了不少,不过感觉最好的是意大利人的这个
http://medialab.di.unipi.it/wiki/Wikipedia_Extractor
这个python脚本忽略掉Wikipedia中的表格,注释等信息,而专注于正文文本,稍作修改后,刚好适用于训练语言模型。
下载脚本
找到line 52
prefix = 'http://it.wikipedia.org/wiki/'
替换成
prefix = 'http://en.wikipedia.org/wiki/'
找到line 413
return '%s' % (get_wiki_document_url(document_title, ''), link_text)
替换成
return link_text
然后到工作目录下执行

mkdir extracted
python /path/to/software/WikiExtractor.py -b 500M -o extracted < /path/to/Wikipedia/dump/enwiki-latest-pages-articles.xml > extract.log 2>&1 &

就可以在extracted目录下得到一个个抽取出来的大小不超过500M的Wikipedia正文了。如果你的机器内存够大,可以不用设置文件大小上限,直接生成一个Wikipedia正文文件。为了后面叙述方便,这里把所生成的所有正文都重定向到一个文件wiki.xml中去。所生成的文件格式大概如下
<doc id="12" url="http://en.wikipedia.org/wiki/Anarchism">
Anarchism.
Anarchism is a political philosophy which considers the ...
</doc>

<doc id="25" url="http://en.wikipedia.org/wiki/Autism">
Autism.
Autism is a disorder of neural development ...
</doc>
...
接下来就可以用这个文本中的内容训练Wikipedia的语言模型了。


第三步
训练语言模型需要把文本切成一个个单元,术语叫做tokenize。我用了统计机器翻译中的一个比较典型的tokenizer(地址)。
把它下载并解压到工作目录后可以看到这个工具包里面包含两个部分:
split-sentences.perl负责将整段的文字切分成一个个句子;
tokenizer.perl负责将句子切分成一个个token。
可以通过执行下面的命令完成tokenize工作:
perl /path/to/tools/split-sentences.perl -l en < extracted/AA/wiki.xml | perl /path/to/tools/tokenizer.perl -l en > extracted/AA/wiki.tok 2>&1 &
其中wiki.tok就是分好tokens的结果。下面介绍用srilm工具包训练语言模型的操作步骤。
第四步
训练语言模型,有若干比较有名的工具包可用。比如srilmirstlm等等。这里我们用srilm来训练语言模型。下载并编译后,执行下面的命令,就可以得到语言模型了。
/path/to/srilm/bin/i686-m64/ngram-count -order 3 -interpolate -kndiscount -unk -text extracted/AA/wiki.tok -lm extracted/AA/wiki.lm > log.out 2>&1 &
这里我们训练了一个trigram的语言模型wiki.lm。查看这个文件格式如下:

head extracted/AA/wiki.lm
\data\
ngram 1=13881548
ngram 2=103081137
ngram 3=91614070
\1-grams:
-3.464225 ! -1.217958
-1.898412 " -0.8756708
-8.841018 "*" -0.1168323
...
也就是说,一共得到了13881548个unigram,103081137个bigram,91614070个trigram。
要预测一个句子由这个语言模型生成的概率可以用下面的命令,假设目标句子保存在sent.txt中。
/path/to/srilm/bin/i686-m64/ngram -lm extracted/AA/wiki.lm -ppl sent.txt
也可以看一下由这个语言模型随机生成的句子是什么样的,命令如下
/path/to/srilm/bin/i686-m64/ngram -lm extracted/AA/wiki.lm -gen 10 > gen_sent.txt
就会在gen_sent.txt中得到随机生成的10个句子。
更多好玩的东西有待进一步开发。