LoginSignup
239
121

More than 3 years have passed since last update.

【続】AIが三国志を読んだら、孔明が知力100、関羽が武力99、を求められるのか?をガチで考える物語(Word2Vec編)

Last updated at Posted at 2019-08-13

背景

この物語は前編(自然言語処理編)からの続編です。

魏延「前回はどんな話だったかな・・・・?」
魏延「たしか、頭に角が生える話だったな!」
姜維「(いやそれはオマエの見た夢だろ・・・しかも死亡フラグ)」

前回のお話を忘れてしまった方は以下からご覧くだされ!

AIが三国志を読んだら、孔明が知力100、関羽が武力99、
を求められるのか?をガチで考える物語(自然言語処理編)
https://qiita.com/youwht/items/92056e63498c36de4e3b

そして、その魏延の死亡フラグはいきなり当たってしまうのであった!

今回は、Word2Vec によって、
武将名(自然言語)をベクトル化(数値化)するお話。
武将を「数値」で扱うことが出来れば、
その中のどこかの値に、
「武力」「知力」を示す値があるのではないか?
という仮説を検証する。

魏延「わしをベクトルに出来るものはおるか!?」

馬岱 Gensim「ここにいるぞ!」
魏延「ギャアァァァッ」
楊儀「やった、ついに反骨ヤロウを50次元のベクトルにしたぞ!

馬岱のかわりに魏延を切ってくれるのは、
Gensimというライブラリ。
以下のコマンドでインストールしておこう。

gensimのインストール
!pip install gensim 

前回の「自然言語処理編」で作った、
吉川英治三国志の形態素解析結果(名詞動詞を抽出したリスト)に対して、
機械学習を行い、武将を数値表現にする(ベクトル化)

ここで取り扱う機械学習の仕組みとしては、例えば
「関羽」は「劉備」の「義弟」である
「張飛」は「劉備」の「義弟」である
という2つの文章を見た場合、
(形態素解析により単語抽出済みであるため、
 [関羽,劉備,義弟]と[張飛,劉備,義弟]という
 二つの単語リストを入力した場合)
「関羽」と「張飛」だけ入れ替わったデータが存在する、
ということから、
「関羽」と「張飛」は似ている単語だ、
と、機械が学習していくのだ。

「曹操」は「張遼or夏侯惇or許褚」に「命じた」
などのような表現が多数あつまれば、
「張遼」≒「夏侯惇」≒「許褚」と機械が学習するし、
「劉備」は「趙雲」に「命じた」 などの表現と合わせると、
「曹操」≒「劉備」ということも学習していく、というワケ。

一騎当千の武将たち、神算鬼謀の軍師たち、
それぞれ、お互い「似ている」と機械が学習してくれれば、
「その中で ”似ている方向” の最先端にいる人は誰?」
を見れば、武力100、知力100、が分かるのではないか、
というのが本稿最大のアイデアである。

機械学習結果の出力として、各武将(各単語)は、
N次元のベクトルとして表現されることになり、
ベクトル同士の距離が近ければ「似ている」という感じ。

早速、以下のコマンドで実行してみよう!

機械学習:Word2Vecモデルの作成
%%time
#↑実行時間をログに出すためのオマジナイ

# Word2Vecライブラリのロード
from gensim.models import word2vec
import pickle

#ワードリストの復元(自然言語処理編の最後で作成したファイルの読み込み)
with open('drive/My Drive/Sangokusi/Word_list_Sangokusi_AzanaOK_with_userdict_neologd_V4.pickle', 'rb') as f:
    word_list = pickle.load(f)
print(len(word_list))


#機械学習におけるパラメータの設定値
#ここの値の調整が精度に直結している。
size_setting = 50
min_count_setting = 5
window_setting = 6
iter_setting = 4500

# size: 圧縮次元数
# min_count: 出現頻度の低いものをカットする(最低何回出現したら許可するか?)
# window: 前後の単語を拾う際の窓の広さを決める
# iter: 機械学習の繰り返し回数(デフォルト:5)十分学習できていないときにこの値を調整する
# model.wv.most_similarの結果が1に近いものばかりで、
# model.dict['wv']のベクトル値が小さい値ばかりのときは、学習回数が少ないと考えられる。
# その場合、iterの値を大きくして、再度実行したほうが良い

# ★ここで学習の実施。事前準備したword_listを使う
model = word2vec.Word2Vec(word_list, size=size_setting,min_count=min_count_setting,window=window_setting,iter=iter_setting)

# 学習の設定値ごとに、ファイル名を書いて保存しておく
# ※やりすぎてゴミが増えるとディスク容量を圧迫する点は注意
model_sava_file_name = "W2V_V4_"+str(size_setting)+"_"+str(min_count_setting)+"_"+str(window_setting)+"_"+str(iter_setting)+"_model.pickle"
with open('drive/My Drive/Sangokusi/'+model_sava_file_name, 'wb') as f:
    pickle.dump(model, f)

この機械学習の実行は、設定値によっては、
かなり時間がかかるので、司馬懿のようにじっと待つべし
(上記例だと1時間弱くらい)

司馬懿「・・・」
司馬懿「・・・・・」
司馬懿「・・・・・・・」
部下 「孔明に 女物の衣服 まで贈られて、まだ攻めないのですか!?」
司馬懿「・・・・・」
司馬懿「(なぜワシの女装癖がバレたのだろう?孔明恐るべし・・・)」

さあ、司馬懿が女装している間に学習が完了したので
魏延をベクトルにした結果を見てみよう!

結果の確認(魏延編)
#一つ一つの単語はN次元のベクトルとして表現されている。
#もし、各要素の値が0に近いものばかりの場合は学習繰り返し回数の不足
print(model.__dict__['wv']['魏延'])
魏延のベクトル化表示
[ -3.29209     -0.8619167    2.548894    -6.2769666    4.820325
  -4.3188534    4.892581     3.0584764   -1.941075     7.202591
   2.825382     2.6815546   -1.5141411    1.2163684    7.8137026
   5.9709163    4.2522264   -3.750429    -1.2866642   -5.4226913
  -1.1429474    0.74476415   4.2300115    3.1387594    0.60046256
   0.8668483   -5.342602    -1.0369713    1.8684605   -0.29890215
  -6.667386    -1.8291212   -3.2661974   -0.50744665   1.6939703
   1.3792468   -0.2192511  -10.185009    -2.773828     2.1797962
  -2.4290617    1.8001399    5.592892    -9.066986    -2.3023245
   2.6630638   -3.0628533   -4.383273     8.999806    -4.0579867 ]

このように、各武将を
「50次元のベクトル」に変換することが出来た!
魏延の数字をよーく見ると、
「反骨の相」が出ているのが分かる。
(うそ。どんな風向きも東南に変える気象予報士様なら分かるのかもしれない)

じゃあ、どうやってこの数字の羅列を使うんだよ!?

全部の「単語(武将)」が数値化されているということは、
その数値同士の距離を比較したり、計算したりが出来るということ。

治世の能臣、乱世の奸雄に比肩する英雄は誰?

曹操「天下の英雄、と言えば誰であろうか?」
劉備「河北の袁紹、淮南の袁術、呉の孫策、荊州の劉表、益州の劉璋・・・」
曹操「そいつらは英雄とは言えないな」
劉備「じゃあ誰だというのですか?」
曹操「オレとオマエだ(ハート)
劉備「(ポッ)

この後カミナリに邪魔されなければ、
梅園で彼らのラヴロマンスが始まりそうなところではあるが、
ここで無情にも「曹操」に類似する単語を、
出来たばかりの機械学習結果を使って調べてみよう。

三国志演戯中の全単語(名詞と動詞)がベクトルになっているため、
指定した単語ベクトルに最も近い(コサイン類似度が大きい)単語を
調べる関数を実行する。果たして「劉備」は出てくるのか・・・?

曹操と似た単語を調べる
# 関数most_similarを使って「曹操」の類似単語を調べる 
print("--曹操--")
ret = model.wv.most_similar(positive=['曹操']) 
for item in ret:
    print(str(item[0]), str(item[1]))
曹操と​似ている単語の結果表示
袁紹 0.7524725794792175
賈詡 0.6547679901123047
呂布 0.6256376504898071
袁譚 0.6161890029907227
袁術 0.6136394739151001
陳宮 0.5922695994377136
董卓 0.5671449303627014
公孫瓚 0.5582242608070374
魏王 0.5288677215576172
劉表 0.5284026861190796

後ろにある数字は、いわば「似ている度合い」を表す。
結果は、「袁紹」がぶっちぎりの一位であった。
(こっそり「魏王」が入っているのが良い。
 「武将名」に限定せず一般名詞系も含むため、
 魏王などの結果が出てくる場合もある)

