自民と希望の政策キーワードを可視化してみた
今日の衆議院選挙の参考に、自民党と希望の党の政策テキストを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()
こうして出来たのが、最初に挙げたテキストマップというわけ。