# -*- coding: utf-8 -*-
"""
Created on Wed Aug  8 11:23:24 2018

@author: YosiYoshi

東方カップリングの階層表現学習におけるPoincaré Embeddingsの応用
Poincaré Embeddings for Learning Hierarchical Representations of Touhou Coupling 

@Yosiyoshi: 南秘

KW: Touhou Project, Poincaré Embeddings, Hierarchical Representations, Machine Learning

東方projectのキャラクターは公式設定、および二次創作によりカップリングが複数存在する。
[M Nickel and D Kiela, 2017]による
"Poincaré Embeddings for Learning Hierarchical Representations"
の触発を受け、Poincaré Embeddingsを東方カップリングの階層表現学習に応用した。

・実験方法
[Niconico大百科, 2018]の"東方projectのカップリング一覧:キャラクター別"
http://dic.nicovideo.jp/a/%E6%9D%B1%E6%96%B9project%E3%81%AE%E3%82%AB%E3%83%83%E3%83%97%E3%83%AA%E3%83%B3%E3%82%B0%E4%B8%80%E8%A6%A7
より、n=['博麗霊夢','霧雨魔理沙','東風谷早苗','アリス・マーガトロイド']の四名に係るカップリングを
任意に抽出した。カップリング相手をm=[任意の文字列]とし、カップリングをdata=(n,m)と定義する。

dataをgensim.models.poincare.PoincareModelに入力し、epoch=50で学習する。
学習結果はPoincaré双曲面上にプロットされる。

・結果
れいまりの距離: 0.9867836799596653
まりありの距離: 1.193140088539443
れいありの距離: 1.33561024791922
れいれみの距離: 0.8767354255212357
れいさとの距離: 0.5425000174999931
まりれみの距離: 0.22278990408263546
まりさとの距離: 0.4602781802364823
さなれみの距離: 0.18275833633037145
さなさとの距離: 0.39465960366370423
ありれみの距離: 0.9773531395801837
ありさとの距離: 1.0359620245638737

・結論
上記結果より、れいさと（霊夢・さとり）、まりれみ（魔理沙・レミリア）、まりさと（魔理沙・さとり）、
さなれみ（早苗・レミリア）、さなさと（早苗・さとり）のカップリング両者間における距離
が特に小さい。したがって、レミリア・スカーレットと古明地さとりは上記四名とカップリングにおいて親和的である。
"""

from gensim.models.poincare import PoincareModel, PoincareRelations
from gensim.test.utils import datapath

data = [('れいむ', 'まりさ'), ('れいむ', 'ルーミア'), ('れいむ', 'チルノ'), ('れいむ', 'めーりん'),
        ('れいむ', 'さくや'), ('れいむ', 'レミィ'), ('れいむ', 'パチェ'), ('れいむ', 'フラン'),
        ('れいむ', 'レティ'), ('れいむ', 'アリス'), ('れいむ', 'ルナサ'), ('れいむ', 'ゆゆこ'),
        ('れいむ', 'ゆかり'), ('れいむ', 'えーりん'), ('れいむ', 'ぐーや'), ('れいむ', 'もこう'), 
        ('れいむ', 'すいか'), ('れいむ', 'あやや'), ('れいむ', 'ゆーかりん'), ('れいむ', 'もみじ'),
        ('れいむ', 'さなえ'), ('れいむ', 'すわこ'), ('れいむ', 'てんこ'), ('れいむ', 'ヤマメ'),
        ('れいむ', 'さとり'), ('れいむ', 'おりん'), ('れいむ', 'こいし'), ('れいむ', '三月精'),
        ('れいむ', 'せいが'), ('れいむ', 'みこ'), ('まりさ', 'ルーミア'), ('まりさ', 'チルノ'),
        ('まりさ', 'めーりん'), ('まりさ', 'こあ'), ('まりさ', 'ぱちぇ'), ('まりさ', 'さくや'),
        ('まりさ', 'レミィ'), ('まりさ', 'フラン'), ('まりさ', 'メルラン'), ('まりさ', 'みょん'),
        ('まりさ', 'ゆかり'), ('まりさ', 'けーね'), ('まりさ', 'てゐ'), ('まりさ', 'うどんげ'),
        ('まりさ', 'ぐーや'), ('まりさ', 'すいか'), ('まりさ', 'あやや'), ('まりさ', 'こまち'),
        ('まりさ', 'ヤマザナドゥ'), ('まりさ', 'ゆーかりん'), ('まりさ', 'にとり'), ('まりさ', 'もみ'),
        ('まりさ', 'さなえ'), ('まりさ', 'かなこ'), ('まりさ', 'てんこ'), ('まりさ', 'ヤマメ'),
        ('まりさ', 'パルスィ'), ('まりさ', 'ゆーぎ'), ('まりさ', 'おりん'), ('まりさ', 'おりん'),
        ('まりさ', 'おくう'), ('まりさ', 'こいし'), ('まりさ', 'ナズーリン'), ('まりさ', 'こがさ'),
        ('まりさ', 'ひじりん'), ('まりさ', 'ぬえ'), ('まりさ', '三月精'), ('さなえ', 'チルノ'),
        ('さなえ', 'さくや'), ('さなえ', 'レミィ'), ('さなえ', 'リグル'), ('さなえ', 'けーね'),
        ('さなえ', 'あやや'), ('さなえ', 'しずは'), ('さなえ', 'ひな'), ('さなえ', 'にとり'),
        ('さなえ', 'もみ'), ('さなえ', 'かなこ'), ('さなえ', 'すわこ'), ('さなえ', 'てんこ'),
        ('さなえ', 'キスメ'), ('さなえ', 'さとり'), ('さなえ', 'こいし'), ('さなえ', 'こがさ'),
        ('さなえ', 'ひじり'), ('さなえ', 'ぬえ'), ('さなえ', 'マミゾウ'), ('アリス', 'チルノ'),
        ('アリス', 'めーりん'), ('アリス', 'パチェ'), ('アリス', 'さくや'), ('アリス', 'レミィ'),
        ('アリス', 'フラン'), ('アリス', '上海人形'), ('アリス', 'ゆかり'), ('アリス', 'みすちー'),
        ('アリス', 'もこう'), ('アリス', 'あやや'), ('アリス', 'ヤマザナドゥ'), ('アリス', 'メディスン'),
        ('アリス', 'ゆーかりん'), ('アリス', 'ひな'), ('アリス', 'もみ'), ('アリス', 'さなえ'),
        ('アリス', 'パルスィ'), ('アリス', 'てんこ'), ('アリス', 'ナズーリン'), ('ありす', 'ひじりん')]
model = PoincareModel(data, negative=2, size=2)
model.train(epochs=50)
print("れいまりの距離:", model.kv.distance('れいむ', 'まりさ'))
print("まりありの距離:", model.kv.distance('まりさ', 'アリス'))
print("れいありの距離:", model.kv.distance('れいむ', 'アリス'))
print("れいれみの距離:", model.kv.distance('れいむ', 'レミィ'))
print("れいさとの距離:", model.kv.distance('れいむ', 'さとり'))
print("まりれみの距離:", model.kv.distance('まりさ', 'レミィ'))
print("まりさとの距離:", model.kv.distance('まりさ', 'さとり'))
print("さなれみの距離:", model.kv.distance('さなえ', 'レミィ'))
print("さなさとの距離:", model.kv.distance('さなえ', 'さとり'))
print("ありれみの距離:", model.kv.distance('アリス', 'レミィ'))
print("ありさとの距離:", model.kv.distance('アリス', 'さとり'))
