桐間紗路研究所日報

技術以外の話→ https://kirimasyaro.hateblo.jp

報告:えらぼーと結果の集計による世論調査

 えらぼーと( https://vote.mainichi.jp/ )というのがあります。簡単な質問でどの政党に自分の思想が近いかわかるっぽいです。

 このサイトはツイッターで結果を自分語りすることができて、

日本を、トリモロス! 考えが近い政党は維新(39%)でした。えらぼーと2019参院選を試してみよう! #えらぼーと #ボートマッチ #選挙 #参院選 https://t.co/c2vvJ9k0fJ @mainichieravote

というような形式でツイッターに投稿されます。これを検索すれば、ツイッターでの政党支持の傾向がわかるんじゃないかと思って、1700件ほど収集してみました。

概要

 1738ツイートが取得でき、分析対象はそのうちリツイートを除く1304ツイートとします。さらに、その中で有効であったツイート(分析結果についてのツイート)は845個でした。 f:id:copuy:20190709013324p:plain

こんな感じで抽出できました。

from twitter import *
from auth import auth
import os, sys, json, re, time

def search(q, ):
    t, _ = auth()
    allmsg = t.search.tweets(q=q, count=200)["statuses"]
    for i in range(30):
        max_id = allmsg[-1]['id'] - 1
        msg = t.search.tweets(q=q, count=200, max_id=max_id)["statuses"]
        if len(msg) == 0:
            break
        allmsg += msg
        time.sleep(1)
    return allmsg

def main():
    js = search(q='#えらぼーと #ボートマッチ #選挙 #参院選 https://vote.mainichi.jp/ @mainichieravote')
    with open('result.json', 'w') as f:
        json.dump(js, f, ensure_ascii=False, indent=2)

if __name__ == '__main__':
    main()

auth.pyの中身は

    t = Twitter(
        auth=OAuth(oauth_token, oauth_secret, CONSUMER_KEY, CONSUMER_SECRET)
    )
    t_media = Twitter(
        auth=OAuth(oauth_token, oauth_secret, CONSUMER_KEY, CONSUMER_SECRET),
        domain='upload.twitter.com'
    )
    return t, t_media

みたいになってます。これで生成されたresult.jsonに対して以下の処理をします。

from twitter import *
from auth import auth
import os, sys, json, re, time

def main():
    ans = []
    t, _ = auth()
    with open('result.json', 'r') as f:
        js = json.load(f)
    for x in js:
        if not "retweeted_status" in x.keys():
            xx = re.findall(
                r'考えが近い政党は(.*)でした。えらぼーと2019参院選を試してみよう! #えらぼーと #ボートマッチ #選挙 #参院選',
                x['text']
            )
            if xx != []:
                ans.append(xx)
                print(xx)
    print(len(js), len(ans))


if __name__ == '__main__':
    main()

pythoncollections.Counterで結果を見てみます。

[('国民', 213),
 ('社民', 201),
 ('維新', 200),
 ('幸福', 179),
 ('立憲', 97),
 ('共産', 92),
 ('公明', 88),
 ('オリ', 87),
 ('自民', 26),
 ('労働', 19),
 ('ありません', 2),
 ('◯◯', 1),
 ('❌❌', 1),
 ('幸福実現党', 1),
 ('れ新', 1),
 ('安楽', 1),
 ('N国', 1),
 ('○○', 1),
 ('立憲民主党', 1)]

一部、ツイートを改変した人がいるために変なのがヒットしてます。 国民民主党社民党、維新の会、幸福実現党、の順に支持されているようです…

支持の組み合わせ別では、

[('幸福', 156),
 ('維新', 150),
 ('国民', 134),
 ('公明', 60),
 ('社民', 50),
 ('共産、社民', 40),
 ('立憲', 23),
 ('社民、オリ', 18),
 ('オリ', 16),
 ('立憲、社民', 15),
 ('立憲、共産、社民', 14),
 ('立憲、国民', 14),
 ('国民、社民', 12),
 ('自民', 12),
 ('国民、維新', 11),
 ('維新、幸福', 10),
 ('公明、維新', 10),
 ('共産、社民、オリ', 9),
 ('国民、共産、社民', 8),
 ('立憲、社民、オリ', 6),
 ('立憲、共産、社民、オリ', 5),
 ('公明、国民', 4),
 ('労働', 4),
 ('自民、維新', 4),
 ('自民、公明', 4),
 ('国民、オリ', 4),
 ('立憲、国民、共産、維新、社民、オリ、労働', 3),
 ('立憲、国民、共産、社民', 3),
 ('国民、社民、オリ', 2),
 ('国民、共産、社民、オリ', 2),
 ('立憲、共産、社民、オリ、労働', 2),
 ('立憲、オリ', 2),
 ('立憲、国民、社民、オリ', 2),
 ('公明、国民、維新、オリ', 2),
 ('立憲、国民、共産、社民、オリ、労働', 1),
 ('国民、維新、労働', 1),
 ('自民、公明、維新', 1),
 ('◯◯、❌❌', 1),
 ('国民、労働', 1),
 ('自民、維新、幸福', 1),
 ('幸福実現党', 1),
 ('公明、立憲、幸福', 1),
 ('立憲、国民、幸福', 1),
 ('維新、社民、オリ', 1),
 ('共産、社民、オリ、労働', 1),
 ('公明、共産、社民、オリ', 1),
 ('立憲、国民、社民', 1),
 ('立憲、国民、共産、社民、オリ', 1),
 ('自民、公明、立憲、国民、共産、維新、社民、れ新、幸福、安楽、N国、オリ、労働', 1),
 ('立憲、共産、社民、幸福', 1),
 ('○○', 1),
 ('国民、幸福', 1),
 ('公明、国民、社民、オリ', 1),
 ('公明、幸福', 1),
 ('自民、公明、幸福', 1),
 ('維新、労働', 1),
 ('幸福、オリ、労働', 1),
 ('維新、幸福、労働', 1),
 ('立憲、国民、オリ', 1),
 ('自民、公明、国民、維新、社民、幸福、オリ', 1),
 ('自民、幸福', 1),
 ('維新、オリ', 1),
 ('国民、オリ、労働', 1),
 ('立憲民主党', 1),
 ('維新、幸福、オリ', 1),
 ('オリ、労働', 1)]

となっていて、幸福、維新、国民、は単独で政策一致率が高いのかもしれません。 次にこれを、政策一致率の平均で見ていくと、

('国民', 213) 67
('社民', 201) 73.23880597014926
('維新', 200) 59.35
('幸福', 179) 60.66480446927374
('立憲', 97) 68.94845360824742
('共産', 92) 69.59782608695652
('公明', 88) 57.07954545454545
('オリ', 87) 68.95402298850574
('自民', 26) 47.07692307692308
('労働', 19) 67.42105263157895
('◯◯', 1) 65
('❌❌', 1) 65
('幸福実現党', 1) 48
('れ新', 1) 0
('安楽', 1) 0
('N国', 1) 0
('○○', 1) 52
('立憲民主党', 1) 74

となります。比較的どの政党も積極的に支持されている可能性が高いのではないかと思いました。

 特に社民党は政策一致率と一致した人の人数が共に高く、これは実際の投票結果とは正反対なので面白いと思いました。一方で自民党の政策はあまり支持されていないのではないでしょうか…?また、幸福実現党は意外とネットユーザーとの親和性が高いのかもしれません。あくまで政策だけ見れば…

 もちろんこの質問の結果が支持に絶対つながるとは限りませんので、何の役にも立たないかもしれませんが、こういう実験を色んなところでしていくのは面白いかなあと思いました。そもそも、あくまでマニフェスト?との一致なので、政党の実行力なども考慮していけば、いくら一致しているからと言って支持につながらないと思います。

最終的に分析に使ったコードは以下になりました。

import os, sys, json, re, time
from collections import Counter
from pprint import pprint
from statistics import mean

def main():
    ans = []
    seito2 = []
    seito = []
    t, _ = auth()
    with open('result.json', 'r') as f:
        js = json.load(f)
    for x in js:
        if not "retweeted_status" in x.keys():
            xx = re.findall(
                r'考えが近い政党は(.*)でした。えらぼーと2019参院選を試してみよう! #えらぼーと #ボートマッチ #選挙 #参院選',
                x['text']
            )
            if xx != []:
                if xx[0] != 'ありません':
                    xxx = list(re.findall(r'(.*)((.*)%)', xx[0])[0])
                    seito2.append(xxx[0])
                    xxx[0] = xxx[0].split('、')
                    xxx[1] = int(xxx[1])
                else:
                    xxx = [['ありません'], None]
                ans.append(xxx)
                seito += xxx[0]
    pprint(sorted(dict(Counter(seito)).items(), key=lambda x:x[1], reverse=True))
    pprint(sorted(dict(Counter(seito2)).items(), key=lambda x:x[1], reverse=True))
    for item in sorted(dict(Counter(seito)).items(), key=lambda x:x[1], reverse=True):
        l = [x[1] for x in ans if item[0] in x[0]]
        if None not in l:
            print(item, mean(l))


if __name__ == '__main__':
    main()

おわり。

追記:集計に使ったツイートは、Mon Jul 08 16:00:10 +0000 2019 から Thu Jul 04 04:08:33 +0000 2019 の間に投稿されたものです。これはUTCですので日本では7月4日の13時ころから、7月9日の1時ころです。