🌟

【自然言語処理】【Python】Word2Vecを使って「人生」から「愛」を引いたら何が残るかを計算してみた

2022/07/31に公開

はじめに

自然言語処理の学習を進める中で、最初に驚くのが、単語をベクトルであらわしたことではないでしょうか。
単語をベクトル化することで、単語の四則演算が可能になる。
有名な例では、王様から男性を引いて女性を足すと女王になるというのがありますね。
ここではもう少し哲学的に踏み込んで、「人生」から「愛」を引いたら何が残るのか? Word2Vecを解明したいと思います。**

Word2Vecについてはコチラを参照

https://zenn.dev/robes/articles/61847e68587b98

ライブラリのインストール

gensimを使います。

!pip install gensim

学習済みモデルWord2Vecのダウンロード

こちらからモデルをダウンロード http://bit.ly/2srnKoy
zipを解凍して、ja.binというファイルを使用します。

モデルのロード

import gensim
model = gensim.models.Word2Vec.load('/content/ja.bin')

「人生」の類似語を調べる

まずは、Word2Vecの分散表現を使って、人生という言葉の類似語を調べてみます。

for item, value in model.wv.most_similar('人生'):
    print(item,value)

出力結果
なんとなく、合っている気がしますね。

心境 0.5031609535217285
運命 0.4962955415248871
幸福 0.4731469750404358
僕 0.45822054147720337
老後 0.44594892859458923
著書 0.4451371133327484
半生 0.4450538754463196
思索 0.4410485029220581
永遠 0.43776482343673706
一生 0.43756037950515747

「人生」から「愛」を引いてみる

実際にWord2Vecを使って、単語ベクトルの演算をやってみます。
コードは次のとおりです。

model.wv.most_similar(positive=['人生'],negative=['愛'])

出力結果
1位は「キャリア」、2位は「カネ」、ということです。
9位の「メジャーリーガー」はよくわかりませんが。。。

[('キャリア', 0.3442475199699402),
 ('カネ', 0.33152854442596436),
 ('チャンス', 0.2999703586101532),
 ('老後', 0.29941919445991516),
 ('サリヴァン', 0.29740941524505615),
 ('苦難', 0.2900192439556122),
 ('成果', 0.286318302154541),
 ('一般理論', 0.2787232995033264),
 ('メジャーリーガー', 0.2783268094062805),
 ('プレッシャー', 0.27150285243988037)]]

定番の「王様」+「女性」ー「男性」をやってみる

model.wv.most_similar(positive=['王','女'],negative=['男'])

出力結果
王女がでてきました

[('王女', 0.4609297811985016),
 ('王位', 0.4463587999343872),
 ('女王', 0.440536767244339),
 ('王家', 0.4360467791557312),
 ('父王', 0.4177766740322113),
 ('王妃', 0.4131211042404175),
 ('マガダ', 0.410072922706604),
 ('ファラオ', 0.4071836471557617),
 ('ベーラ', 0.404167115688324),
 ('カッパドキア', 0.40059027075767517)]

fastTextでも計算してみる

学習済みモデルfastTextをダウンロード

こちらからモデルをダウンロードfastText
zipを解凍して、model.vecというファイルを使用します。

モデルのロード

import gensim
model = gensim.models.KeyedVectors.load_word2vec_format('/content/model.vec',binary=False)

「人生」の類似語を調べる

  • その前に「人生」の特徴量ベクトルを求める。
  • 300次元あります。ちなみにWord2Vecは100次元でした。
 word = '人生'
print(f'{word}の特徴量のベクトル')
print(model[word])
model[word].shape

出力結果

(300,)
print(f'{word}の類似語')
for item ,value in model.most_similar(word):
    print(item,value)

出力結果
Word2Vecに比べて、より具体的になっている印象です。

人生の類似語
生き方 0.643797755241394
生きる 0.5911297798156738
生涯 0.5900983810424805
一生 0.5889523029327393
人生観 0.5824947953224182
生きること 0.5823161602020264
幸せ 0.574641227722168
青春時代 0.5740978717803955
結婚生活 0.5648994445800781
思い出 0.5635090470314026

「人生」から「愛」を引いてみる

model.most_similar(positive=['人生'],negative=['愛'])

出力結果
類似語と同様に具体的すぎますね。
fastTextのような優秀なモデルは、ざっくりとしたテーマには向かないようです。

[('振り返り', 0.34721365571022034),
 ('選手生活', 0.32623374462127686),
 ('プロ生活', 0.3085706830024719),
 ('キャリア', 0.30444127321243286),
 ('人生設計', 0.2932748794555664),
 ('経歴', 0.2895069122314453),
 ('生活', 0.283188134431839),
 ('転機', 0.2803061604499817),
 ('振り返っ', 0.27186983823776245),
 ('やり直す', 0.2653588056564331)]

さいごに

ドイツの詩人シラーは言いました。
「愛の光なき人生は無価値である」 語録より
シラーは「愛の光なき人生は無価値である」と言いましたが、必ずしも無価値ではなさそうですね。

Discussion