pPolis2024-10-29
nishio 東大谷口研の2022年参院選でのデータからUMAPで可視化した、共産島(共産党の島)とかができてる https://gyazo.com/da86893dd4e4a0d4e8321f820251d9c9
https://gyazo.com/7483712c10cac770769da024e2bcfb3e
https://gyazo.com/93b7e7dd8c963b8f79e480aeee3d60ee
https://gyazo.com/ded0f771d275222169bd06dddcf01d5f
https://gyazo.com/843b394913c884514e61f3cffc752789
https://gyazo.com/a5ee7ba2f0041965ad410920eb56fbbchttps://gyazo.com/eded459106b9331a9b8e018bd4ab3475
https://gyazo.com/1e04477f03347e2d01a6fc6d86264011https://gyazo.com/f06909d884fe0dad9b8c15503af76fb1https://gyazo.com/07ee5f54c0bb37176cda5662cf6710ff
https://gyazo.com/8676b0ea7e03071e89bc0169b408eb64
https://gyazo.com/c89cf28104d5923186df3a996c737c60
code:py
import umap
# UMAPによる次元削減
reducer = umap.UMAP(
n_neighbors=15, min_dist=0.1, n_components=2, random_state=42, n_jobs=1
)
embedding = reducer.fit_transform(matrix)
# UMAPの結果を含むDataFrameを作成し、matrixのインデックス(User_ID)を含める
umap_df"User_ID" = matrix.index # matrixのインデックスをUser_IDとする # dataにUser_ID列を追加してから、umap_dfとマージ
data = data.reset_index().rename(
columns={"index": "User_ID"}
) # User_IDとしてインデックスを追加
merged_data = pd.merge(data, umap_df, on="User_ID", how="inner") # User_IDで結合
# 政党名の列を追加
data = merged_data
# カラーマップの準備
unique_parties = data"PARTY".unique() colors = plt.cm.tab10(np.linspace(0, 1, len(unique_parties)))
parties_letter = {
"自民党": "自",
"立憲民主党": "立",
"公明党": "公",
"日本維新の会": "維",
"国民民主党": "国",
"共産党": "共",
"社民党": "社",
"れいわ新選組": "れ",
"NHK党": "N",
"参政党": "参",
"諸派": "諸",
"無所属候補": "無",
}
# 可視化
plt.figure(figsize=(10, 7))
for i, party in enumerate(unique_parties):
party_data = data[data"PARTY" == party] pname = political_partiesparty pletter = parties_letter[political_partiesparty] plt.scatter(
s=0,
marker="+",
label=f"{pname}({pletter})",
)
for p in party_data.iterrows():
plt.text(
s=pletter,
fontsize=5,
ha="center",
va="center",
)
plt.title("Political Parties UMAP Visualization")
plt.xlabel("UMAP1")
plt.ylabel("UMAP2")
plt.legend(title="政党")
plt.show()
割とクラスタが分かれてくれるので、次はこれにPolis的クラスタ特徴抽出を掛けて、世論地図的なAIクラスタ解説をすると面白い
---
2022年参院選のPolis的可視化に関して、以前はPCAでやってて、先日その主成分軸をAIに解説させてあまり面白くなくて
それを踏まえて「じゃあ軸に意味が見出せなくてもいいから別の方法で可視化してもいいよね」とTalk to the Cityで使われてるUMAPを使ってみたものがこちら
なんかそれっぽく別れてますね
共産党だけで集まってる離れ小島の「過激な共産党」と他の政党と同居してる「マイルド共産党」がいて面白い
自民もそう
維新の離れ小島に混ざってる自民党の人は誰だw(もちろん調べればわかる)
UMAPしてからクラスタリングしてAIに解説させようかと思ってたけど、こんな感じに別れるならはっきり分かれてるのは人間が範囲指定してクラスタにしての大きい島だけクラスタリングで数個に分けた方が納得感が高いかも
---
文脈を補うと、600人でPCAしたら二分割にしかならなかったこのデータでもUMAPしたら6つにわかれたわけなので、世論地図の二分割になってるものもUMAPを使えば細かく分かれた詳細地図ができるかもねという予備実験でした
---
Scatterから範囲選択してどこが選択されたか表示
code:py
# 選択範囲内のデータを表示する関数
def on_select(eclick, erelease):
x1, y1 = eclick.xdata, eclick.ydata # 選択範囲の開始点
x2, y2 = erelease.xdata, erelease.ydata # 選択範囲の終了点
# 選択範囲とデータを表示
print(
)
from matplotlib.widgets import RectangleSelector
# RectangleSelectorを使用して選択イベントを監視
fig, ax = plt.subplots()
selector = RectangleSelector(ax, on_select, useblit=True, button=1, interactive=True) # 可視化
# plt.figure(figsize=(10, 7))
for i, party in enumerate(unique_parties):
party_data = data[data"PARTY" == party] pname = political_partiesparty pletter = parties_letter[political_partiesparty] ax.scatter(
s=0,
marker="+",
label=f"{pname}({pletter})",
)
for p in party_data.iterrows():
ax.text(
s=pletter,
fontsize=5,
ha="center",
va="center",
)
plt.title("Political Parties UMAP Visualization")
plt.xlabel("UMAP1")
plt.ylabel("UMAP2")
plt.legend(title="政党")
plt.show()
https://gyazo.com/5e7cd8225308b38dc02f6255d9742445
https://gyazo.com/ee781335c743d0654b1784f1805ce56b
いまPolis的分析(Polisのリアルタイム散布図を省いたもの)を一つのコードでやってるけど、部品が理解できてきたから分解していこう クラスタの集合を与えられて、そのクラスタの中と外を分ける特徴的な意見をだす部品
図ではフィッシャー正確検定と描いているが正確な名称ではない
なのだけどそもそも技術的に同じものを使っているってだけの話で、部品の使用意図は全く異なってる
違うクラスタかどうかを検定しているのではなく、検定する時に使われる尺度をクラスタを特徴付ける質問を選ぶときの尺度に流用している
たぶんこの部分を部品として扱ってないから概念を表現するのに適切な言葉がまだない
この部品の部分を切り出して独立して使えるようにしたい
同じように世論地図のデータもUMAPして政党アイコンを出せば政党に代表されていない意見クラスタがわかるかもな〜
---
2024-10-31
nishio 1枚目この範囲の議員が持ってる特徴的な意見ベクトルが2枚目 https://gyazo.com/840f96feb977be80294a6dc75e5b9c31https://gyazo.com/1ac5ee3e873990fc3b63f176b17fa3d7
nishio AIが勝手にクラスタリングするだけではなく、人間が「この範囲」と指定して分析できるようになったって話 https://gyazo.com/d230fddf28841c8e2f5d3c323dd64ca9
このクラスタの中でさらに左上の純粋共産島と他の部分にどういう意見の差があるのか見たくなってきた
数学的にはできるはずだ...
技術的には...
挫折した(少なくともチョチョイとできることではなかった)
諦めて個別クラスタをやったら意外と目的が達成された
結果はここにおいた