残念!曹操様は劉備よりも、
「袁紹」「呂布」「袁譚」「袁術」「董卓」「公孫瓚」「劉表」
のほうがライバル的存在と認識されてしまった!!
劉備とは、属性が違う、逆方向的な印象であるため、
しょうがないのかもしれない。

曹操だけだとわかりにくいと思うので、
以下いくつか結果を出してみよう。

似ている単語の結果だけ表示
--関羽--
劉備 0.6806955337524414
趙雲 0.6609582901000977
孫乾 0.6063336730003357
張飛 0.5494095683097839
裴元紹 0.4910241365432739
呂布 0.4753880798816681
馬超 0.4582022428512573
張苞 0.4560770094394684
厳顔 0.4506300389766693
廖化 0.4462217390537262

--張飛--
劉備 0.602747917175293
趙雲 0.5853415727615356
王忠 0.5635724067687988
関羽 0.5494095683097839
 0.5104227662086487
魏延 0.49119892716407776
黄忠 0.4832606613636017
馬岱 0.44260838627815247
呂布 0.4418014883995056
厳顔 0.4356195330619812

--劉備--
関羽 0.6806954145431519
張飛 0.602747917175293
孫乾 0.5762519836425781
劉表 0.5263820886611938
毎年 0.5026741027832031
劉焉 0.49397462606430054
張松 0.4727109968662262
劉琦 0.4714389443397522
趙雲 0.46208474040031433
趙範 0.46007320284843445

--魏延--
馬岱 0.6856343746185303
姜維 0.6569146513938904
王平 0.6510531306266785
張嶷 0.647894561290741
趙雲 0.6387921571731567
黄忠 0.6179856657981873
劉封 0.5881460905075073
厳顔 0.5788888931274414
関興 0.571064293384552
張翼 0.5704936385154724

--周瑜--
魯粛 0.734963059425354
孫権 0.6405857801437378
陸遜 0.5940338373184204
諸葛亮 0.5786603689193726
呂蒙 0.5721293091773987
黄蓋 0.5462436676025391
 0.5148110389709473
凌統 0.5106927752494812
 0.5096937417984009
諸葛瑾 0.49628153443336487

--諸葛亮--
姜維 0.612575352191925
司馬懿 0.6117764711380005
陸遜 0.5794469714164734
周瑜 0.5786603689193726
魏延 0.5581164360046387
馬謖 0.5399507284164429
龐統 0.5133271217346191
魯粛 0.5112813711166382
王平 0.49135640263557434
 0.48400527238845825

--諸葛瑾--
孫権 0.5880517959594727
ほる 0.5455287098884583
 0.5328208208084106
呉夫人 0.5227155685424805
魯粛 0.5116612315177917
沛国譙 0.5020761489868164
蔡瑁 0.49696531891822815
呂範 0.4963788688182831
周瑜 0.49628153443336487
郭嘉 0.463478684425354

--呂布--
陳宮 0.6613448262214661
曹操 0.6256376504898071
董卓 0.6036599278450012
丁原 0.6022049784660339
袁紹 0.5389851331710815
高順 0.49822214245796204
関羽 0.4753880500793457
無二 0.46212291717529297
袁術 0.4614390730857849
劉備 0.4575232267379761

--荀彧--
賈詡 0.6549777388572693
韓馥 0.5326628088951111
曹操 0.48662832379341125
荀攸 0.4653368294239044
孫翊 0.46216070652008057
一員 0.46210145950317383
審配 0.4613281190395355
郭嘉 0.46035730838775635
一因 0.4602801501750946
何進 0.45899227261543274

--呂蒙--
陸遜 0.6509128212928772
周瑜 0.5721293091773987
呉夫人 0.540614664554596
徐盛 0.5363913774490356
孫権 0.531932532787323
重態 0.519347608089447
黄蓋 0.5045372843742371
 0.4957953989505768
江頭 0.48872271180152893
魯粛 0.4872535765171051

いかがでしょうか?

まれに、よくわからん単語が混ざっている箇所があるが、
一般名詞/動詞含めた状態で見ても、
だいたい「武将名」同士で似ていると判断されている。

さらに、その出てくる武将名についても
ある程度納得感のある人が挙がっているような気がする。

よくわからん単語や、よくわからん武将が上位に来る場合は、
その単語/武将が出現頻度が低く、それらが誤ったベクトルで
登録されていると考えられる。

備考/考察:
「諸葛瑾(子瑜)」は単語の切り方がイマイチで少し精度が低い印象。
武将名は「自然言語処理編」でかなり調整したものの、
どうしても一部完璧にはならない部分が残っている。
「諸葛瑾」は「瑾」などと、一文字で表現される場合が多く、
実は前回のコードでは、一文字名前だけの場合をフルネーム化、
という処理はかなりレアケースなので実施していなかった。
「備」⇒「劉備」みたいな処理で、一般的に適切な変換ではない。
ただ「瑾」は、ほぼほぼ「諸葛瑾」なので、
彼だけ特殊処理を入れても良かったかもしれない。

