OpenKEを用いて知識グラフ補完を行ってみた

OpenKEというオープンソースのフレームワークを用いて知識グラフ補完を行いました。
自分用のメモとして、その結果を文字に起こしておこうと思います。

## 記事の流れ

1. [本記事の対象](https://qiita.com/yuta0919/private/b49b5a8120bd3336d1d3#%E6%9C%AC%E8%A8%98%E4%BA%8B%E3%81%AE%E5%AF%BE%E8%B1%A1)
2. [知識グラフとは](https://qiita.com/yuta0919/private/b49b5a8120bd3336d1d3#%E7%9F%A5%E8%AD%98%E3%82%B0%E3%83%A9%E3%83%95%E3%81%A8%E3%81%AF)
3. [OpenKEとは](https://qiita.com/yuta0919/private/b49b5a8120bd3336d1d3#openke%E3%81%A8%E3%81%AF)
4. [使用するプログラム](https://qiita.com/yuta0919/private/b49b5a8120bd3336d1d3#%E5%AE%9F%E8%A1%8C%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AE%E4%BD%9C%E6%88%90)
5. [実行結果](https://qiita.com/yuta0919/private/b49b5a8120bd3336d1d3#%E5%AE%9F%E8%A1%8C%E7%B5%90%E6%9E%9C)
6. [GitHubとの比較・評価](https://qiita.com/yuta0919/private/b49b5a8120bd3336d1d3#%E8%AB%96%E6%96%87%E3%81%A8%E3%81%AE%E6%AF%94%E8%BC%83%E8%A9%95%E4%BE%A1)
7. [まとめ](https://qiita.com/yuta0919/private/b49b5a8120bd3336d1d3#%E3%81%BE%E3%81%A8%E3%82%81)


## 本記事の対象
以下のいずれかに該当する人が本記事の対象となります。

 - 知識グラフについて興味がある人
 - pythonでできることを知りたい人
 - OpenKEを使ってみたい人

## 知識グラフとは
知識グラフは様々な知識の繋がりを構造として表したものになります。

**例)**
(obama, born-in, Hawaii)

のような主語(subject), 関係(the form of relations), 目的語(object)の関係をもつデータを知識グラフと言います。

主語(subject), 関係(the form of relations), 目的語(object)それぞれを$s, r, o$とおいた場合、$s$ と $r$ もしくは $o$ と $r$ の関係から残った $o, s$ を推測することが今回の目的となります。


## OpenKEとは
OpenKEは[欢迎来到清华大学自然语言处理与社会人文计算实验室(THUNLP)](http://nlp.csai.tsinghua.edu.cn/site2/index.php/zh)が作成したオープンソースのフレームワークです。

C++とpythonで作成されている知識グラフ専用のフレームワークで、現在はpytorchとtensorflowに対応しているようです。

詳しくは以下のgithubのリンクもしくはOpenKEのホームページを参照してください。
[OpenKEのホームページ](http://139.129.163.161//)
[OpenKEのgithub](https://github.com/thunlp/OpenKE)




## 使用するプログラム

次に実際に実行するプログラムを以下に示します。
今回はexamples内のtrain_distmult_WN18.pyを用います。

```python
import openke
from openke.config import Trainer, Tester
from openke.module.model import DistMult
from openke.module.loss import SoftplusLoss
from openke.module.strategy import NegativeSampling
from openke.data import TrainDataLoader, TestDataLoader

# dataloader for training
train_dataloader = TrainDataLoader(
	in_path = "./benchmarks/WN18RR/",
	nbatches = 100,
	threads = 8,
	sampling_mode = "normal",
	bern_flag = 1,
	filter_flag = 1,
	neg_ent = 25,
	neg_rel = 0
)

# dataloader for test
test_dataloader = TestDataLoader("./benchmarks/WN18RR/", "link")

# define the model
distmult = DistMult(
	ent_tot = train_dataloader.get_ent_tot(),
	rel_tot = train_dataloader.get_rel_tot(),
	dim = 200
)

# define the loss function
model = NegativeSampling(
	model = distmult,
	loss = SoftplusLoss(),
	batch_size = train_dataloader.get_batch_size(),
	regul_rate = 1.0
)


# train the model
trainer = Trainer(model = model, data_loader = train_dataloader, train_times = 2000, alpha = 0.5, use_gpu = True, opt_method = "adagrad")
trainer.run()
distmult.save_checkpoint('./checkpoint/distmult.ckpt')

# test the model
distmult.load_checkpoint('./checkpoint/distmult.ckpt')
tester = Tester(model = distmult, data_loader = test_dataloader, use_gpu = True)
tester.run_link_prediction(type_constrain = False)
```

test_dataloaderは"./benchmarks/WN18RR/"
modelはdistmult
loss関数はSoftplusLoss()
にしておきます。
dimは200という形に設定されています。
全て、ダウンロードした時の値そのままです。

examples内に他にも複数種類の実行プログラムがあります。




### 設定に関して

データセット、モデル、ロスの3つが変更できる部分がになります。

train_dataloaderとtest_dataloaderの"./benchmarks/WN18RR/"は同じものにしてください。
このbenchmarksには以下のリンク内のデータセットを使用できます。
[benchmarks](https://github.com/thunlp/OpenKE/tree/OpenKE-PyTorch/benchmarks)

TrainDataLoaderの中の変数は自由に変えることができます。sampling_modeにはnomalの他にcrossが選択できます。（cross設定はより深い設定を少し変えないといけない場合があります。）

モデルは以下のリンクを参照していただければと思います。
[使用可能モデル](https://github.com/thunlp/OpenKE#models)

ロスにはSoftplusLossの他にMarginLossとSigmoidLossを用いることができます。







## 実行結果
実行結果は以下のようになりました。私はGPUマシンを持っていないためgoogle colaboratoryで実行しました。
![スクリーンショット 2020-05-27 19.13.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641537/2d227a10-0f48-4975-e75c-e07871b435aa.png)




## GitHubとの比較・評価
GitHubにあるExperimentsの表と比較していきます。表はHits@10(filter)の時の値のようです。
![スクリーンショット 2020-05-28 13.14.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641537/94e86668-ca64-5624-7d19-77def19cf7ca.png)

実験結果では平均0.463306となったので精度はGitHubにあるDistMultの値より0.015ほど低くなってしまいました。

改善点としては、他のloss関数を採用するということが挙げられます。
また、neg_entやneg_rel, alphaの値を変化させてみるというのも一つの手だと思います。

 

## まとめ
今回はOpenKEを用いて知識グラフ補完を行ってみました。
結果としては期待する結果を得ることはできませんでしたが、改善の余地がみられたため上記で示した改善点に着手していければと考えています。

最後まで読んでいただきありがとうございました。