Wikipediaから日本語の大量の文章をダウンロードする
https://dumps.wikimedia.org/jawiki/latest/jawiki-latest-pages-articles.xml.bz2から日本語コンテンツをダウンロードする(1時間ぐらいかかった)。
jawiki-latest-pages-articles.xml.bz2
がダウンロードしたファイル。
圧縮状態で2.78GB、解凍すると11.64GBとかなり大きいです。
wikiextractorでxmlタグを削除して文書を切り出す
内容はxml形式なのでそのままでは使えないので(タグがたくさん入っている)、
wikiextractorで文章のみ切り出す。
git clone https://github.com/attardi/wikiextractor.git cd wikiextractor/ python setup.py install python WikiExtractor.py jawiki-latest-pages-articles.xml
textフォルダにAA, ABといったフォルダが作成され、これらのフォルダ内にwiki_00~wiki_99というテキストファイルが作成される。
この大量のテキストファイルをひとつのwiki.txtに統合する。
find text/ | grep wiki | awk '{system("cat "$0" >> wiki.txt")}'
wc -ml wiki.txt
2461万行で10億文字あるみたいですね。
ファイルの中身を見てみると、
あしたのニュース
『あしたのニュース』は、フジテレビ系列で2015年(平成27年)3月30日から2016年(平成28年) 4月2日まで、(月曜日から金曜日)の最終版に生放送されていた報道・情報番組である。後続のスポーツニュース番組『すぽると!』とコンプレックス枠を形成されていた(ビデオリサーチの視聴率公表上の放送枠、EPG、ネット各局の公式ウェブサイトの番組表のみ。新聞では『あしたのニュース』と『すぽると!』はそれぞれ単独番組扱い)。
のようになっていて、docタグ内にコンテンツが入っています。
ファイルを一定行数ごとに分割する
大きなデータを扱っていると、よく出会うエラーがOOM (out of memory)エラーです。
メモリーに載せきることができませんでした。
みたいなエラーです。
これを避けるには、ファイルを分割することが必要です。
ファイルを分割するにはsplitコマンドが便利です。
split -l 100000 wiki.txt wiki_
sedを使ってdocタグを取り除く
<doc>タグを取り除きたい場合は、
cat wiki.txt | sed '/^<[^>]*>$/d' > wiki_removed_doc_tag.txt
sedと正規表現を使って取り除けます。
catでwiki.txtを開いてパイプ( | )でsedに送って正規表現でdocタグを除去して、wiki_removed_doc_tag.txtに書き出しています。
簡単sed講座
sed '/^<[^>]*>$/d'
dはdelete(削除する)という意味
/ / で囲われた部分は正規表現を意味していて、あるパターンに基づいて文章を抜き出したりするのに使われます。
今回の例では、/ / で囲われた正規表現を使って抽出して削除(delete)するということになります。
正規表現で使われるメタ文字
^ 文頭
$ 文末
ただし、[ ] 内で使われると
[^・・・・・]
否定という意味になる。
[^0-9] 数字以外
[^a-z] 小文字のアルファベット以外という意味
[^>] は >以外の文字という意味で、
[^>]* と*(アスタリスク)がつくと0文字以上の繰り返しという意味。
なので、^<[^>]*>$は
文頭が<で始まり、文末が>で終わり <>の中は>以外の任意の文字列という意味。
つまり<doc>や<html>や<div>などのタグですね。
今回は<doc>を取り除いています。
sentencepieceで分かち書きするためのモデルを作成する
pip install sentencepiece
import sentencepiece as spm spm.SentencePieceTrainer.Train('--input=wiki.txt, --model_prefix=m --character_coverage=1.0 --vocab_size=32000')
iMacで2時間ぐらいかかった。
--character_coverage=1.0にすることですべての文字をカバーしてくれる。
デフォルトは0.9995なので、0.05%の文字がカバーされない。マイナーな漢字が無視されるということですね。一万文字あたり、5文字だが、今回はそれは困るので1.0にしました。
--model_prefix=mにより接頭辞がmのm.modelとm.vocabというファイルが作成される。
spm_segmentation.py
import sentencepiece as spm sp = spm.SentencePieceProcessor() sp.Load("m.model") print(sp.EncodeAsPieces("アメリカ南部一致ルーテル教会()の宣教師を中心とする宣教師社団在日本アメリカ南部福音ルーテル教会ユナイテッド・シノッド宣教師社団の名称で発足。民法第34条に基づき文部大臣の認可を得て社団法人として創設された。教育機関や福祉施設の設立・維持支援に取り組んだ。"))
これを実行すると、
python spm_segmentation.py
分かち書きができるようになる。そこそこ良さそうですね。
コメント