wikidata
重要情報
wikidata query serviceに対してsparqlを呼ぶよりも、wikidataのdumpをダウンロードしてwikibase-dump-filter使ったほうがお得
しかしdumpが巨大すぎてwikibase-dump-filterは数時間掛かる……
2021/4/18 17:10
wikidata-sdkを使ってみる
code:js
const WBK = require('wikibase-sdk');
const wdk = WBK({
instance: 'https://www.wikidata.org',
sparqlEndpoint: 'https://query.wikidata.org/sparql'
});
const fetch = require('node-fetch');
const url = wdk.getEntities({
ids:'P580', 'Q41655079', 'Q232595', 'Q41654707',
languages: 'ja',
props: 'labels', 'descriptions'
});
fetch(url)
.then(response => response.json())
.then(wdk.parse.wb.entities)
.then(entities => {
console.log(entities)
})
これは便利っぽい
どういう実装にするのか、戦略を練る
ndjsonをcatで標準入力から受け取る
改行区切りで処理する
一行入力されてきたという前提で↓のPとQを探す方法を実装してみる
https://www.npmjs.com/package/@moneyforward/stream-util
これがよさそうなので使ってみる
できた 2021/4/18 19:05
https://gist.github.com/yuiseki/3ec513ad1df755c67630376ddc31500e
2021/4/18 16:48
propertyを日本語にする
claimsからpropertyを探す
root/claims/P0000/[@]/mainsnak/property
qualifiersを日本語にする
root/claims/P0000/[@]/mainsnak/datatypeがwikibase-itemのとき
root/claims/P0000/[@]/mainsnak/datavalue/value/id
qualifiersをunixtimeにする
root/claims/P0000/[@]/qualifiers/P1111/[@]/datatypeがtimeのとき
root/claims/P0000/[@]/qualifiers/P1111/[@]/datavalue/value/time
2021/4/18 16:15
wd props -l ja P31 | jq -r 'to_entries[] | select(.key == "P31") | .value'
でP31が「分類」であることがわかる
wd label -l ja Q5
でQ5が「ヒト」であることがわかる
ndjsonのデータ構造
code:ndjson.ts
type LangToValue = {
lang-code: {
language: string;
value: string;
};
}
type Reference: any;
type Snak = {
snaktype: string;
property: string;
datatype: string;
datavalue: {
value: {
entity-type?: string;
numeric-id?: number;
id?: string;
time?: string;
timezone?: number;
before?: number;
after?: number;
precision?: number;
calendarmodel? string;
}
type: string;
}
}
type MainSnak = {
mainsnak: Snak;
type: string;
id: string;
rank: string;
references: Array<Reference>;
qualifiers:
}
type Claim = {
prop-id: Array<MainSnak>
}
type WikidataNDJSON = {
type: string;
id: string;
labels: LangToValue;
descriptions: LangToValue;
aliases: LangToValue;
claims: Array<Claim>
}
2021/4/17 17:56
elastic-wikidataは参考にはなるがあまり使い物にはならない
Q232595みたいな値がElasticsearchに入っていてもどうしようもない
時刻情報がElasticsearchで扱える時刻型になっていない気もする
wikidata-cliとjqを使えばPとかQとかの値を求める自然言語にできることはわかった
wikibase-dump-filterで生成したdumpのPとかQとかをwikidata-cliで日本語に解決してElasticsearchにつっこみたい
ToDo
wikibase-dump-filterで生成したdumpのPとかQとかをwikidata-cliで日本語に解決してJSONフィールドに追加する
適切なキャッシュ戦略が必要
elastic-wikidataを作り直す
上記で構築したJSONをElasticsearchに突っ込めるようにする
すべでのフィールドを投入できるようにするべき
時刻情報を適切に扱えるようにするべき
おなじIDのドキュメントは上書きするようにするべき
2021/4/17 16:35
wikidataのPとかQとか意味わからん
シェル芸で良い感じにしたい
理想
code:sh
cat humans.ndjson | wikibase-dump-filter -l ja --claim '国籍:日本&職業:政治家&~死亡年月日' > politicians_japan.ndjson
claimの部分だけ、wikidata-cliを使って生成したら良さそう
code:bash
cat humans.ndjson | wikibase-dump-filter --claim ./wdfc.sh 国籍:日本&職業:政治家&~死亡年月日 > politicians_japan.ndjson
とりあえずできた
https://gist.github.com/yuiseki/ca02942c588912815880f358568707a9
要点
wd props -l ja 国籍 | jq -r 'to_entries[] | select(.value == "国籍") | .key'
でP0000みたいなのが取れる
wd id -l ja 日本
でQ0000みたいなのが取れる
2021/4/17 16:32
現在生存する政治家だけを抽出したい
wikibase-dump-filterのnot句を使う
P570「死亡年月日」が「存在しない」という条件で抽出
cat humans.ndjson | wikibase-dump-filter --claim 'P27:Q17&P106:Q82955&~P570' > politicians_japan.ndjson
2021/4/17 16:09
できるようになったこと
wikidataのdumpから特定の条件で情報抽出する
日本語からラベルを調べる
ラベルから日本語を調べる
2021/4/17 13:16
wikidataのラベルをいちいち調べるのが大変すぎるのでどうにかしたほうがよさそう
wikidata-cliとwikidata-taxonomyを導入する
npm install -g wikidata-cli
npm install -g wikidata-taxonomy
wd id -l ja 自由民主党でQ232595が得られるようになった
逆に、wd label -l ja Q232595で自由民主党が得られるようになった
https://gyazo.com/e8fabc27ec2ba8eed915c5428d5f2a49
wb props -l ja 国籍でP27が得られる
wb query -o Q232595 -p P102 -a -l jaで自民党所属議員が得られる
wikidata-taxonomyは別にいらなかった…
2021/4/17 11:59
'P27:Q17&P106:Q82955'で日本国籍の職業政治家を抽出できた
このndjsonをElasticsearchにつっこんで検索できるようにしたい
good.icon 適当にElasticsearchとKibanaを立ち上げるdocker-compose.ymlを書く
code:docker-compose.yml
version: '3.7'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.12.0
ports:
- 9200:9200
environment:
discovery.type: single-node
volumes:
- elasticsearch:/usr/share/elasticsearch/data
restart: unless-stopped
networks:
- wikidata
kibana:
image: docker.elastic.co/kibana/kibana:7.12.0
ports:
- 3000:5601
networks:
- wikidata
volumes:
elasticsearch:
driver: local
networks:
wikidata:
name: wikidata
docker-compose up
エラー等が発生せずに動作することを確認する
http://localhost:3000/ にアクセスしたらKibanaが動いていることを確認する
subtle.icon elastic-wikidataでwikidataのndjsonをElasticsearchにつっこむ
https://github.com/TheScienceMuseum/elastic-wikidata
pip install elastic_wikidata
export ELASTICSEARCH_CLUSTER=http://localhost:9200/
ew dump -p politicians_japan.ndjson -lang ja -i elastic-wikidata
エラー無く動いた!
KibanaでElasticsearchのデータを覗いてみる
http://localhost:3000/app/management/kibana/indexPatterns/create
https://gyazo.com/2b006e164227b6f1488310c3d25c525f
フィールドが少なすぎるぞ…?
wikibase-dump-filterで出力されたndjsonを確認する
tail -n 1 dumps/politicians_japan.ndjson | jq
めっちゃ大量にプロパティある
ewコマンドで取り込むプロパティを指定しないといけないっぽいな
プロパティを目で採取するのは面倒なのでjq使う
tail -n 1 dumps/politicians_japan.ndjson | jq '.claims | keys'
念の為別の行も確認してみる
head -n 1 dumps/politicians_japan.ndjson | jq '.claims | keys'
全然違うプロパティ持ってるやんけ………
https://gyazo.com/7eb31a426ce55b87b0aaa12410daaa0e
政治家を分析する上で必要なプロパティを理解するしか無いっぽい
good.icon wikidataのページを睨んで必要そうなプロパティを列挙した
ew dump -p dumps/politicians_japan.ndjson -prop P31,P21,P27,P569,P19,P22,P26,P39,P69,P102,P106,P3602,P1559 -lang ja -i elastic-wikidata
Q232595で検索することで自民党の政治家一覧を得られるようになった
https://gyazo.com/4da0b5df39c5c24a9d8ccb8ca2431c7b
Q20983100で検索すれば2017年の衆議院議員選挙の候補者一覧が得られる
2021/4/17 10:52
64GBのhumans.ndjsonから日本の国会議員・地方議会議員を抽出したい
bad.icon P39:Q17(公職、日本)かつP39:Q11997597(公職、代議士)を抽出してみる
cat humans.ndjson | wikibase-dump-filter --claim 'P39:Q17&P39:Q11997597' > politicians.ndjson
出力0件
P31でフィルタリングした時点でP39は含まれていないのか?
bad.icon 元のdumpから抽出しなおす
cat latest-all.json.bz2 | bzcat | wikibase-dump-filter --claim 'P39:Q17' > P39_Q17.ndjson
P39:Q17ではまったくヒットしない
P39のデータ構造的にQ17を持っていないのではないか
good.icon humans.ndjsonの意味を調べる
P31は「instance of」
Q5は「human」
実際の人物のwikidataを見てみる
https://www.wikidata.org/wiki/Q122465
日本人かどうか分かる部分は、
「country of citizenship」
つまり「国籍」「日本」で絞り込む必要があるのではないか
国籍はP27
https://www.wikidata.org/wiki/Property:P27
日本はQ17
https://www.wikidata.org/wiki/Q17
なのでP27:Q17と指定すればよいはず
cat humans.ndjson | wikibase-dump-filter --claim 'P27:Q17' > humans_japan.ndjson
動いた!
good.icon 「日本国籍かつ職業政治家」で絞り込みたい
職業はP106
https://www.wikidata.org/wiki/Property:P106
政治家はQ82955
https://www.wikidata.org/wiki/Q82955
cat humans.ndjson | wikibase-dump-filter --claim 'P27:Q17&P106:Q82955' > politicians_japan.ndjson
これでどうか
動いた!
2021/4/16 20:09
wikidataのdumpを取得できた
wget https://dumps.wikimedia.org/wikidatawiki/entities/latest-all.json.bz2
3:50かかった
とりあえず、日本の議員だけを抽出したい
https://github.com/maxlath/wikibase-dump-filter
npm install -g wikibase-dump-filter
とりあえず、README通りのコマンドを打ってみる
cat latest-all.json.bz2 | bzcat | wikibase-dump-filter --claim P31:Q5 > humans.ndjson
えぐい時間掛かる
https://gyazo.com/adf64fad0a0e59373d8d107a7b60ee38
progress出力がわかりやすいのでまだ良心的
7:14かかった
64GBのhumans.ndjsonができた
--claimに指定する値の意味を知る必要が有りそうだ
https://github.com/maxlath/wikibase-dump-filter/blob/master/docs/cli.md#by-claims
先人がいた
https://qiita.com/takahashim/items/63b301ba88207ee20bfe
公職はP39
https://www.wikidata.org/wiki/Property:P39
日本はQ17
https://www.wikidata.org/wiki/Q17
議会議員Q14761450というのがあるがこれは国会議員と地方議会議員を包括しているんだろうか??
https://www.wikidata.org/wiki/Q14761450
代議士Q11997597というのがあった
https://www.wikidata.org/wiki/Q11997597
公職かつ日本かつ代議士であれば、日本の国会議員または地方議会議員だろう(本当に?)
2021/4/16 朝 wikidataのデータを扱う方法を調べる
2021/4/16 09:15 いろいろ眺めた感想としては
wikidataのdumpでかすぎ
https://qiita.com/CivFractal/items/e3a6b0274428cf96f3a5
https://dumps.wikimedia.org/wikidatawiki/entities/latest-all.json.bz2 は65GBある
wikibase-dockerを使えば自前でwikidata query serviceを立ち上げられてrate limitを回避できる
ものすごく強力なマシンが必要でお金が掛かる
elastic-wikidataを使えばwikidata query serviceのapi limitを回避できる
wikidataのdumpをそのままつっこむとえらいことになりそう
wikibase-dump-filterを使えばwikidataのdumpを必要な分だけフィルタリングしたdumpを作れる
dumpをwikibase-dump-filterで必要な分だけフィルタリングしてelastic-wikidataをつかってElasticsearchに入れるのがよさそうだ
nodejsで作られているwikibase-sdk, wikibase-cli, wikibase-dump-filter等は同じ作者が継続的にメンテナンスしていて良さそう
wikidata公式dumpとデータ構造
dump
https://www.wikidata.org/wiki/Wikidata:Database_download/ja
https://dumps.wikimedia.org/wikidatawiki/entities/
json dumpのデータ構造
https://doc.wikimedia.org/Wikibase/master/php/md_docs_topics_json.html
wikidataのデータ構造
https://www.mediawiki.org/wiki/Wikibase/DataModel
https://www.mediawiki.org/wiki/Wikibase/DataModel/Primer
wikidata query service
https://query.wikidata.org/
https://www.wikidata.org/wiki/Wikidata:SPARQL_query_service/ja
https://www.mediawiki.org/wiki/Wikidata_Query_Service/User_Manual/ja
https://www.wikidata.org/wiki/Wikidata:SPARQL_tutorial/ja
api limit
1分以上掛かるクエリはタイムアウトする
同一IPからの並列リクエストは5件まで
2021/4/16 08:34 ライブラリ・ツール調査
https://www.wikidata.org/wiki/Wikidata:Tools/For_programmers/ja
Javaとか.NETとかRは除外した
データ収集が目的なので、更新(編集)用ツール・ライブラリは除外した
以下、最終メンテが近い順
https://github.com/LeMyst/WikibaseIntegrator
wikibaseのPythonライブラリ
Python
最終メンテ八時間前
https://github.com/andrewtavis/wikirepo
wikidataのPythonライブラリ
Python
最終メンテ二日前
https://github.com/maxlath/wikibase-sdk
wikidataのJavascriptライブラリ
Javascript
最終メンテ四日前
https://github.com/maxlath/wikibase-cli
wikibaseのAPIをコマンドラインで呼ぶツール、wikidataにも対応
Javascript
最終メンテ六日前
https://github.com/maxlath/wikibase-dump-filter
wikidataのJSON dumpをfilterできるツール
Javascript
最終メンテ二ヶ月前
https://github.com/wmde/wikibase-docker
wikidata query serviceを自前で立ち上げられるDockerコンテナ
Shellscript
最終メンテ三ヶ月前
利用例
https://addshore.com/2019/10/your-own-wikidata-query-service-with-no-limits/
https://github.com/TheScienceMuseum/elastic-wikidata
wikidataのデータをelasticsearchに取り込むツール
Python
最終メンテ四ヶ月前
https://github.com/dahlia/wikidata
wikidataのPythonライブラリ
Python
最終メンテ八ヶ月前
https://github.com/nichtich/wikidata-taxonomy
wikidataの分類体系を取得するコマンドラインツール
Javascript
最終メンテ二年前
https://github.com/kensho-technologies/qwikidata
wikidataのpythonライブラリ
Python
最終メンテ二年前
https://qwikidata.readthedocs.io/en/stable/readme.html
https://github.com/nichtich/wdq
wikidataのquery serviceをコマンドラインで呼ぶツール
Perl
最終メンテ五年前