pythonと英語版wordnetで類似度、類義語(対義語)検索してみた

#経緯
単語間の類似度を測るにあたって自然言語処理の勉強をしていました。その際に読んでいた”自然言語処理の基礎”という本にwordnetというものを知ったので、これを使って単語間の類似度を求めてみようと思いました。

しかし、ネットで「wordnet　類義語」とか調べても日本語版wordnetのqiitaの記事ばかりで英語版を書いてる人がすくなかったです。そこで初の投稿をしてみようと思いました。

((え、記事がない＝需要がない？


[自然言語処理の基礎のamazonリンク](https://www.amazon.co.jp/%E8%87%AA%E7%84%B6%E8%A8%80%E8%AA%9E%E5%87%A6%E7%90%86%E3%81%AE%E5%9F%BA%E7%A4%8E-%E5%A5%A5%E6%9D%91-%E5%AD%A6/dp/4339024511/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2JM4GSH4WB5W2&keywords=%E8%87%AA%E7%84%B6%E8%A8%80%E8%AA%9E%E5%87%A6%E7%90%86%E3%81%AE%E5%9F%BA%E7%A4%8E&qid=1566616376&s=gateway&sprefix=%E8%87%AA%E7%84%B6%E8%A8%80%E8%AA%9E%E5%87%A6%E7%90%86%2Caps%2C367&sr=8-1)
私のwordnetに関する基本的知識はこの本です！

#wordnetとは
[wordnetのホームページ](https://wordnet.princeton.edu/)

wordnetは、シソーラス、概念階層という単語辞書を使って単語間の類似度を出します。

シソーラスは、似ている単語同士は近くに，そうでない単語同士は遠くに位置するような辞書です！

シソーラスはこれ↓
 ![Screenshot from 2019-08-24 13-05-59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486822/b673110f-1f09-49c8-2208-17b21cd20926.png)
引用: http://astamuse.com/ja/published/JP/No/2010129025


さて、これを使ってどうやって類似度を求めるのでしょう？

任意の２つの単語の類似度は、このシソーラスから、２つの単語の共通する単語の深さをもとに計算できます。２つの単語のシソーラス中での根からの深さをそれぞれ、a, b，２つの単語の共通の上位語の根からの深さをｃとすると、

類似度(sim) = (a+b)\\(c✕２)　　(0≦sim≦1)

となります!

###このシソーラスから飛行機と自動車の類似度を求めてみる
概念から飛行機までの足の長さは４、自動車までは５ですね！
![Screenshot from 2019-08-24 13-11-43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486822/dc4babac-c135-7661-4657-8678af2a60c0.png)

これらの２つの単語の共通上位語は乗り物で、そこまでの足の長さは３！

![Screenshot from 2019-08-24 13-06-34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486822/e13741b0-d854-8cc6-8f50-a3765bffa28e.png)

以上より、

類似度(sim) = (4+5)\\(3✕２) = 0.666666...

飛行機と自動車の類似度は0.666...ですのでまあまあ似てるって感じ？

#早速pythonで使ってみよう
環境
python3
ubuntu 18.04

---
基本的な使い方は以下のリンクを参考↓
[WordNet Interface](http://www.nltk.org/howto/wordnet.html)

---
####wordnetのインストール

これを実行すればインストールされると思います
また、データセットの更新もこのコードを実行すればできます

```python:wordnet_installer.py
import nltk
nltk.download("wordnet")
```

####pythonで上の飛行機と自動車の類似度を出してみる

手計算で出した上の0.6666...になればいいけど、、

```python:wordnet_sim.py
from nltk.corpus import wordnet

word = ["plane", "car"]
w1 = wordnet.synset(word[0]+'.n.01')
w2 = wordnet.synset(word[1]+'.n.01')
print(word[0] + "と" + word[1] + "の類似度：" + str(w1.wup_similarity(w2)))
```
結果↓
planeとcarの類似度：0.6666666666666666

いい感じ！

####Happyの類義語と対義語を出してみる

単にwordnetを使って類義語とかだすと、"＿"や"-"を含んだ単語をも出てきてやだったので、これらは省きました。

```python:wordnet_syn_ant.py
from nltk.corpus import wordnet
synonyms = []
antonyms = []

for syn in wordnet.synsets("happy"):
    for l in syn.lemmas():
        if "_" not in l.name() and "-" not in l.name():
            synonyms.append(l.name())
        if l.antonyms():
            antonyms.append(l.antonyms()[0].name())

print("類義語")
print(list(set(synonyms)))
print("対義語")
print(list(set(antonyms)))
```

結果↓
類義語
['glad', 'felicitous', 'happy']
対義語
['unhappy']

felicitous ...?
調べてみたら、”幸運な”って意味らしいのでhappyの類義語として良さそう！

使えそう！

#次回

次回は、英語版word2vecについてや、実際にwordnetを使って、
質疑応答の精度を上げる
入力された文章の類似文章を作る
とかのqiita書きたいです

#参考
https://wordnet.princeton.edu/
http://www.nltk.org/howto/wordnet.html
https://pythonprogramming.net/wordnet-nltk-tutorial/