OpenRefineを用いてWikidataを編集する

本記事はWikidataのサイトに掲載されている[チュートリアル](https://www.wikidata.org/wiki/Wikidata:Tools/OpenRefine/Editing/Tutorials/Inverse_Listeria)に従い、OpenRefineを用いてWikidataを編集するハンズオン用の資料です。必要な環境は以下の通りです。

- [OpenRefine Ver.3.0 RC1以降](http://openrefine.org/download.html)
- [Wikidataのアカウント](https://www.wikidata.org/w/index.php?title=Special:CreateAccount&returnto=Wikidata%3AMain+Page)（Wikipediaのアカウントなど、Wikimediaのアカウントをすでにお持ちの場合は共通で使えます。）

本資料の流れは次の通りです。最初にWikipediaの表データをOpenRefineに入力し、Wikidataの構造に合わせた整形を行います。続いてWikidataを編集するために必要なスキーマ構築を行い、最後に実際にWikidataをOpenRefineの機能を用いて編集します。

**更新情報**
2018年9月17日、OpenRefineの言語環境を日本語にしていても問題なくWikidataのスキーマ編集ができることを確認しました。

## OpenRefineにWikipediaの表を入力する

ここでは、上述のチュートリアルに倣い、例として英語版Wikipediaに掲載されている[世界の地下鉄に関するページ](https://en.wikipedia.org/wiki/List_of_metro_systems)から情報を取得します。一般的にウェブページに表示されている表を取得したい場合には、OpenRefineのクリップボード入力機能を利用して当該ページ上の表をOpenRefine上にコピペするだけでうまくいきます。しかし、Wikipediaの表の場合は、単なるページ上に表示されている表のコピペだけでは大切な情報が失われてしまうので、少し異なる方法を用います。単なるコピペでは取得できない情報とは以下の通りです。

- Wikipediaの表に埋め込まれているwikilink
- 個々のセルに記述されている参照情報

全てのWikipediaの記事は、対応するWikidataの項目にリンクがあるので、表に埋め込まれているwikilinkをたどることで、関連するWikidataの情報を取得できます。これにより、曖昧性を除去しやすくなります。たとえば、「SkyTrain」という語だけでは具体的には[幾つかの概念を表す](https://www.wikidata.org/w/index.php?search=&search=skytrain&title=Special:Search&go=Go)ので、一意にその意味を判定できませんが、表に埋め込まれているwikilinkである[SkyTrain (Vancouver)](https://en.wikipedia.org/wiki/SkyTrain_(Vancouver))をたどれば、[対応するWikidataの項目](https://www.wikidata.org/wiki/Q876780)を見つけられるので一意に決められます。また、参照情報はWikidataにデータを取り込む際に併せて含めておきたいものです。

このため、OpenRefineのコピペ入力機能にはWikipediaの表を、そのソースコードの状態で取り込む機能が含まれています。では、まずOpenRefineを起動させましょう。~~もしも言語設定を日本語にしている場合は、OpenRefine 3.0 RC1においては適切に本チュートリアルの内容を実行できないので、英語に切り替えてください。~~続いて、Wikipedia記事に含まれるリストのソースコードを表示させましょう。まず、[世界の地下鉄に関するページ](https://en.wikipedia.org/wiki/List_of_metro_systems)の[List](https://en.wikipedia.org/wiki/List_of_metro_systems#List)を表示させます。
![3_LOD_WS_SS1.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/789d8c74-993c-f8b7-d683-f22a95342c35.jpeg)
続いて、項目名「List」の右隣に表示されている「edit」をクリックします。
![3_LOD_WS_SS2.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/178c442b-3ab3-19e8-5019-4e2d5746ed58.jpeg)
すると編集モードに切り替わるので、そのさいに、Visual editorではないことを確認してください。
![3_LOD_WS_SS3.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/84edca14-cf98-5db1-940e-978d0f84d4f1.jpeg)
そして、表示される表のソースコードをすべて選択して、[コピーします](https://commons.wikimedia.org/wiki/File:OR-WD-inverse-listeria-copy-wikicode.png)。それから、OpenRefineのクリップボード入力エリアにペーストし、「Next」をクリックします。
![3_LOD_WS_SS4.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/874b764a-5260-b98b-ca93-fa644af0b1ed.jpeg)
![3_LOD_WS_SS5_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/beadfd1f-cd4d-48c0-f464-f7f7d30bd4d6.jpeg)
しばらくするとプレビューが表示されます。
![3_LOD_WS_SS6.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/fb1ad2db-45e6-a74a-3d7d-4b3a368e4013.jpeg)
初期設定では、「Include templates and images as raw wikicode」にチェックが入っていないので、ここにチェックを入れます。するとプレビューが更新され、それまで空欄だった「Country」列に値が表示されることを確認できます。
![3_LOD_WS_SS7.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/fa193c9b-50b1-3c98-ffe9-cf2c3ba33788.jpeg)
初期値として「clipboard」が入力されているOpenRefine上部の「Project name」に適宜入力して「Create Project」をクリックします。
![3_LOD_WS_SS8.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/949f9550-80a2-a8a8-3856-10b6ddffdc25.jpeg)
プロジェクトが生成されると、通常のOpenRefineへデータを入力して生成させる場合と以下の点で異なることが分かります。

- 多くのセルが既に照合されている
- 新しい列が生成されている

上述の通り、予めwikilinkを通してWikidataの項目との関連づけがされている場合はそれへのリンクが含まれています。また、同様にして参照ページへのリンクがある場合には、その値が新しい列に入力されています。それらは、「Column5」や「Column6」の値として抽出されています。
さて、OpenRefineにより自動的に照合が行われたとしても、その内容を確認しておくことは必要です。たとえば、wikilinkが「曖昧さ回避」ページにリンクしていることはよくあることです。この場合、Wikidataへの関連付けが適切になされていないことになります。そこで、OpenRefineの、照合された列に基づき新たな列を作る機能を用いて簡単に確認する方法を紹介します。この方法は、確認したい値が含まれている列名の左隣りに表示されている逆三角形のアイコンをクリックして行います。ここでは例として、「City」列を対象にします。アイコンをクリックして表示されるプルダウンメニューの、「Edit column」を選択し、さらに表示されるプルダウンメニューの、「Add columns from reconciled values...」を選択します。
![3_LOD_WS_SS9.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/aae89f94-3a72-4e54-bfea-9df457c5d4f6.jpeg)
続いて表示されるウィンドウ内の「Add Property」の下にある欄に「instance of」と入力します。補完機能が働くので途中まで入力すると候補が表示されるので、そこから選択することもできます。
![3_LOD_WS_SS10.png](https://qiita-image-store.s3.amazonaws.com/0/119205/2877d320-6809-d72a-1820-165f8b9d2756.png)
すると、「City」列のそれぞれの値に対して自動的に照合されたWikidataの項目が属するクラスが表示されます。例えば、最初の行に含まれる「Algiers」はWikidataにおいて「capital」クラスであることが分かります。このため、この照合は妥当であると判断できます。その他の値についても行うために、左下の「OK」をクリックして、「City」列の右隣に新たな列「instance of」を生成します。なお、確認作業を終えたら、生成した列「instance of」を削除しておきます。これは次の整形作業を行うさいに生じる問題を回避するためです。列を削除するには、削除対象の列名右側の逆三角形アイコンをクリックして表示されるプルダウンメニューの「Edit column」を選択し、さらに表示されるプルダウンメニューの「Remove this column」を選択します。
![3_LOD_WS_SS12.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/7262f681-fcb2-2c9f-3134-cd7730e2a408.jpeg)

## データを整形する

ここでは例として、「Annual Ridership (millions)」列の値をWikidataに入力するために必要な整形方法を紹介します。この列には`28.4 (2016)`という具合に、特定の年における利用者数が百万人の単位で記述されています。ここから利用者数の`28.4`とその数値が得られた年である`2016`を分ける作業をします。これは正規表現を用いて行います。ざっとこの列の値を見ることで、大体次のような形式であることが分かります。すなわち、数字と小数点から成る値に続いて空白があり、その次は開き括弧、そして西暦が来て最後に閉じ括弧という形式です。これを正規表現で表すと、`[\d.]+ \(\d{4}\)`と書けるでしょう。ただ、この正規表現を最初から書ける必要はありません。当該列で「Text filter」を作り、試行錯誤しながら所望の正規表現を構築できるからです。列名「Annual Ridership (millions)」の左側にある逆三角形のアイコンをクリックして表示されるプルダウンメニュー中の「Text filter」を選択します。すると左側のペーンにそのための欄が表示されます。
![3_LOD_WS_SS13.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/0040d2fb-7241-1bc6-4542-6bad5a847269.jpeg)
正規表現でのフィルタを作るために、欄の右下にある「regular expression」をチェックします。その後、適宜欄内に正規表現を記述することで、フィルタが動作してその結果が反映されます。また、欄の右上にある「invert」を選択することで、記入した正規表現にマッチしない値だけを表示させることできます。
![3_LOD_WS_SS14.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/bba62ec7-0b15-59bd-d508-3799f3867d3a.jpeg)
正規表現にマッチしない値を確認すると、値が提供されておらず空欄であるものと、参照元が見当たらないものがあります。今回はそれらをWikidataに挿入する対象から外すことにします。以上で、対象データを抽出するための正規表現が得られたので、続いて、それを当初の目的である、利用者数と利用年を分けるために利用します。正規表現のグループを作り、抽出部分を特定します。すなわち、`([\d.]+) \((\d{4})\)`とします。最初の括弧で利用者数を、次の括弧で利用年を抽出します。そして、それぞれの列を追加します。先と同様に、列名「Annual Ridership (millions)」の左側にある逆三角形のアイコンをクリックして表示されるプルダウンメニュー中の「Edit column」を選択し、さらに表示されるプルダウンメニューの「Add column based on this column」を選択します。そこで表示されるウィンドウ中にある「Language」を「Python / Jython」にします。
![3_LOD_WS_SS15.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/2b389b52-be34-7b8d-4856-cf957d22204e.jpeg)
そして「Expression」の欄に以下のコードを記入します。

```python
import re # 正規表現モジュールをインポートします。
match = re.search(r'([\d.]+) \((\d{4})\)', value) # 正規表現へのマッチを行います。
return match.group(1) # 上記でマッチした文字列のうち、最初の括弧でくくられた部分を取り出します。
```
「New column name」に「利用者数」など適宜新規の列名を入力して「OK」をクリックします。続いて利用年を抽出するように繰り返します。すなわち、上記コードの最後の行を`return match.group(2)`とし、列名を「利用年」などとします。最後に、利用者数が現状では百万人単位なので、これを一人単位に変換します。これを簡単に行うには、列名「利用者数」の左隣にある逆三角形のアイコンをクリックして表示されるプルダウンメニューの「Edit cells」を選択し、さらに表示されるプルダウンメニューの「Transform...」を選択します。表示されるウィンドウの「Expression」欄を`return value+"e6"`として「OK」をクリックします。
![3_LOD_WS_SS16.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/a723e02f-73ec-8974-3b78-2cee1b2e1c16.jpeg)

## スキーマを作る

データの整形を終えたので次はWikidataのスキーマを作ります。まず最初にどのプロパティを使うかを決めます。例として、[アルジェの地下鉄（Q728045）](https://www.wikidata.org/wiki/Q728045)を確認し、利用者数を示すプロパティ「ridership」についての値を追加することにします。Wikidataは「[patronage（P3872）](https://www.wikidata.org/wiki/Property:P3872)」を提案します。当該プロパティについて調べると、これを利用することが妥当と判断できます。そしてこのプロパティの使い方として「[point in time（P585）](https://www.wikidata.org/wiki/Property:P585)」修飾子を用いて、プロパティ値が得られたカレンダー年を含めることが提案されています。

それでは実際にスキーマを構築していきます。OpenRefineの右上にある「Extensions」の右隣にある「Wikidata」をクリックして表示されるプルダウンメニューで「Edit Wikidata schema」を選択します。
![3_LOD_WS_SS17.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/7a9bf13a-63c5-e60a-1bcd-2e2b9f5da633.jpeg)
するとWikidataに投稿するために必要なスキーマを構築するためのページが表示されます。
![3_LOD_WS_SS18.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/93243cb3-8e48-f60e-485b-ee95d4b478eb.jpeg)
右上に表示されている「+ add item」をクリックすると、Wikidataの各項目を選択して表示されるページと同様の体裁で、OpenRefineで得られている値を流し込むためのスキーマを構築できるようになります。
![3_LOD_WS_SS19.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/e494686f-0c10-36f2-c4d6-ef975cff23ee.jpeg)
Wikidataの項目名に該当するのは「Name」列の値なので、「Name」と書かれている部分を「type item or drag reconciled column here」の部分にドラッグアンドドロップします。
![3_LOD_WS_SS20.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/e5643320-12db-b194-f6c8-9177383e2177.jpeg)
すると、ドラッグアンドドロップした所が「Name」に変わります。続いて、右側にある「+ add statement」をクリックします。すると。「Statements」の直下に新たに「property」と書かれた入力欄が表示されます。そこに、上述の通り、利用者数を示す「patronage」と入力します。この欄も補完機能が働くので、最後まで入力しなくても所望のプロパティがプルダウンメニューに表示されるでしょう。
![3_LOD_WS_SS21.png](https://qiita-image-store.s3.amazonaws.com/0/119205/2dde3df4-522a-fe31-96d0-f54c6d70260c.png)
「patronage」を選択すると、プロパティ値として入力されるべき「amount」と「unit」と表示された欄が現れます。「Name」同様に、先ほど整形して生成した列の名前「利用者数」を「amount」部分にドラッグアンドドロップします。「unit」はそのままにして、続いて右側に表示されている「+ add qualifier」をクリックします。すると、「property」と書かれた欄が新たに出現します。ここには「point in time」と記入します。
![3_LOD_WS_SS22.png](https://qiita-image-store.s3.amazonaws.com/0/119205/057306de-cadf-d95b-b918-cf16585ede28.png)
記入欄の直下に表示されるプルダウンメニューの「point in time」を選択すると、また新たに右側に欄が出現するので、そこには、先ほど整形して得られた列の名前「利用年」をドラッグアンドドロップします。
![3_LOD_WS_SS23.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/56e59963-b029-ec99-b1e1-1b841ecab3a5.jpeg)
その次は参照元の入力です。右側に表示されている「+ add reference」をクリックします。改めて現れる「property」欄には「reference URL」と入力し、直下に現れるそれを選択します。続いて現れた欄には列名「Column6」をドラッグアンドドロップします。さらに、「+ add」をクリックし、今度は「property」欄を同様の方法で「Wikimedia import URL」（P4656）とします。右に現れる欄には、データの取得元のWikipedia記事のURLを記入しますが、Wikipediaの記事は随時書き換えられるので、取得時の版へのパーマリンクを記入することが望まれます。そこで、取得元のWikipedia記事のページにおいて左側のペーンに表示されている「Permanent link」のリンク先URLを取得します。
![3_LOD_WS_SS24.jpg](https://qiita-image-store.s3.amazonaws.com/0/119205/fec96bcb-59ad-1938-249e-f5880d0030bb.jpeg)
ここで得られたURLを、先ほどのOpenRefineのスキーマ構築ページにおける「Wikimedia import URL」プロパティのプロパティ値とします。最後に改めて「+ add」をクリックして「retrieved」プロパティ（P813）とし、その値を、対象データを取得した日にちとします。
![3_LOD_WS_SS25.png](https://qiita-image-store.s3.amazonaws.com/0/119205/220a0b08-557f-1d6a-7dde-917d6557a829.png)
以上で利用者数に関するスキーマが構築されました。同様の方法で他の列の値を用いたプロパティを追加できます。例えば、追加できるプロパティとして、開通した日を示す[date of official opening (P1619)](https://www.wikidata.org/wiki/Property:P1619)があるでしょう。ここで構築したスキーマに基づき、OpenRefine内のデータをWikidataに一気にデータを流し込むことができます。

## Wikidataを編集する

取得して整形したデータを、上述の方法で構築したスキーマに基づいてWikidataを編集するには、OpenRefine右上の「Wikidata」をクリックして表示されるプルダウンメニューの「Upload edits to Wikidata」を選択します。選択して表示されるウィンドウで利用者名とパスワードを入力すると、「Upload edits to Wikidata」というウィンドウが現れます。「No issue was detected in your edits.」と表示されていれば、右下の「Upload edits」をクリックします。しばらくすると編集が完了します。Wikidataの該当ページにアクセスすると、自身のOpenRefineによる編集結果が反映されていることを確認できます。

資料は以上になります。ぜひ自身の関心のある分野でWikidataを充実させてください。