自民と希望の政策キーワードを可視化してみた

今日の衆議院選挙の参考に、自民党希望の党の政策テキストを2次元マップに可視化してみた。
詳しい方法は後に回すとして、まずは結果から。

自民党、全体。中心はごちゃごちゃしてよく分からないが、「農業」とか「革命」などが意味的に突出しているようだ。

自民党、ごちゃごちゃを拡大。なんとなく重要キーワードが群を成している。

自民党、さらに拡大。

個人的に気になる、「IoT, ICT」といったキーワードは、「加速、活躍、所得」に近いらしい。
一方、「税」は「削減、適切」に、「データ」は「外国、着実、総合」に近いのだろうか。

希望の党、全体。こちらでは「政府, 検討」などが大きく外れている。

希望の党、ごちゃごちゃを拡大。

希望の党、さらに拡大。

こちらでは「EV, ユリノミクス, エネルギー」といったキーワードが目立つ。
眺めていると、どことなく自民党と集まり方が違う。

試しに両方の党で、「日本」「原発」といったキーワードに近い単語を出力すると、こんな感じに。

自民党
・CHECK_WORD= 日本
1. 事案 0.8811548352241516
2. 紛争 0.869037389755249
3. 則る 0.8689562678337097
4. 出す 0.8679717779159546
5. サイクル 0.8678414821624756
6. ハブ 0.8675268888473511
7. 仲裁 0.8667996525764465
8. 結論 0.8663533926010132
9. 額 0.865086019039154
10. 柱 0.863643229007721

・CHECK_WORD= 原発
1. 区域 0.9755296111106873
2. 暮らし 0.9720321893692017
3. 総務 0.9708766937255859
4. 支払 0.9689890742301941
5. 省 0.9675025939941406
6. 統合 0.9669897556304932
7. 直接 0.9648252129554749
8. ほとんど 0.9646211862564087
9. 除く 0.9640038013458252
10. 方針 0.9639186859130859

希望の党
・CHECK_WORD= 日本
1. 満たす 0.9634389877319336
2. 率 0.9588447213172913
3. 都市 0.9553815126419067
4. 踏まえる 0.9451758861541748
5. 水産 0.9422210454940796
6. 徹底 0.9415571093559265
7. 近海 0.9351164102554321
8. 他国 0.9350647926330566
9. ガイドライン 0.930781364440918
10. 道路 0.9273162484169006

・CHECK_WORD= 原発
1. 老朽 0.9683917760848999
2. 方針 0.9643222689628601
3. 額 0.9633558988571167
4. 経験 0.9626327753067017
5. 公費 0.9625997543334961
6. 総合 0.9602236747741699
7. 以上 0.9596429467201233
8. 20 0.9584065079689026
9. 40 0.9578380584716797
10. 補てん 0.955456018447876


■ 方法

(1). 各党のホームページから、政策が書かれたテキストを取得した。
自民党: 衆議院選挙公約2017, 政策BANK >> https://special.jimin.jp/political_promise/bank/
希望の党: 政策について >> https://kibounotou.jp/policy/

(2). 各テキストを、Python分かち書き"janome"を用いて単語に分解した。
日本語形態素解析器"janome" >> http://mocobeta.github.io/janome/
分かち書きの際、['助詞', '助動詞', '記号'] は除外し、活用のある単語は原型とした。以下のような感じ。

* 自民党テキスト

Ⅰ . 経済 再生
生産 性 革命
少子 高齢 化 最大 壁 立ち向かう ため 生産 性 革命 人 づくり 革命 断行 する この 2 大改革 新しい 経済 政策 パッケージ 年内 取りまとめる
ロボット IoT 人工 知能 AI 生産 性 劇的 押し上げる 最先端 イノベーション 起こす 生産 性 革命 実現 する
2020 年 3 年間 生産 性 革命 集中 投資 期間 大胆 税制 予算 規制 改革 あらゆる 施策 総動員 する
人手 不足 高齢 化 補う ため ロボット IoT 人工 知能 AI 企業 生産 性 飛躍 的 高める 投資 推進 する 特に 生産 性 低い 業種 中堅 企業 中小 企業 小規模 事業 者 集中 的 支援 する

* 希望の党テキスト

政策 集 私 たち 目指す 希望 道
1 政治 希望  〜 徹底 する 情報 公開 透明 性 高い 政治 実現 〜
特区 等 事業 者 選定 その 選定 過程 国民 全て 開示 する
企業 団体 献金 ゼロ 法的 義務付ける
地方 議員 政務 活動 費 公開 同様 国会 議員 文書 通信 交通 滞在 費 使途 公開 義務付ける
衆議院 参議院 対等 統合 一院制 迅速 意思 決定 可能 する 議員 定数 議員 報酬 国会 運営 費用 大幅 削減 する


(3). Python の gensim, word2vec を用いて、取り出した単語をベクトル化した。
分かち書きしたテキストを、以下のようなコードに放り込むだけ。

from gensim.models import word2vec

sentences = word2vec.LineSentence( INPUT_FILE )
model = word2vec.Word2Vec(sentences,
                          sg=1,
                          size=100,
                          min_count=1,
                          window=10,
                          hs=1,
                          negative=0 )
model.save( OUTPUT_FILE )

(4). できあがった word2vecモデルを t-SNEという方法で2次元に圧縮し、プロットした。
# 参考: gensimのword2vecの結果を手軽に可視化する方法 >> https://hacknote.jp/archives/25247/

import numpy as np
from gensim.models import word2vec
from sklearn.manifold import TSNE
import matplotlib.pyplot as plt 
from matplotlib.font_manager import FontProperties

# word2vecで作成したモデルのファイル名
#INPUT_MODEL = "w2v_jimin.model"
INPUT_MODEL = "w2v_kibo.model"

#vocab_thresh   = 7    # 自民の場合、7回以上登場する単語を拾う、258単語だった
vocab_thresh = 3    # 希望の場合、3回以上登場する単語を拾う、197単語だった

if __name__ == "__main__" :
    
    word2vec_model = word2vec.Word2Vec.load( INPUT_MODEL )

    # 単語の一覧を取得する
    vocabs = []
    for word, vocab_obj in word2vec_model.wv.vocab.items():
        if vocab_obj.count >= vocab_thresh:    # N回以上登場する閾値
            vocabs.append( word )
    
    n_vocab = len(vocabs)
    print( u"単語数={}", n_vocab )
    
    emb_tuple = tuple([word2vec_model[v] for v in vocabs])
    X = np.vstack(emb_tuple)
    
    model = TSNE(n_components=2, random_state=0)
    np.set_printoptions(suppress=True)
    model.fit_transform(X) 
    
    # matplotlibで t-SNEの図を描く
    skip = 0
    limit = n_vocab  # 全単語を出力しよう
    
    # 日本語フォント対応、Windowsの場合
    fp = FontProperties(fname=r'C:\WINDOWS\Fonts\YuGothB.ttc', size=14)
    
    plt.figure( figsize=(40,40) )
    plt.scatter( model.embedding_[skip:limit, 0], model.embedding_[skip:limit, 1] )
    
    count = 0
    for label, x, y in zip(vocabs, model.embedding_[:, 0], model.embedding_[:, 1]):
        count +=1
        if( count < skip ): continue
        plt.annotate(label, xy=(x, y), xytext=(0, 0), textcoords='offset points', fontproperties=fp)
        if( count == limit ): break
    
    plt.show()

こうして出来たのが、最初に挙げたテキストマップというわけ。