网上有人做过类似的事情,正好拿来借鉴一下。
第一步
下载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
然后到工作目录下执行
网上可用的抽取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工具包训练语言模型的操作步骤。
第四步
训练语言模型,有若干比较有名的工具包可用。比如srilm,irstlm等等。这里我们用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也就是说,一共得到了13881548个unigram,103081137个bigram,91614070个trigram。
\data\
ngram 1=13881548
ngram 2=103081137
ngram 3=91614070
\1-grams:
-3.464225 ! -1.217958
-1.898412 " -0.8756708
-8.841018 "*" -0.1168323
...
要预测一个句子由这个语言模型生成的概率可以用下面的命令,假设目标句子保存在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个句子。
更多好玩的东西有待进一步开发。