博士課程の研究者であればXのtweet取得が無料でできる(要申請)と公式サイトにあるのですが、まだ大学のメアドを付与されていないので、代わりにMESHSTATSでTweetを取得してトピックモデル分析をやってみようと思います。今回は前処理編です。
※Xの日本語公式にその旨残っていたのに、英語で検索したらNo moreでした。API変わって有料になったのわかってたのですが、まさかAcademicもなくなっていたとは。研究計画白紙からやり直しです。。。SNSのテキストマイニングはもはやほとんどの研究者にとって研究対象にならないのでは、と思います。データが馬鹿高い金を払わなければ入手できない。
MESHSTA(メッシュスタッツとは)
MESHSTATS(メッシュスタッツ)は、世界規模のメッシュ統計を可視化・分析・再集計できるシステムで、インターネット上から収集されるデータや政府統計などをデータソースとしているます。様々なアプリが公開されていて、APIを通じてさまざまな分析が可能となるデータを提供しています。
運営は(一社)世界メッシュ研究所で、代表理事は横浜市立大データサイエンス研究科の佐藤教授です。
【活用例】←ブラウザAIのサジェッション
地域的な災害の社会経済的リスク予測
小売業の市場規模予測
世界規模の問題をデータ駆動的に解決する基盤データの提供
ステークホルダーとの連携の構築
*利用にはユーザー登録が必要です
今回やりたいこと
MESHSTATSのアプリの中で、Twitterのツイート(2020年末から約3年間、ジオタグ付きで東京エリア限定)をAPIを通じて取得することができます。形態素解析済みのテキストデータで取得できますが、アプリの動作が結構独特で、30日分を取得するのにtimedeltaなどを使いました。
今回は「コロナ」を含むツイートを取得してトピックモデル分析を行うLDAにデータを流すために二重リスト形式に整形するまで行いました。
結構データにクセ(jsonではなくてテキスト) があって、Chat-GPTと協力しながらなんとか整形しましたが、前処理の重要性というかめんどくささを思い知らされました。
とても読みにくいコードですが備忘録としてアップします。
from datetime import datetime, timedelta
import requests
import re
import pandas as pd
# signifty the date
start_date = datetime(2020, 12, 17)
# get 30 days as a list
dates = [
(start_date + timedelta(days=i)).strftime('%Y%m%d')
for i in range(30)
]
# get tweete for 30 days
data = []
for i in dates:
#get tweete from meshstats for one day
url = 'https://www.meshstats.net/meshstats/twitterapi.php'
params = {
"func": "word",
"word": "コロナ",
"sampledate": i,
"apikey": "*****************"
}
response = requests.get(url, params)
# shape the text
records = [rec.strip() for rec in response.text.splitlines() if rec.strip()]
rows = [str(rec).split(',') for rec in records]
split_rows = [re.split(r'\t', row) if isinstance(row, str) else row for sublist in rows for row in sublist]
data.append(split_rows)
# flatten to 2d
flattened_data = [inner for outer in data for inner in outer]
# delete specific list_1
def remove_unwanted_lists(nested_list, unwanted_lists):
result = []
for item in nested_list:
if isinstance(item, list):
# 再帰的にリストを処理
if item not in unwanted_lists: # unwanted_list から外れる場合のみ
result.append(remove_unwanted_lists(item, unwanted_lists))
else:
result.append(item)
return result
unwanted_lists = [['yyyymmdd'], ['lat'], ['long'], ['worldmesh3'], ['worldmesh4'], ['worldmesh5'], ['noun'], ['verbs']]
filtered_data = remove_unwanted_lists(flattened_data, unwanted_lists)
# delte specific list_2
def remove_specific_prefixes(nested_list):
prefixes = ("20", "35", "139", "14")
return [
item for item in nested_list
if not (isinstance(item, list) and item and str(item[0]).startswith(prefixes))
]
cleaned_data = remove_specific_prefixes(filtered_data)
# delete none
cleaned_data = [item for item in cleaned_data if item != ['']]
# export to xlsx
df = pd.DataFrame(cleaned_data)
df.to_excel("コロナ.xlsx", index=False)