この記事は,ラテン語プログラミング Advent Calendarの15日目の記事になります.
https://qiita.com/advent-calendar/2013/latin
はじめに
どうもはじめまして.気づいたら誕生日にラテン語の教科書が届き,いつの間にかラテン語のテキストを読む会に参加していた@miettalこと「たいしょー」と申します.
http://connpass.com/event/3898/
今回,僕はラテン語版Wikipediaのデータをデータベースに読み込んで,日本語→ラテン語に変換したり,逆にラテン語→日本語に変換したりしてみました.
データベースのコマンドを列挙しているだけなので,主にプログラマの方向けの記事にはなってしまいましたが,ラテン語版Wikipediaに限らず,他の言語版(日本語版,英語版など)でも通用する話だと思うので参考にしていただけたら幸いです.
動機
- ラテン語-日本語のWeb辞典少ないよね.
- そもそも不自由で邪悪な辞書は嫌だ.
- Wikipediaのデータいじるの面白そう.
- 「Wikipediaは6回のリンクでどの記事にも行ける」って奴あるじゃん.あれ作りたい(参考:[http://gigazine.net/news/20110915_wikitter/:title]).
- データベースのコマンド覚えるのに良さそう.教科書とかWebに載ってるつまらない例は萎える(例:社員番号,部署名など...).
- 日本語版Wikipediaはデータの量が多くて,処理に時間かかりそう.ラテン語なら軽い?
- など...
準備・データの取得
環境のセットアップ
今回,OSはDebian Linuxを使った.
http://www.debian.or.jp/
パッケージのインストール
sudo apt-get install mysql-server mysql-client
ユーザー追加
mysql -u root -p
>mysql GRANT ALL PRIVILEGES ON *.* TO username@localhost IDENTIFIED BY password WITH GRANT OPTION;
作業ディレクトリ
cd
mkdir lawiki
cd lawiki
ダウンロード
ラテン語版Wikipediaのデータのダウンロードに関するページはこちら.SQLファイルとして公開されている.
http://la.wikipedia.org/wiki/Vicipaedia:Dump
そのうち,最新版ダウンロードページはこちら.
http://dumps.wikimedia.org/lawiki/latest/
今回は,日本語→ラテン語,ラテン語→日本語に変換するだけなので,ページ情報と外国版Wikipediaへのリンクに関するものだけをダウンロードする.
- lawiki-latest-page.sql.gz (ページ情報.本文データや編集履歴は入っていない)
- lawiki-latest-langlinks.sql.gz (外国版Wikipediaへのリンク.Wikipediaの左サイドバーのやつ)
ダウンロード
wget http://dumps.wikimedia.org/lawiki/latest/lawiki-latest-page.sql.gz
wget http://dumps.wikimedia.org/lawiki/latest/lawiki-latest-langlinks.sql.gz
伸長
gzip --decompress lawiki-latest-page.sql.gz
gzip --decompress lawiki-latest-langlinks.sql.gz
データベースへ読み込む
mysql -u username -p
mysql> create database lawiki;
mysql> use lawiki
mysql> source lawiki-latest-langlinks.sql
mysql> source lawiki-latest-page.sql
データを見てみる
まず,どんな項目があるか見てみる.
mysql> describe page;
+-----------------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+---------------------+------+-----+---------+----------------+
| page_id | int(8) unsigned | NO | PRI | NULL | auto_increment |
| page_namespace | int(11) | NO | MUL | 0 | |
| page_title | varbinary(255) | NO | | | |
| page_restrictions | varbinary(255) | NO | | NULL | |
| page_counter | bigint(20) unsigned | NO | | 0 | |
| page_is_redirect | tinyint(1) unsigned | NO | MUL | 0 | |
| page_is_new | tinyint(1) unsigned | NO | | 0 | |
| page_random | double unsigned | NO | MUL | 0 | |
| page_touched | varbinary(14) | NO | | | |
| page_latest | int(8) unsigned | NO | | 0 | |
| page_len | int(8) unsigned | NO | MUL | 0 | |
| page_no_title_convert | tinyint(1) | NO | | 0 | |
+-----------------------+---------------------+------+-----+---------+----------------+
12 rows in set (0.00 sec)
mysql> describe langlinks;
+----------+-----------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-----------------+------+-----+---------+-------+
| ll_from | int(8) unsigned | NO | PRI | 0 | |
| ll_lang | varbinary(20) | NO | PRI | | |
| ll_title | varbinary(255) | NO | | | |
+----------+-----------------+------+-----+---------+-------+
3 rows in set (0.03 sec)
次に,実際にどんなデータが入っているか見てみる.
mysql> select * from page order by rand() limit 10;
+---------+----------------+---------------------+-------------------+--------------+------------------+-------------+----------------+----------------+-------------+----------+-----------------------+
| page_id | page_namespace | page_title | page_restrictions | page_counter | page_is_redirect | page_is_new | page_random | page_touched | page_latest | page_len | page_no_title_convert |
+---------+----------------+---------------------+-------------------+--------------+------------------+-------------+----------------+----------------+-------------+----------+-----------------------+
| 148945 | 0 | Cuparus | | 0 | 1 | 1 | 0.957458754558 | 20130731114711 | 1897296 | 23 | 0 |
| 17496 | 0 | 1772 | | 0 | 0 | 0 | 0.143781100115 | 20131122233309 | 2409541 | 963 | 0 |
| 128990 | 0 | Plesiosauria | | 0 | 0 | 0 | 0.684304580113 | 20131121180535 | 2459067 | 15796 | 0 |
| 183533 | 0 | Basse-Goulaine | | 0 | 1 | 0 | 0.626077621431 | 20130428203814 | 2539476 | 39 | 0 |
| 106379 | 2 | K123456 | | 0 | 0 | 0 | 0.297740073092 | 20130328033141 | 1723685 | 124 | 0 |
| 133244 | 0 | Mouterhouse | | 0 | 0 | 0 | 0.639352890557 | 20131119153122 | 2461535 | 601 | 0 |
| 80270 | 0 | Gulielmus_Sancroft | | 0 | 0 | 0 | 0.376759706596 | 20131106121400 | 2435459 | 1053 | 0 |
| 83696 | 0 | Georgius_J._Stigler | | 0 | 0 | 0 | 0.785471178401 | 20131023072455 | 2625379 | 564 | 0 |
| 67672 | 0 | Manneken_Pis | | 0 | 0 | 0 | 0.631265219803 | 20131111060306 | 2429669 | 1686 | 0 |
| 69150 | 0 | Aemilianus_Zapata | | 0 | 0 | 0 | 0.030580196108 | 20131013042356 | 2430250 | 722 | 0 |
+---------+----------------+---------------------+-------------------+--------------+------------------+-------------+----------------+----------------+-------------+----------+-----------------------+
10 rows in set (0.28 sec)
mysql> select * from langlinks order by rand() limit 10;
+---------+---------+---------------------------------------+
| ll_from | ll_lang | ll_title |
+---------+---------+---------------------------------------+
| 41633 | pnb | بوآ: جرمنی |
| 120420 | vi | Bạc hà Âu |
| 99017 | yo | 1064 Aethusa |
| 56016 | sr | Категорија:Умрли 221. |
| 187772 | it | Racines (Francia) |
| 45481 | crh | Kategoriya:1894 senesinde doğğanlar |
| 168939 | sv | Brèves |
| 195587 | pl | Vitry-lès-Cluny |
| 156134 | ja | サラダ |
| 141856 | fa | سیارک ۴۸۶۲ |
+---------+---------+---------------------------------------+
10 rows in set (4.51 sec)
どうやら,pageテーブルはpage_idがページごとに割り振られる番号で,page_titleがページタイトル,langlinksテーブルはll_fromがpage_idのことで,ll_langがどの言語のWikipediaへのリンク,ll_titleがその言語のWikipediaのページタイトルを表している.
データで遊ぶ
さきほど,実際にどんなデータが入っているのかを見たときに,日本語版Wikipediaの「サラダ」の項目に,ラテン語版Wikipediaのpage_idが156134の項目から,外国版Wikipediaのリンクが貼られていることがわかった.そこで,page_idが156134のページタイトルを調べてみる.
mysql> select * from page where page_id = 156134;
+---------+----------------+------------+-------------------+--------------+------------------+-------------+----------------+----------------+-------------+----------+-----------------------+
| page_id | page_namespace | page_title | page_restrictions | page_counter | page_is_redirect | page_is_new | page_random | page_touched | page_latest | page_len | page_no_title_convert |
+---------+----------------+------------+-------------------+--------------+------------------+-------------+----------------+----------------+-------------+----------+-----------------------+
| 156134 | 0 | Acetaria | | 0 | 0 | 0 | 0.788934734254 | 20131128082657 | 2475994 | 1055 | 0 |
+---------+----------------+------------+-------------------+--------------+------------------+-------------+----------------+----------------+-------------+----------+-----------------------+
1 row in set (0.10 sec)
どうやら,「サラダ」のラテン語はAcetariaのらしい.実際Google翻訳にかけたら同じのが出た.正しいみたい.
わざわざ,langlinksテーブルからpage_idを調べてから,pageテーブルでもう1度調べるのは面倒だから
結合させよう.
mysql> select page_title, ll_title from page inner join langlinks on page_id = ll_from where ll_lang = "ja" order by rand() limit 10;
+---------------------------+-----------------------------------------------------+
| page_title | ll_title |
+---------------------------+-----------------------------------------------------+
| Partidul_Conservator | 保守党 (ルーマニア) |
| Carmianum | カルミアーノ |
| Gadolinium | ガドリニウム |
| Oceanus_Indicus | Category:インド洋 |
| Alessandro | アレッサンドロ |
| Petrus_Bérégovoy | ピエール・ベレゴヴォワ |
| Hancock_Comitatus_(Ohium) | ハンコック郡 (オハイオ州) |
| 1956_Olympia_Hiemalia | コルティナダンペッツォオリンピック |
| Frida_Kahlo | フリーダ・カーロ |
| Gens_Antonia | Category:アントニウス氏族 |
+---------------------------+-----------------------------------------------------+
10 rows in set (0.11 sec)
おおー結合できてる.これで日本語とラテン語の対応がわかりやすくなった.
どれくらい,対応があるんだろ
mysql> select count(*) from page inner join langlinks on page_id = ll_from where ll_lang = "ja";
+----------+
| count(*) |
+----------+
| 53637 |
+----------+
1 row in set (0.13 sec)
5万項目か.ちょっと調べてみたら,小学生の国語辞典が3万〜4万項目ぐらいだったので,結構な量なのでは.
日本語→ラテン語
できた.
mysql> select page_title, ll_title from page inner join langlinks on page_id = ll_from where ll_lang = "ja" and ll_title = "サラダ";
+------------+-----------+
| page_title | ll_title |
+------------+-----------+
| Acetaria | サラダ |
+------------+-----------+
1 row in set (0.00 sec)
ラテン語→日本語
できた.
mysql> select page_title, ll_title from page inner join langlinks on page_id = ll_from where ll_lang = "ja" and page_title = "Acetaria";
+------------+-----------+
| page_title | ll_title |
+------------+-----------+
| Acetaria | サラダ |
+------------+-----------+
1 row in set (0.06 sec)
最後に
結構簡単にできました.
次はWebのフロントエンドでも作ります.
@kagamiwariさんと内容が結構被ってしまって申し訳ない感
http://qiita.com/kagamiwari/items/2967412e4a7ec9ccfb0e