ここでのポイントは「似ている」の基準
何を以て「似ている」かは、様々な尺度があるため、
その総合得点で評価されているということが重要。
例えば、以下。

  • 君主同士、軍師同士など「役割」が似ている。
  • 劉備配下など、「陣営」が似ている。
  • 別陣営であっても、良く対比される「ライバル」として似ている。
  • 同じ時代、同じ戦など、「活躍した時」が似ている。
  • 「仲良し」な人で似ている。(魏延と馬岱など

人間に聞いたとしても、
例えば、「諸葛亮」に「近い属性の人は?」と聞かれると、
司馬懿であったり、姜維、周瑜、龐統、または劉備かも?
などなど様々な答えがかえってくるでしょう。それと同じ理屈。

龐統 「諸葛亮に似ている人の6位に・・・」
龐統 「山登りのスペシャリスト が出ていますよ?」
諸葛亮「だまらっしゃい!!

この「似ている度」を基本として、
次はその応用編。三国志ファン感涙の、
武将同士のベクトル演算で、
魏呉蜀各武将のライバル関係が明らかに!!

孫権「曹操には張遼がいる、わしには甘寧がいる」

孫権 「曹操には張遼がいる、わしには甘寧がいる
孫権 「ということは、張遼と曹操の関係が、甘寧と孫権の関係と同じだから」
孫権 「張遼 マイナス 曹操 = 甘寧 マイナス 孫権 、になる!」
陸遜 「(またお酒が入りすぎているようだな・・・)
机の角「(ガクガクブルブル・・・)」

無実なのに切って捨てられた机の角よ、ご安心めされよ。
今回作ったえーあいは、この酒乱江東の碧眼児孫権の言うような
武将同士の計算が出来るのだ!

既に武将がベクトル情報になっているため、
その足し算引き算をした結果ベクトルに対し、
最も似ている単語(武将)を見る、というシンプルな仕組みだ。

左辺と右辺を整理すると以下のようになる。

「張遼」 = 「甘寧」+「曹操」-「孫権」

さあ、この右辺の計算が本当に「張遼」になるのか試してみよう!!

ついでに、
劉備にとっての(孫権に対する)甘寧は誰だよ?と、
劉備にとっての(曹操に対する)張遼は誰だよ?も、
一緒にやってみる。

曹操と似た単語を調べる
# 「甘寧」+「曹操」-「孫権」
print(model.wv.most_similar(positive=['甘寧','曹操'], negative=['孫権'],topn=10))
# 「甘寧」+「劉備」-「孫権」
print(model.wv.most_similar(positive=['甘寧','劉備'], negative=['孫権'],topn=10))
# 「張遼」+「劉備」-「曹操」
print(model.wv.most_similar(positive=['張遼','劉備'], negative=['曹操'],topn=10))
武将演算の出力結果
# 「甘寧」+「曹操」-「孫権」の出力結果
[('張遼', 0.5975690484046936), ('双方', 0.5424929261207581), ('車冑', 0.5172145962715149), ('秦琪', 0.5103437900543213), ('寄手', 0.5010682344436646), ('呂布', 0.4903222918510437), ('ひょう', 0.480598509311676), ('誰か', 0.47944292426109314), ('楊奉', 0.4771113991737366), ('紀霊', 0.4762181043624878)]

# 「甘寧」+「劉備」-「孫権」の出力結果
[('張飛', 0.6009012460708618), ('車冑', 0.5231213569641113), ('誰か', 0.5017432570457458), ('王忠', 0.4733934998512268), ('関羽', 0.46644333004951477), ('下がる', 0.4650993049144745), ('張遼', 0.46208637952804565), ('朋友', 0.43470197916030884), ('右翼', 0.4339367747306824), ('山下', 0.42906704545021057)]

# 「張遼」+「劉備」-「曹操」の出力結果
[('張飛', 0.5989757776260376), ('関羽', 0.589595377445221), ('孫乾', 0.5613676309585571), ('趙雲', 0.5599579215049744), ('関平', 0.5381424427032471), ('卒', 0.49242568016052246), ('はあと', 0.46057409048080444), ('呉懿', 0.44697314500808716), ('夫人', 0.4372628629207611), ('ふたり', 0.4333947002887726)]

「車冑」って誰だっけ・・・?
2位以降がイマイチな点はあるが、
結構な大差をつけて、「ワシの甘寧」の1位は、
曹操⇒「張遼」と劉備⇒「張飛」が
それぞれ出てくることになった。(なお、関羽は5位)
劉備にとっての張遼、については、張飛/関羽が接戦であった。

張遼の二位以下にもう少し魏の武力90台を出して欲しかったが
精度の問題か、最初は敵だった属性が効いているのか

孫権サマの「ワシの甘寧」発言は、
三国志演戯を機械学習した結果からも妥当性がある
ということが判明した。

以下いくつか他の結果も出力してみる。(コードは省略)

武将演算の様々な結果
# 「曹操」にとって、劉備の諸葛亮にあたる人は誰?(曹操+諸葛亮-劉備)
[('司馬懿', 0.6807084083557129), ('曹真', 0.6253277659416199), ('張郃', 0.5542588829994202), ('曹遵', 0.5308239459991455), ('審配', 0.5271061062812805), ('兵法', 0.5043819546699524), ('周瑜', 0.4940730035305023), ('陸遜', 0.4794454574584961), ('賈詡', 0.47504767775535583), ('郭淮', 0.4681739807128906)]

# 無理やり最強合体で呂布と諸葛亮を足すと?(呂布+諸葛亮)
[('曹操', 0.6402270197868347), ('劉備', 0.6272321343421936), ('陳宮', 0.6206848621368408), ('関羽', 0.5986325740814209), ('法正', 0.5725218653678894), ('厳顔', 0.5579944252967834), ('賈詡', 0.5574716329574585), ('司馬懿', 0.5248735547065735), ('周瑜', 0.5034980177879333), ('馬超', 0.4987131357192993)]

# 「曹操」にとって、劉備の張飛にあたる人は誰?(曹操+張飛-劉備)
[('許褚', 0.6215435266494751), ('秦琪', 0.6193733811378479), ('董卓', 0.5844904780387878), ('呂布', 0.5498712062835693), ('寄手', 0.5366292595863342), ('双方', 0.5207207798957825), ('陳宮', 0.5160595178604126), ('張遼', 0.5159090757369995), ('韓遂', 0.5104340314865112), ('ひょう', 0.5089328289031982)]

# 「曹操」にとって、劉備の関羽にあたる人は誰?(曹操+関羽-劉備)
[('袁紹', 0.5561782121658325), ('張遼', 0.5554732084274292), ('夏侯惇', 0.5427525043487549), ('呂布', 0.535315215587616), ('楽進', 0.5261821746826172), ('丁原', 0.5100050568580627), ('侯成', 0.48861902952194214), ('許褚', 0.4884832799434662), ('賈詡', 0.47699469327926636), ('于禁', 0.4732886254787445)]

# 「劉備」にとって、孫権の魯粛にあたる人は誰?(魯粛+劉備-孫権)
[('司馬徽', 0.5429366230964661), ('徐庶', 0.5424918532371521), ('張飛', 0.5137515664100647), ('孫乾', 0.4811612665653229), ('小才', 0.4786354899406433), ('連れ', 0.4577670395374298), ('毎年', 0.4426392614841461), ('筆', 0.44031772017478943), ('鄭重', 0.43619340658187866), ('後ろ姿', 0.4288194179534912)]

いかがでしょうか?
三国志ファンなら半日くらい遊べてしまいそうな危険なオモチャ

武将3名分の50次元ベクトルを足し算引き算しているため、
単純な「似ている」に比べて、参照する対象が多くなっており、
どうしてもゴミが入りやすくなる傾向はあるが、
TOP3には、なるほどな人が出ているような気はする。

おそらく、孫権の甘寧に対するこのセリフを
小説上本当に成り立っているのか分析したのは
世界初レベルの無駄の無双乱舞的なプロジェクト。

こうして三国志の世界にまた一つ新たなトリビアが生まれた。
「曹操には張遼がいる、孫権には甘寧がいる」
は、三国志演義の小説をAIが読んでも同じ結果を導けた!

次項ではいよいよ、このモデルを使って
「武力」「知力」の数値化を考えたいが、その前に
実は、この物語の裏には、
無双ゲージがMAXになるまで
雑兵を1000人くらい切るような努力があったのだ。
その裏話も語らせていただこう!

三日会わざれば刮目して見よ(機械学習のチューニング)

魯粛「お、呂蒙?しばらく見ない間にずいぶんと変わったな!」
魯粛「まさに、呉下の阿蒙にあらず」
呂蒙「美容院に行ったの気付いてくれるのは魯粛殿だけです(ハート)」
魯粛「(ポッ)」
魯粛「大都督あげちゃうっ!」

三日会わざれば刮目して見よ
~~意味~~
三日も経つと人は成長しているものだ、
三日も会わなければ評価を改めてしっかりみなさい。
逆に言えば、人は三日でも大きく成長出来るものだ。
~~~~~~

呂蒙は三日ごとに美容院でイメチェンしていたわけだが、
機械学習のモデルはまさに呂蒙のごとく。
最初に魏延をベクトル化した際のコードの設定値の部分。
この設定をちょっと変更すると、機械学習結果は大きく異なる

設定値の一例
#機械学習におけるパラメータの設定値
#ここの値の調整が精度に直結している。
size_setting = 50
min_count_setting = 5
window_setting = 6
iter_setting = 4500

3つ値が違えば刮目して見よ! ということ。

本稿では主に上記の4つを様々に変えて試していた。
(Word2Vecの学習時のパラメータは上記以外にもいろいろある)

30回以上は様々なモデルを作っていたと思う。
ゲームしながらColaboratory放置を何十時間も。

何度もやったから「狙った結果」が出たんでしょ、
という人もいるかもしれないが、
武将名だけで数百単語、一般名詞/動詞も含めると約1万の単語がある中で、
複数の演算結果を同時に「狙った結果」にするのは不可能に近い。
自然言語処理編で武将名識別&名寄せを丁寧に行い、
かつ、パラメータを試行錯誤することで、
それっぽい機械学習モデル(ベクトル化された単語データ)を
やっと得ることが出来たのだ。
INPUTが自然言語で書かれた小説のテキスト一つで、
パラメータ調整だけでこれくらいの結果まで行く、と見て欲しい。
なお、より精度を上げるには、まずは複数の作者の小説を入れてみたい。
武将によっては登場回数が少なすぎて、吉川英治版のみでは評価が難しいため。

パラメータ調整時の面白いポイントをひとつ、例としてご紹介する。
次元数」について、今回50次元のベクトルとしたが、
一見、次元数を多くすればするほど詳細な分析になりそうである。
しかし、100次元などと多くしても良い結果は出なかった。
最低でも20次元くらいは必要で、30~60次元あたりが、
妥当な値に思えた。データ量(テキストの分量)に見合う程度の個数、
データ軸を設定しなければいけない、ということ。
多すぎても少なすぎても上手くいかない。

こうした雑兵1000人組手のような地道な努力によって、
ある程度納得感のある機械学習モデルを得ることが出来た!
いよいよコレを使って、武力知力の数値化を考えてみよう。

人中の呂布、馬中の赤兎(最強の武を求める)

張飛「燕人張飛ここにあり!呂布め、いくぞ!」
呂布「来い!飛将呂布奉先、おまえのようなやつには負けん!」
関羽「助太刀するぞっ!」
呂布「ム、援軍か、これはまずいな。一度退くか・・・。」
劉備「あのゴキブリの触覚のようなのを付けているやつが呂布だ!」
呂布「3人まとめてやっつけてやる!!(怒)

さて最強の武(の値)を求める
にはどうしたらよいだろうか?

作成した機械学習モデルに、
「三国志の世界が正しく投影されている」とすれば
そのモデルの中のどれかの値や、何かの計算結果を見れば、
「武力」「知力」に相当する値が得られるのではないか?
というのが本稿最大のアイデアである。

まず最初にやってみた実験が、
50次元のベクトルになっているのだから、
そもそも、その中のどれか一つの値が、「武力」「知力」や、
「蜀への所属度」「忠誠心」などの、
なんらかの分かりやすい値になっているかもしれない、
という内容の確認だ。

モデル全体の中から、三国志の武将名だけのデータを取り出す。
(一般名詞や動詞のデータは除外する)
ついでに、その武将名が何回登場しているか?のデータも付与して眺めてみよう。

武将のベクトルだけ取り出す
import pickle
model_sava_file_name = 保存したモデルファイル名
with open('drive/My Drive/Sangokusi/'+model_sava_file_name, 'rb') as f:
    model = pickle.load(f)

#作成したモデルのなかに登録されている単語数の確認
print(len(model.wv.vocab.keys()))

#作成したモデルのなかで、「武将」のデータと、そのベクトルを全て抜き出してリストを作る
Busyou_data_list = []
for word, vocab_obj in model.wv.vocab.items():
    #jinbutu_word_listは自然言語処理編で作った全武将の単語リスト
    #その単語が、「武将名」であれば、リストに追加する処理を行う。
    if word in jinbutu_word_list:
        #print(word,":",vocab_obj.count)

        #分散表現(ベクトル情報)を抜き出す
        busyou_vector = model.__dict__['wv'][word]
        #武将名、出現回数、ベクトル情報、を格納したリストにする
        Busyou_data_list.append([word, vocab_obj.count]+ busyou_vector.tolist())

#「出現回数」で並べ替え
Busyou_data_list = sorted(Busyou_data_list, key=lambda x: -x[1])

#全体として何人の武将データが作れたか表示
print(len(Busyou_data_list))
#サンプルとして、最初のデータを表示
print(Busyou_data_list[0])
武将のベクトルだけ作った結果
9653
421
['曹操', 2843, 3.834890365600586, 0.6499840617179871, 1.3674521446228027, -0.29894790053367615, -0.9264350533485413, -3.5290303230285645, -0.2177853137254715, -2.4688072204589844, -2.185100555419922, -0.9018422365188599, -2.48173451423645, -2.8471529483795166, 1.0149024724960327, 0.3895401358604431, -3.4980974197387695, 0.4531531035900116, 2.1340160369873047, 1.5887707471847534, 1.6122041940689087, -2.1009063720703125, -0.36042818427085876, -1.551460862159729, 1.1327486038208008, -0.8541130423545837, 1.072536826133728, -0.08540906757116318, -2.70839524269104, -3.965020179748535, -0.5980285406112671, -4.0637431144714355, -3.365858793258667, 0.4908220171928406, 1.3250325918197632, 0.2127988189458847, 2.9902565479278564, -1.4399590492248535, -2.3241443634033203, -2.2173967361450195, 0.1169036328792572, -2.4554295539855957, -0.05750872567296028, 0.31866252422332764, 0.3000071942806244, 0.5707933902740479, -2.4878640174865723, 1.7815735340118408, 1.4298678636550903, -3.451324939727783, 0.8778221607208252, -1.5637134313583374]

上記の結果の意味としては、
元々9653単語が機械学習モデル内に登録されており、
武将名のデータに限定すると421名分のデータ。
(※min_count_setting = 5であるので、5回以上出現した武将が421名)
うち「曹操」が最も出現頻度が高い単語で、小説中に2843回出現した、
ということを意味する。
これで421名×(50次元 + 出現回数)のデータが作れた。

このまま愚直に、
各次元ごとに、値の高い武将~低い武将を見てみよう!
412名全部を見るとエライことになるため、
出現回数の多い50名分のデータに絞って実施する。

魏延のベクトル表示結果を思い出してほしい。

魏延のベクトル化表示
[ -3.29209     -0.8619167    2.548894    -6.2769666    4.820325
  -4.3188534    4.892581     3.0584764   -1.941075     7.202591
   2.825382     2.6815546   -1.5141411    1.2163684    7.8137026
   5.9709163    4.2522264   -3.750429    -1.2866642   -5.4226913
  -1.1429474    0.74476415   4.2300115    3.1387594    0.60046256
   0.8668483   -5.342602    -1.0369713    1.8684605   -0.29890215
  -6.667386    -1.8291212   -3.2661974   -0.50744665   1.6939703
   1.3792468   -0.2192511  -10.185009    -2.773828     2.1797962
  -2.4290617    1.8001399    5.592892    -9.066986    -2.3023245
   2.6630638   -3.0628533   -4.383273     8.999806    -4.0579867 ]

この、1番目の数字が高い順、2番目の数字が高い順、・・・・
と、並べていったものを出そう、ということ。

全次元それぞれに対し、値の高い武将~低い武将を表示
#マイナー武将が入ってくるとカオスになるので、
#登場頻度が高い武将だけに絞る
tmp_Busyou_data_list = Busyou_data_list[0:50]

#各ベクトルごとに、その50名をソートして表示する
#つまり、各ベクトルごとのTOP~ビリまでの順番で出る
for a in range(1,52):
    print(a)
    tmp_Busyou_data_list = sorted(tmp_Busyou_data_list, key=lambda x: -x[a])
    for Busyou_data in tmp_Busyou_data_list:
        print(Busyou_data[0]+", " , end="")
    print("")

以下が、出現回数の最も多い50人に対して、
各次元ごとの、1位~50位(ビリ)までの全結果。
膨大だが、「ベクトル化」の意味を考える上でも興味深いために全部掲載する。
なお、一番上の「1」は、出現頻度順であり、
これだけはベクトルの数値ではない。
出現頻度も結構意外な順番

各次元ごとの1位~50位(ビリ)までの全結果
1
曹操, 劉備, 諸葛亮, 関羽, 張飛, 呂布, 袁紹, 周瑜, 孫権, 趙雲, 司馬懿, 董卓, 孫策, 魏延, 馬超, 魯粛, 黄忠, 劉表, 袁術, 張郃, 孫堅, 張遼, 貂蝉, 孟獲, 姜維, 徐晃, 陳宮, 曹丕, 徐庶, 曹仁, 許褚, 陸遜, 龐統, 董承, 龐徳, 呂蒙, 甘寧, 馬岱, 夏侯惇, 曹洪, 曹真, 王允, 劉璋, 孟達, 関平, 関興, 孫乾, 夏侯淵, 王平, 太史慈, 
2
曹洪, 袁術, 袁紹, 呂布, 董卓, 馬超, 孟達, 董承, 張郃, 劉璋, 夏侯惇, 張遼, 夏侯淵, 曹仁, 陳宮, 徐晃, 王允, 孫策, 貂蝉, 曹丕, 劉表, 曹操, 司馬懿, 曹真, 姜維, 許褚, 王平, 孫堅, 劉備, 馬岱, 関羽, 甘寧, 黄忠, 孫乾, 孟獲, 趙雲, 龐統, 魯粛, 諸葛亮, 龐徳, 張飛, 関平, 呂蒙, 太史慈, 魏延, 関興, 孫権, 徐庶, 陸遜, 周瑜, 
3
魯粛, 曹真, 司馬懿, 陸遜, 董卓, 王平, 甘寧, 劉璋, 孫権, 関興, 張飛, 許褚, 周瑜, 徐晃, 董承, 諸葛亮, 呂蒙, 劉備, 曹操, 馬岱, 貂蝉, 袁術, 呂布, 張遼, 張郃, 孫乾, 関羽, 龐統, 陳宮, 魏延, 趙雲, 姜維, 袁紹, 孫策, 馬超, 曹洪, 夏侯惇, 黄忠, 夏侯淵, 孫堅, 劉表, 徐庶, 王允, 龐徳, 孟獲, 曹仁, 曹丕, 関平, 孟達, 太史慈, 
4
劉璋, 袁紹, 張郃, 孟達, 孫乾, 馬超, 曹洪, 姜維, 曹仁, 関羽, 夏侯惇, 魏延, 呂蒙, 孫権, 趙雲, 呂布, 龐統, 司馬懿, 諸葛亮, 曹操, 王平, 夏侯淵, 孫堅, 劉備, 孟獲, 曹丕, 馬岱, 甘寧, 董承, 劉表, 陸遜, 黄忠, 関興, 陳宮, 周瑜, 徐庶, 張飛, 龐徳, 徐晃, 曹真, 董卓, 関平, 袁術, 許褚, 魯粛, 孫策, 貂蝉, 張遼, 王允, 太史慈, 
5
劉璋, 呂布, 王允, 馬超, 袁術, 孫権, 夏侯惇, 孟獲, 龐徳, 孫堅, 董卓, 曹洪, 董承, 貂蝉, 関羽, 陳宮, 曹操, 徐晃, 甘寧, 張遼, 許褚, 趙雲, 劉表, 曹仁, 曹丕, 孫策, 張飛, 袁紹, 王平, 太史慈, 劉備, 孫乾, 孟達, 呂蒙, 関平, 夏侯淵, 馬岱, 魏延, 周瑜, 姜維, 陸遜, 魯粛, 関興, 諸葛亮, 龐統, 司馬懿, 張郃, 徐庶, 曹真, 黄忠, 
6
関興, 孫権, 曹洪, 趙雲, 曹仁, 夏侯淵, 馬岱, 魏延, 甘寧, 許褚, 周瑜, 関羽, 呂布, 陸遜, 太史慈, 王平, 徐晃, 張飛, 袁術, 張遼, 龐統, 劉表, 関平, 孟達, 黄忠, 馬超, 曹真, 諸葛亮, 劉備, 呂蒙, 夏侯惇, 孟獲, 陳宮, 張郃, 姜維, 魯粛, 徐庶, 孫堅, 曹操, 孫乾, 袁紹, 司馬懿, 龐徳, 孫策, 董承, 董卓, 劉璋, 貂蝉, 王允, 曹丕, 
7
王允, 貂蝉, 董承, 魯粛, 曹丕, 太史慈, 諸葛亮, 王平, 曹真, 姜維, 劉璋, 呂蒙, 董卓, 劉備, 龐統, 周瑜, 孟獲, 徐庶, 袁術, 陳宮, 馬岱, 趙雲, 曹操, 馬超, 夏侯淵, 司馬懿, 孫権, 孫乾, 魏延, 劉表, 関羽, 龐徳, 徐晃, 孟達, 張郃, 呂布, 張飛, 夏侯惇, 黄忠, 曹洪, 張遼, 陸遜, 関興, 関平, 許褚, 甘寧, 孫堅, 孫策, 曹仁, 袁紹, 
8
貂蝉, 王允, 黄忠, 曹仁, 龐徳, 曹丕, 龐統, 董承, 太史慈, 魏延, 周瑜, 孫権, 魯粛, 張遼, 司馬懿, 諸葛亮, 趙雲, 徐晃, 張郃, 陸遜, 甘寧, 曹洪, 関平, 孫策, 張飛, 夏侯惇, 曹真, 関羽, 孟獲, 呂蒙, 姜維, 馬岱, 孟達, 徐庶, 董卓, 曹操, 夏侯淵, 許褚, 袁紹, 孫乾, 馬超, 劉備, 関興, 孫堅, 呂布, 陳宮, 袁術, 王平, 劉璋, 劉表, 
9
王平, 姜維, 董承, 龐徳, 曹真, 魏延, 徐晃, 張郃, 夏侯淵, 関羽, 夏侯惇, 馬超, 司馬懿, 黄忠, 陸遜, 許褚, 諸葛亮, 孫権, 曹洪, 関興, 孟達, 劉表, 王允, 劉備, 関平, 劉璋, 趙雲, 呂布, 呂蒙, 孫策, 馬岱, 袁紹, 曹操, 魯粛, 徐庶, 孫堅, 龐統, 曹丕, 陳宮, 張飛, 袁術, 太史慈, 張遼, 曹仁, 貂蝉, 周瑜, 孫乾, 孟獲, 甘寧, 董卓, 
10
徐庶, 夏侯惇, 貂蝉, 関興, 孫策, 曹仁, 張飛, 孫乾, 張遼, 劉備, 孟獲, 関羽, 趙雲, 司馬懿, 陸遜, 太史慈, 王允, 馬岱, 呂布, 諸葛亮, 張郃, 甘寧, 黄忠, 魯粛, 董卓, 姜維, 周瑜, 呂蒙, 龐統, 王平, 魏延, 曹操, 馬超, 孫堅, 袁紹, 曹丕, 関平, 許褚, 袁術, 孫権, 曹洪, 劉璋, 陳宮, 徐晃, 董承, 曹真, 劉表, 夏侯淵, 孟達, 龐徳, 
11
孟達, 馬岱, 魏延, 徐庶, 王平, 張郃, 張飛, 黄忠, 陳宮, 夏侯惇, 張遼, 関平, 姜維, 関興, 曹真, 孟獲, 徐晃, 曹仁, 劉璋, 諸葛亮, 馬超, 龐統, 孫乾, 夏侯淵, 貂蝉, 劉備, 許褚, 龐徳, 司馬懿, 趙雲, 曹操, 関羽, 呂布, 董卓, 魯粛, 王允, 董承, 曹洪, 曹丕, 周瑜, 太史慈, 劉表, 袁紹, 袁術, 孫権, 甘寧, 陸遜, 孫策, 呂蒙, 孫堅, 
12
関平, 関興, 張飛, 孫乾, 姜維, 孟達, 龐統, 魏延, 劉備, 董承, 関羽, 曹洪, 呂蒙, 劉璋, 曹丕, 諸葛亮, 馬岱, 孫策, 孟獲, 趙雲, 黄忠, 張遼, 許褚, 馬超, 王平, 陳宮, 周瑜, 魯粛, 甘寧, 王允, 夏侯淵, 陸遜, 太史慈, 曹操, 曹真, 曹仁, 呂布, 司馬懿, 董卓, 孫権, 袁術, 貂蝉, 徐庶, 袁紹, 張郃, 孫堅, 徐晃, 劉表, 夏侯惇, 龐徳, 
13
関平, 魯粛, 姜維, 曹仁, 曹洪, 呂蒙, 徐庶, 孫策, 徐晃, 黄忠, 孫乾, 魏延, 王平, 趙雲, 許褚, 陸遜, 張郃, 関興, 龐統, 張飛, 夏侯淵, 周瑜, 諸葛亮, 龐徳, 劉備, 孫権, 張遼, 夏侯惇, 陳宮, 太史慈, 甘寧, 馬岱, 孫堅, 劉璋, 関羽, 曹操, 司馬懿, 孟達, 呂布, 曹丕, 馬超, 董承, 王允, 貂蝉, 曹真, 董卓, 袁紹, 孟獲, 袁術, 劉表, 
14
魯粛, 陳宮, 太史慈, 孫策, 曹仁, 袁紹, 周瑜, 呂布, 孫権, 孫乾, 孫堅, 甘寧, 徐晃, 孟獲, 張飛, 関羽, 関平, 貂蝉, 曹洪, 王允, 張遼, 呂蒙, 許褚, 徐庶, 夏侯惇, 龐徳, 劉備, 劉表, 陸遜, 龐統, 董卓, 馬超, 袁術, 曹操, 王平, 曹丕, 黄忠, 曹真, 趙雲, 夏侯淵, 馬岱, 諸葛亮, 魏延, 董承, 張郃, 姜維, 関興, 孟達, 司馬懿, 劉璋, 
15
曹真, 王平, 董卓, 馬岱, 孫乾, 袁紹, 孟獲, 曹洪, 関平, 王允, 呂蒙, 陳宮, 陸遜, 黄忠, 曹仁, 魏延, 張遼, 張飛, 関羽, 曹操, 孫策, 司馬懿, 袁術, 曹丕, 劉備, 劉璋, 夏侯惇, 呂布, 張郃, 徐晃, 夏侯淵, 諸葛亮, 姜維, 魯粛, 孫権, 孫堅, 趙雲, 周瑜, 許褚, 徐庶, 龐徳, 馬超, 劉表, 孟達, 関興, 太史慈, 龐統, 甘寧, 貂蝉, 董承, 
16
魏延, 王平, 姜維, 甘寧, 夏侯惇, 馬岱, 趙雲, 陸遜, 関興, 曹真, 孟獲, 呂蒙, 龐統, 黄忠, 張郃, 孫乾, 孟達, 徐晃, 関羽, 張遼, 曹洪, 諸葛亮, 孫堅, 張飛, 劉璋, 劉備, 関平, 司馬懿, 孫策, 曹丕, 曹仁, 孫権, 馬超, 董承, 魯粛, 周瑜, 徐庶, 曹操, 袁紹, 許褚, 太史慈, 袁術, 龐徳, 夏侯淵, 劉表, 呂布, 王允, 董卓, 貂蝉, 陳宮, 
17
龐統, 許褚, 魏延, 袁術, 司馬懿, 陸遜, 呂蒙, 馬岱, 曹真, 張郃, 呂布, 貂蝉, 董卓, 黄忠, 劉表, 夏侯淵, 太史慈, 諸葛亮, 甘寧, 徐晃, 孟達, 陳宮, 趙雲, 馬超, 曹操, 孟獲, 姜維, 孫堅, 王平, 孫策, 張飛, 王允, 曹洪, 張遼, 徐庶, 魯粛, 関興, 周瑜, 曹仁, 龐徳, 劉備, 関羽, 董承, 袁紹, 夏侯惇, 曹丕, 孫権, 関平, 劉璋, 孫乾, 
18
劉表, 陸遜, 劉璋, 孟獲, 魯粛, 関平, 孫乾, 龐統, 袁術, 周瑜, 関興, 魏延, 孫権, 劉備, 袁紹, 張飛, 太史慈, 曹丕, 徐庶, 諸葛亮, 孫策, 董承, 曹操, 呂蒙, 趙雲, 徐晃, 曹仁, 陳宮, 孫堅, 王允, 呂布, 董卓, 張郃, 黄忠, 夏侯淵, 姜維, 関羽, 司馬懿, 夏侯惇, 馬岱, 王平, 許褚, 張遼, 貂蝉, 曹真, 馬超, 曹洪, 甘寧, 龐徳, 孟達, 
19
孫堅, 張遼, 孫策, 甘寧, 呂布, 太史慈, 黄忠, 夏侯淵, 孫乾, 袁術, 徐庶, 袁紹, 董承, 曹洪, 許褚, 周瑜, 陸遜, 董卓, 張飛, 関羽, 曹操, 夏侯惇, 関平, 龐統, 趙雲, 劉備, 呂蒙, 曹真, 孫権, 魯粛, 馬岱, 曹仁, 孟達, 曹丕, 馬超, 貂蝉, 龐徳, 王允, 劉表, 関興, 徐晃, 司馬懿, 魏延, 陳宮, 張郃, 孟獲, 姜維, 諸葛亮, 王平, 劉璋, 
20
曹洪, 王允, 張遼, 夏侯淵, 袁紹, 貂蝉, 徐晃, 夏侯惇, 馬岱, 呂布, 甘寧, 関羽, 袁術, 関興, 趙雲, 曹仁, 張飛, 徐庶, 孫策, 劉備, 劉表, 曹操, 黄忠, 張郃, 孫乾, 関平, 陳宮, 孫権, 許褚, 馬超, 董卓, 魯粛, 周瑜, 王平, 太史慈, 魏延, 劉璋, 曹丕, 董承, 司馬懿, 姜維, 孟獲, 龐統, 諸葛亮, 孟達, 孫堅, 曹真, 呂蒙, 龐徳, 陸遜, 
21
劉璋, 袁術, 孫権, 劉表, 劉備, 袁紹, 周瑜, 趙雲, 曹洪, 王允, 関羽, 関平, 孟達, 曹丕, 陸遜, 孫乾, 龐統, 諸葛亮, 張遼, 張飛, 曹操, 魯粛, 徐庶, 呂蒙, 甘寧, 呂布, 太史慈, 孫堅, 許褚, 姜維, 馬超, 陳宮, 王平, 龐徳, 孫策, 黄忠, 司馬懿, 魏延, 貂蝉, 董卓, 曹仁, 夏侯惇, 曹真, 馬岱, 董承, 関興, 徐晃, 夏侯淵, 張郃, 孟獲, 
22
呂布, 孫乾, 董承, 許褚, 張飛, 関羽, 関平, 孫堅, 劉備, 劉表, 甘寧, 夏侯惇, 袁術, 孫策, 孟達, 馬超, 張遼, 夏侯淵, 劉璋, 関興, 孫権, 龐統, 趙雲, 曹操, 太史慈, 呂蒙, 周瑜, 黄忠, 曹仁, 孟獲, 陳宮, 魯粛, 魏延, 諸葛亮, 王允, 曹洪, 袁紹, 董卓, 徐晃, 徐庶, 陸遜, 司馬懿, 貂蝉, 龐徳, 姜維, 曹真, 王平, 曹丕, 馬岱, 張郃, 
23
董承, 関平, 王允, 董卓, 夏侯惇, 許褚, 袁術, 張飛, 周瑜, 甘寧, 曹洪, 張郃, 魏延, 王平, 呂蒙, 黄忠, 劉表, 徐晃, 魯粛, 貂蝉, 曹仁, 呂布, 関羽, 姜維, 孫策, 曹操, 夏侯淵, 孫権, 劉備, 関興, 趙雲, 陸遜, 龐統, 曹真, 劉璋, 曹丕, 袁紹, 孫堅, 諸葛亮, 司馬懿, 張遼, 馬岱, 孫乾, 陳宮, 龐徳, 孟達, 馬超, 孟獲, 徐庶, 太史慈, 
24
孟獲, 張郃, 太史慈, 司馬懿, 夏侯淵, 張飛, 趙雲, 王平, 許褚, 馬岱, 周瑜, 魏延, 曹真, 馬超, 袁術, 劉表, 姜維, 黄忠, 夏侯惇, 龐統, 曹洪, 龐徳, 張遼, 孟達, 諸葛亮, 関羽, 関平, 袁紹, 劉備, 陳宮, 孫堅, 魯粛, 孫策, 曹操, 関興, 劉璋, 徐晃, 董卓, 董承, 呂布, 曹丕, 曹仁, 孫権, 孫乾, 貂蝉, 陸遜, 甘寧, 呂蒙, 徐庶, 王允, 
25
甘寧, 夏侯惇, 呂蒙, 夏侯淵, 張遼, 関平, 曹仁, 太史慈, 王平, 張郃, 徐晃, 馬超, 黄忠, 周瑜, 龐徳, 曹真, 司馬懿, 関興, 魏延, 孟獲, 曹洪, 馬岱, 陸遜, 曹丕, 劉璋, 孫権, 孫堅, 諸葛亮, 孫乾, 張飛, 関羽, 曹操, 許褚, 趙雲, 姜維, 魯粛, 孫策, 袁術, 孟達, 王允, 劉備, 龐統, 呂布, 董卓, 陳宮, 劉表, 徐庶, 袁紹, 董承, 貂蝉, 
26
董卓, 孟獲, 曹丕, 孫権, 徐庶, 姜維, 関興, 孟達, 孫堅, 貂蝉, 孫策, 董承, 司馬懿, 劉璋, 周瑜, 魯粛, 陳宮, 袁術, 諸葛亮, 張郃, 許褚, 劉備, 呂蒙, 曹操, 魏延, 呂布, 陸遜, 袁紹, 関羽, 関平, 王允, 黄忠, 張飛, 趙雲, 徐晃, 曹洪, 夏侯惇, 王平, 太史慈, 龐統, 孫乾, 龐徳, 甘寧, 馬岱, 劉表, 張遼, 曹真, 夏侯淵, 馬超, 曹仁, 
27
姜維, 曹洪, 陳宮, 張郃, 趙雲, 徐庶, 孫乾, 関羽, 張遼, 劉璋, 関興, 夏侯惇, 徐晃, 龐統, 周瑜, 王平, 孟達, 諸葛亮, 馬岱, 董承, 司馬懿, 魏延, 呂布, 袁紹, 曹真, 黄忠, 王允, 魯粛, 夏侯淵, 曹操, 呂蒙, 劉備, 劉表, 曹丕, 甘寧, 太史慈, 董卓, 関平, 曹仁, 孫権, 貂蝉, 馬超, 孟獲, 張飛, 龐徳, 許褚, 孫策, 陸遜, 孫堅, 袁術, 
28
董承, 魯粛, 徐庶, 貂蝉, 龐統, 周瑜, 甘寧, 孫堅, 張飛, 呂布, 劉璋, 関羽, 孟獲, 諸葛亮, 王允, 王平, 黄忠, 孫策, 劉備, 呂蒙, 孫乾, 馬超, 袁紹, 袁術, 孫権, 陳宮, 司馬懿, 太史慈, 曹操, 趙雲, 陸遜, 龐徳, 曹真, 姜維, 董卓, 夏侯惇, 張郃, 劉表, 馬岱, 曹洪, 魏延, 徐晃, 許褚, 夏侯淵, 張遼, 曹仁, 曹丕, 関平, 孟達, 関興, 
29
孟達, 劉璋, 姜維, 曹丕, 関平, 孟獲, 馬岱, 曹仁, 王平, 孫乾, 甘寧, 司馬懿, 貂蝉, 馬超, 孫権, 諸葛亮, 孫堅, 孫策, 張遼, 董承, 劉備, 呂蒙, 太史慈, 関興, 魏延, 陸遜, 関羽, 趙雲, 魯粛, 劉表, 夏侯淵, 袁紹, 曹操, 張飛, 龐統, 曹洪, 龐徳, 呂布, 黄忠, 曹真, 周瑜, 王允, 董卓, 袁術, 徐庶, 徐晃, 許褚, 陳宮, 張郃, 夏侯惇, 
30
関興, 孟達, 貂蝉, 張飛, 徐庶, 劉表, 董承, 関平, 許褚, 董卓, 劉備, 魏延, 馬超, 龐統, 劉璋, 袁術, 呂布, 趙雲, 姜維, 関羽, 王平, 馬岱, 孫権, 陳宮, 曹操, 曹丕, 夏侯淵, 甘寧, 孫策, 周瑜, 張遼, 太史慈, 孫乾, 魯粛, 張郃, 孫堅, 呂蒙, 諸葛亮, 陸遜, 夏侯惇, 司馬懿, 曹洪, 黄忠, 徐晃, 曹真, 王允, 龐徳, 袁紹, 曹仁, 孟獲, 
31
太史慈, 司馬懿, 黄忠, 陸遜, 姜維, 陳宮, 董承, 曹真, 董卓, 張郃, 徐晃, 魏延, 呂布, 孫堅, 夏侯惇, 張飛, 許褚, 王平, 甘寧, 孟獲, 夏侯淵, 呂蒙, 馬岱, 孫策, 諸葛亮, 馬超, 張遼, 孟達, 曹丕, 曹洪, 関興, 曹操, 趙雲, 徐庶, 劉璋, 龐統, 曹仁, 貂蝉, 劉備, 劉表, 周瑜, 孫権, 袁紹, 関羽, 龐徳, 関平, 魯粛, 袁術, 孫乾, 王允, 
32
呂蒙, 孫権, 孫堅, 孫乾, 関羽, 陸遜, 魯粛, 龐統, 劉表, 孫策, 徐庶, 太史慈, 劉備, 劉璋, 諸葛亮, 趙雲, 周瑜, 関平, 貂蝉, 陳宮, 張飛, 袁術, 王允, 姜維, 龐徳, 黄忠, 孟獲, 袁紹, 夏侯惇, 曹丕, 曹操, 甘寧, 呂布, 張郃, 曹洪, 夏侯淵, 孟達, 曹仁, 許褚, 曹真, 董承, 魏延, 王平, 董卓, 馬超, 馬岱, 徐晃, 張遼, 司馬懿, 関興, 
33
甘寧, 劉璋, 趙雲, 龐統, 王允, 夏侯惇, 孫策, 孫乾, 董卓, 貂蝉, 孟獲, 張飛, 呂布, 龐徳, 張郃, 孫堅, 王平, 黄忠, 徐庶, 馬超, 太史慈, 張遼, 関羽, 曹仁, 袁紹, 孟達, 陸遜, 曹洪, 馬岱, 陳宮, 曹操, 魯粛, 劉備, 関平, 呂蒙, 周瑜, 董承, 司馬懿, 姜維, 許褚, 諸葛亮, 孫権, 魏延, 曹丕, 夏侯淵, 袁術, 徐晃, 劉表, 曹真, 関興, 
34
徐晃, 太史慈, 袁紹, 王允, 許褚, 孫権, 張郃, 魯粛, 呂布, 董卓, 曹丕, 関興, 陳宮, 曹操, 孟獲, 甘寧, 陸遜, 劉璋, 馬岱, 徐庶, 夏侯惇, 夏侯淵, 張遼, 龐統, 王平, 趙雲, 孫策, 関羽, 龐徳, 曹洪, 曹真, 呂蒙, 劉備, 諸葛亮, 曹仁, 貂蝉, 孫堅, 黄忠, 司馬懿, 孫乾, 馬超, 袁術, 魏延, 劉表, 姜維, 周瑜, 張飛, 董承, 関平, 孟達, 
35
関平, 魯粛, 劉璋, 董承, 張遼, 孫権, 夏侯淵, 孫乾, 王平, 呂蒙, 司馬懿, 周瑜, 諸葛亮, 曹仁, 馬超, 曹真, 陸遜, 馬岱, 夏侯惇, 関羽, 劉表, 董卓, 徐庶, 貂蝉, 甘寧, 王允, 姜維, 袁術, 曹操, 孫策, 張郃, 曹丕, 魏延, 劉備, 趙雲, 関興, 孟獲, 龐徳, 許褚, 陳宮, 呂布, 孟達, 龐統, 張飛, 孫堅, 徐晃, 袁紹, 曹洪, 太史慈, 黄忠, 
36
袁紹, 周瑜, 曹真, 魯粛, 王平, 陸遜, 曹操, 甘寧, 劉表, 魏延, 諸葛亮, 孫権, 張遼, 太史慈, 董卓, 呂布, 張郃, 呂蒙, 孟達, 袁術, 関羽, 陳宮, 黄忠, 劉備, 司馬懿, 徐晃, 馬超, 王允, 孫乾, 姜維, 龐統, 徐庶, 曹丕, 劉璋, 龐徳, 曹洪, 許褚, 貂蝉, 孫堅, 夏侯惇, 孟獲, 張飛, 馬岱, 趙雲, 関平, 董承, 孫策, 曹仁, 関興, 夏侯淵, 
37
関興, 姜維, 陸遜, 徐庶, 王允, 曹真, 呂蒙, 馬岱, 司馬懿, 関平, 趙雲, 諸葛亮, 張遼, 太史慈, 王平, 周瑜, 劉表, 魯粛, 夏侯惇, 魏延, 貂蝉, 関羽, 夏侯淵, 曹洪, 袁紹, 甘寧, 龐統, 劉備, 孟達, 董卓, 龐徳, 張飛, 孫堅, 徐晃, 馬超, 曹操, 孫乾, 董承, 曹仁, 孫権, 劉璋, 陳宮, 孫策, 許褚, 孟獲, 張郃, 袁術, 曹丕, 呂布, 黄忠, 
38
曹仁, 董承, 徐晃, 関平, 袁術, 張郃, 夏侯淵, 龐徳, 馬超, 孫堅, 夏侯惇, 龐統, 魏延, 馬岱, 甘寧, 王平, 張飛, 劉備, 許褚, 曹洪, 劉表, 袁紹, 関興, 董卓, 曹操, 趙雲, 姜維, 呂布, 孫乾, 劉璋, 徐庶, 陳宮, 関羽, 司馬懿, 孟獲, 張遼, 諸葛亮, 太史慈, 王允, 孫策, 陸遜, 貂蝉, 黄忠, 呂蒙, 曹真, 孫権, 魯粛, 曹丕, 孟達, 周瑜, 
39
陸遜, 龐統, 魯粛, 孟獲, 袁術, 袁紹, 孫堅, 周瑜, 諸葛亮, 徐庶, 曹洪, 曹真, 甘寧, 龐徳, 王平, 孫策, 張郃, 曹操, 董卓, 王允, 徐晃, 孫権, 貂蝉, 夏侯淵, 孫乾, 黄忠, 司馬懿, 張遼, 陳宮, 劉備, 馬超, 呂布, 馬岱, 関興, 董承, 曹丕, 夏侯惇, 姜維, 太史慈, 許褚, 孟達, 劉璋, 曹仁, 関平, 張飛, 関羽, 趙雲, 呂蒙, 劉表, 魏延, 
40
曹洪, 曹真, 曹丕, 曹仁, 夏侯惇, 孟達, 司馬懿, 孫策, 呂蒙, 陸遜, 董承, 孟獲, 張郃, 孫堅, 袁紹, 徐晃, 孫権, 姜維, 夏侯淵, 周瑜, 魯粛, 諸葛亮, 曹操, 許褚, 劉璋, 甘寧, 関平, 龐統, 太史慈, 龐徳, 王平, 王允, 袁術, 陳宮, 張遼, 馬岱, 劉備, 魏延, 黄忠, 趙雲, 徐庶, 馬超, 呂布, 関羽, 孫乾, 関興, 董卓, 劉表, 貂蝉, 張飛, 
41
王平, 夏侯淵, 関興, 徐晃, 姜維, 趙雲, 許褚, 太史慈, 黄忠, 張遼, 夏侯惇, 馬岱, 曹真, 孟獲, 曹洪, 張郃, 魏延, 曹仁, 龐徳, 甘寧, 関平, 馬超, 孫堅, 諸葛亮, 張飛, 司馬懿, 陸遜, 孫乾, 周瑜, 孫策, 魯粛, 関羽, 陳宮, 龐統, 徐庶, 曹操, 孟達, 呂蒙, 孫権, 劉備, 袁紹, 董承, 董卓, 呂布, 貂蝉, 袁術, 劉璋, 王允, 曹丕, 劉表, 
42
劉璋, 劉表, 徐庶, 馬超, 孫乾, 黄忠, 甘寧, 夏侯淵, 司馬懿, 曹丕, 関平, 劉備, 袁紹, 張遼, 曹真, 孟達, 孫策, 諸葛亮, 張郃, 曹仁, 関羽, 曹操, 魯粛, 龐徳, 孫権, 夏侯惇, 呂蒙, 魏延, 陸遜, 曹洪, 趙雲, 龐統, 呂布, 董承, 張飛, 姜維, 孫堅, 袁術, 王平, 徐晃, 関興, 馬岱, 貂蝉, 陳宮, 董卓, 太史慈, 王允, 周瑜, 孟獲, 許褚, 
43
夏侯淵, 許褚, 王平, 夏侯惇, 馬超, 孫乾, 劉璋, 趙雲, 曹洪, 袁術, 関羽, 司馬懿, 張遼, 魏延, 関平, 曹仁, 孫権, 徐晃, 張郃, 曹操, 孟獲, 劉備, 孫堅, 孟達, 太史慈, 張飛, 劉表, 諸葛亮, 袁紹, 曹真, 陸遜, 周瑜, 魯粛, 黄忠, 龐統, 貂蝉, 董承, 龐徳, 徐庶, 孫策, 董卓, 呂布, 曹丕, 姜維, 甘寧, 王允, 馬岱, 呂蒙, 関興, 陳宮, 
44
馬岱, 呂布, 関平, 張飛, 董卓, 馬超, 魏延, 陳宮, 趙雲, 張郃, 張遼, 徐庶, 姜維, 孫乾, 関羽, 董承, 袁紹, 劉備, 司馬懿, 貂蝉, 夏侯淵, 劉璋, 王平, 王允, 孟獲, 黄忠, 曹真, 曹操, 曹仁, 曹洪, 夏侯惇, 龐徳, 太史慈, 孟達, 許褚, 孫堅, 関興, 徐晃, 諸葛亮, 龐統, 甘寧, 陸遜, 劉表, 袁術, 呂蒙, 孫策, 孫権, 曹丕, 周瑜, 魯粛, 
45
董卓, 曹丕, 孫策, 夏侯惇, 魯粛, 袁紹, 太史慈, 曹真, 呂蒙, 王允, 袁術, 呂布, 孫権, 陳宮, 曹仁, 曹操, 甘寧, 徐晃, 貂蝉, 許褚, 孫堅, 周瑜, 曹洪, 張遼, 劉表, 司馬懿, 孟達, 関興, 関平, 夏侯淵, 張郃, 劉備, 陸遜, 諸葛亮, 孟獲, 劉璋, 徐庶, 董承, 姜維, 馬岱, 関羽, 馬超, 張飛, 孫乾, 趙雲, 龐統, 魏延, 龐徳, 王平, 黄忠, 
46
貂蝉, 関平, 馬岱, 孟獲, 董卓, 夏侯淵, 孟達, 張飛, 龐徳, 黄忠, 董承, 王平, 劉表, 許褚, 孫策, 曹真, 曹洪, 孫堅, 曹丕, 馬超, 劉備, 龐統, 諸葛亮, 魏延, 張郃, 魯粛, 呂布, 曹操, 趙雲, 太史慈, 孫権, 陳宮, 関羽, 徐庶, 司馬懿, 王允, 姜維, 徐晃, 関興, 陸遜, 袁紹, 夏侯惇, 孫乾, 張遼, 周瑜, 袁術, 劉璋, 呂蒙, 曹仁, 甘寧, 
47
孫権, 孟獲, 呂蒙, 孟達, 劉表, 孫乾, 孫策, 孫堅, 曹丕, 魯粛, 徐庶, 陸遜, 太史慈, 袁紹, 関平, 周瑜, 呂布, 張郃, 曹真, 袁術, 夏侯淵, 劉備, 魏延, 董卓, 甘寧, 張飛, 王平, 劉璋, 曹仁, 趙雲, 許褚, 司馬懿, 曹操, 夏侯惇, 陳宮, 徐晃, 関羽, 馬超, 董承, 諸葛亮, 黄忠, 龐統, 馬岱, 関興, 王允, 龐徳, 張遼, 曹洪, 姜維, 貂蝉, 
48
孫乾, 許褚, 張遼, 董承, 袁術, 孫堅, 袁紹, 孟達, 陸遜, 関平, 夏侯惇, 劉璋, 孟獲, 関羽, 司馬懿, 魯粛, 張飛, 董卓, 曹真, 甘寧, 曹丕, 曹操, 劉備, 孫策, 曹洪, 陳宮, 呂布, 呂蒙, 周瑜, 孫権, 劉表, 王允, 龐統, 龐徳, 趙雲, 諸葛亮, 貂蝉, 夏侯淵, 曹仁, 太史慈, 姜維, 徐晃, 馬岱, 関興, 徐庶, 黄忠, 魏延, 王平, 馬超, 張郃, 
49
孫乾, 関興, 龐徳, 董卓, 曹丕, 張飛, 貂蝉, 王允, 徐晃, 孟獲, 袁術, 孫堅, 張遼, 黄忠, 関羽, 劉備, 呂布, 許褚, 曹操, 趙雲, 徐庶, 太史慈, 司馬懿, 陳宮, 魏延, 袁紹, 馬岱, 曹洪, 張郃, 董承, 劉表, 夏侯惇, 姜維, 呂蒙, 諸葛亮, 夏侯淵, 馬超, 関平, 劉璋, 王平, 孫策, 魯粛, 曹真, 周瑜, 曹仁, 陸遜, 孫権, 孟達, 甘寧, 龐統, 
50
関平, 太史慈, 王平, 張郃, 姜維, 魏延, 陸遜, 関興, 呂蒙, 王允, 司馬懿, 許褚, 馬超, 曹丕, 徐晃, 黄忠, 関羽, 龐徳, 馬岱, 孟達, 趙雲, 董卓, 呂布, 孫堅, 周瑜, 孫乾, 諸葛亮, 孫権, 陳宮, 張遼, 貂蝉, 劉璋, 董承, 孟獲, 曹仁, 劉備, 曹操, 曹真, 張飛, 徐庶, 魯粛, 甘寧, 夏侯惇, 孫策, 夏侯淵, 袁術, 曹洪, 袁紹, 龐統, 劉表, 
51
孟達, 徐庶, 張郃, 徐晃, 龐統, 呂蒙, 夏侯惇, 曹仁, 曹洪, 孫乾, 張遼, 姜維, 魯粛, 劉表, 曹操, 許褚, 陳宮, 甘寧, 諸葛亮, 曹丕, 孫策, 趙雲, 孫権, 関平, 龐徳, 劉備, 魏延, 袁紹, 袁術, 呂布, 劉璋, 関羽, 陸遜, 張飛, 周瑜, 貂蝉, 司馬懿, 黄忠, 曹真, 孟獲, 馬超, 馬岱, 夏侯淵, 太史慈, 董承, 孫堅, 関興, 董卓, 王允, 王平, 

いかがでしょうか?

どこかの次元を見て、これが武力順!これが蜀忠義順!などの
なんらかの意味がある情報が見つかっただろうか?
(もし見つけた人がいらっしゃれば、ぜひ教えていただきたい)

全く無作為な順番の羅列のようにも見えるのだが、
これが、さきほどまで武将の似ている度や演算をしていた、
機械学習済みモデルの中身そのもの。

機械学習結果を、人間が「理解」することは難しいと言われており、
それがよく表れていると思う。

人間だったら、武将を数値化したければ、やはり、
武力、知力、忠誠心、所属国、活躍した時代、等で数値化するだろうが、
機械(えーあい)は何を以て数値化したのだろうか?
それでいて、出来たモデルを「使う」際にはそれなりの結果が出ている。

呂布「なるほど!(全くわからん)」
張飛「ウムッ!(全くわからん)」
許褚「良く分かった!(全くわからん)」
曹操「(セリフにする人の人選を誤ったな・・・)」

最強の武(の値)を求めるのは簡単な道ではないのだ。
(次回へ続く・・・?)

Word2Vec編の終わり

仲達「こんなに長い記事を書いているなんて、
   フフフ、諸葛亮も長くはないぞ!」

長くなりすぎた。
キリも良いので、作者と読者の健康のために一旦ここまでで切る。
前回も見たなコレ

ここまでで、
吉川英治三国志の小説を自然言語処理して、
その結果を機械学習にかけることで、
Word2Vecモデルを得ることが出来た。
すなわち、武将を50次元のベクトルとして数値で表現できた

武将同士の「似ている度」「演算」が出来るという、
モデルの使い方も分かり、その演算の結果、
孫権と甘寧の関係を改めて確認することができ、
三国志の世界がそれなりに投影されたモデルである
ことも分かった。

一方で、その機械学習モデルの中身をよく見ても、
「武力」「知力」などの軸を取り出すのには、
まだ工夫が必要であることも分かった。

これは困った。
むむむ!

なにがむむむだ!
甘寧の演算が出来るほどなのだから、
どこかに武力・知力に相当するデータは存在するハズッ!
何か風向きを変える策さえあれば・・・。

風向きというか気が向いたら次回も書く。
話が難しくなってきたしまとめるの結構大変で疲れた。

さて、内容が深くなりすぎて、
前回よりもさらに三国志マニアック度が上がってしまったが、
まだ読んでいる人が居るのだろうか・・・?

(オマケ)前回のSEKIHEKIのたた会の参加者のみなさまへ

主催者より。

おかげさまで前回のイベントは
岸が赤く燃えがあるほどの大盛り上がりになりました。
参加していただいた皆様に感謝と御礼を申し上げます。
(全く予想しないほど三国志ファンが多く驚きました)

あるニートのLTはとくに大好評で、彼は
三個の零(=年俸1000万円超)で某スタートアップに迎えられました。

彼が発表したライブラリ「石兵八陣」は、
早速、真似をする人が続出してしまい、
利用者から「前に見た/似たようなライブラリが多くて迷う」と
言われるほどの大人気です。

ただ、スポンサー様が「げぇ、関羽!」と
叫んで逃げてしまいまして、
次回開催の応援者様を募集中です。


関羽「えっ、ワシのせいなの!?」

★追記:完結編、書きました。
https://qiita.com/youwht/items/61c6d5819cdc3aff9e63

以上。

239
121
9

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
239
121