word2vecで平和について考えてみた

# はじめに
マス目に単語を書き込むことで思考整理、思考を広げるのに役立つマンダラートというものがあります。本来マンダラートは人間が行うものですが、今回はAIの力でそれをやってみるという実験です。
これは完全に趣味でやってたことで、記事にするつもりじゃなかったのでいろいろと雑ですが、温かい目で見てください。

# マンダラートとは？
参考:

https://www.hrbrain.jp/media/human-resources-development/mandalart

9×9のマス目を用意し、その中心に考えを深めたいテーマを置きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1751564/47800d73-abee-e243-f3b9-3fa1a762ceaa.png)

テーマの周囲8マスに、テーマに関連することを書いていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1751564/21184d20-6ed2-b2fd-fbbd-f9c5bb066f1a.png)

周囲に書いたことを、3×3のマスの中心に書きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1751564/ee9ff4d6-7c53-5030-1cf6-e6e587de4b19.png)

先ほどと同じように中心に関連することを書く作業を8回やって完成です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1751564/85470238-600a-8ab1-904f-dac3f3655265.png)


このようにすることで、テーマをより深く掘り下げることができ、思考が深まる（らしい）。

# word2vecって何？
今回マンダラートを埋めるために使用するのはword2vecというものです。
word2vecは単語の意味的な関係性をベクトルで表現する手法のことで、単語同士の類似度計算や機械学習の入力としても活用されています。
マンダラートはテーマと関連する単語を並べていくことで思考を深めるものなので、このword2vecと相性がいいはずです。


参考になる記事：

https://qiita.com/g-k/items/69afa87c73654af49d36

１から学習するのは面倒なので、今回は [chiVe](https://github.com/WorksApplications/chiVe?tab=readme-ov-file) という学習済みモデルを使用させていただきました。
chiVeは（私が調べた限りでは）日本語word2vecモデルの中で性能や語彙数が一番良さそうなモデルでした。

# Pythonプログラム
最初に言っておきます。自分用なので***クッソ雑***です。動けばいいやろ精神で、謎に二次元配列からDataFrameに変換したりしてます。参考にしない方がいいです。
```python:chive_mandala.py
import gensim
import pandas as pd

#モデル読み込み
vectors = gensim.models.KeyedVectors.load("./chive-1.3-mc5_gensim/chive-1.3-mc5.kv")

#中央に入れる単語を設定
origin = "平和"
print("テーマは" + origin)

#マンダラート用二次元配列
data=[["", "", "", "", "", "", "", "", ""],
      ["", "", "", "", "", "", "", "", ""],
      ["", "", "", "", "", "", "", "", ""],
      ["", "", "", "", "", "", "", "", ""],
      ["", "", "", "", "", "", "", "", ""],
      ["", "", "", "", "", "", "", "", ""],
      ["", "", "", "", "", "", "", "", ""],
      ["", "", "", "", "", "", "", "", ""],
      ["", "", "", "", "", "", "", "", ""]]
def assign_array(word_suggestions, central_value, origin_word):
    data[central_value[1]][central_value[0]] = origin_word
    x, y = central_value  # 中心座標を設定
    dx = [-1, 0, 1, 1, 1, 0, -1, -1]  # x方向の移動量
    dy = [-1, -1, -1, 0, 1, 1, 1, 0]  # y方向の移動量
    for i in range(8):
        nx, ny = x + dx[i], y + dy[i]  # 次の座標を計算
        data[ny][nx] = word_suggestions[i]  # 単語を配置

    return data

#Word2Vecを実行し、中央の単語と被っているものを排除した上位8位を出力する関数
def w2v(origin_word):
    topn_volume = 20    #候補数
    output_words = []    #出力用の入れ物
    output_volume = 8    #出力数

    #Word2Vec実行
    similar_words = vectors.most_similar(origin_word, topn=topn_volume)

    # 単語のみを格納する一次元の配列に変換
    words_only = [word for word, _ in similar_words]

    #中央の単語と被っているものを除外
    for i in range(topn_volume):
        if not origin_word in words_only[i]:
            output_words.append(words_only[i])
        if len(output_words) == output_volume:
            break
    return output_words

#中央9マスの推論&格納
assign_array(w2v(origin),[4,4], origin)
assign_array(w2v(data[3][3]),[1,1], data[3][3])
assign_array(w2v(data[3][4]),[4,1], data[3][4])
assign_array(w2v(data[3][5]),[7,1], data[3][5])
assign_array(w2v(data[4][3]),[1,4], data[4][3])
assign_array(w2v(data[4][5]),[7,4], data[4][5])
assign_array(w2v(data[5][3]),[1,7], data[5][3])
assign_array(w2v(data[5][4]),[4,7], data[5][4])
assign_array(w2v(data[5][5]),[7,7], data[5][5])
for i in data:
    print(i)
df = pd.DataFrame(data)
df.to_excel("output.xlsx")
```

# 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1751564/2fa5577b-420c-5149-9c8b-41ea8757ebb8.png)

核関連のワードが多いですね。chiVeのデータセットはインターネットからスクレイピングしたものが多いので、その中に核関連の記事がたくさんあったんでしょうか？

# おわりに
マンダラートをword2vecで埋めるという目的が達成できたので満足です。
word2vecのベクトルはデータセットに依存しているので、国や言語によってどのような差が生まれるか気になりました。