論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
ソーシャルメディアデータ
Social Media Data
データエンジニアリング

🔖 キーワード索引

SNSTwitter/X非構造化テキスト感情分析API

💡 30秒で分かる結論

ソーシャルメディアデータ ── SNSから得られる非構造化データ

📍 文脈 ── どこで出会うか

近年の社会科学・マーケティング論文で頻出。 「リアルタイムの世論」「災害時の情報拡散」など、 公式統計では捉えられない動きを観測できます。

🎨 直感で掴む

SNSデータの3つの層

  1. コンテンツ層:本文、 画像、 動画
  2. 関係層:フォロー、 リプライ、 リツイート、 メンション → ネットワーク構造
  3. 反応層:いいね、 シェア、 ブックマーク → 反応強度

これらを組み合わせて、 「誰が、 何を、 どう広めたか」を分析できます。

📐 定義/数式

【感情分析の枠組み】
tweet → 前処理 → 埋め込み or 辞書照合 → ポジティブ/ネガティブ/中立
【拡散の指標】
エンゲージメント率 = (Like + Retweet + Reply) / Followers
R0(再生産数)= 1ツイートあたりの平均拡散人数

🔬 記号を読み解く

テキスト
本文。 絵文字/URL/メンションを含む
メタデータ
投稿時刻、 位置情報(あれば)、 端末、 言語
グラフ構造
ユーザー間のフォロー/RT関係
時系列
イベント前後でハッシュタグ頻度の変化など

🧮 実値で計算してみる

架空シナリオ:「災害時のSNS反応」

🐍 Python 実装

最小限のスニペットで動作確認できる例。 公的データ(SSDSE 等)を想定しています。

🎯 目的:X (Twitter) API v2 を tweepy で叩き、 「高齢化」を含む日本語ツイート 100 件を取得し、 投稿時刻と「いいね数」を含む DataFrame に整形する。 SSDSE-B-2026 の高齢化率と紐付ける前段階。
📥 入力:Bearer Token(X Developer Portal で取得)、 検索クエリ '高齢化 lang:ja'、 上限 100 件。 tweet_fields=['created_at','public_metrics'] でメタ情報を付与。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# X (Twitter) API v2 の例(tweepyライブラリ)
import tweepy
import pandas as pd

client = tweepy.Client(bearer_token='YOUR_BEARER_TOKEN')
res = client.search_recent_tweets(query='高齢化 lang:ja',
                                  max_results=100,
                                  tweet_fields=['created_at','public_metrics'])
df = pd.DataFrame([{
    'text': t.text,
    'created_at': t.created_at,
    'likes': t.public_metrics['like_count']
} for t in res.data])
print(df.head())
📤 出力 text created_at likes 0 日本の高齢化はもはや先進国共通の課題に… 2026-05-19 12:34:00+00:00 42 1 地方の高齢化と人口減少、 SSDSE で見ると… 2026-05-19 11:50:00+00:00 18 2 高齢化率 30% 超えの県では介護人材不足が… 2026-05-19 11:25:00+00:00 7 (API 課金プランにより取得上限は変動)
💬 解釈:tweepy.Client は API v2 を簡潔に叩ける薄ラッパ。 ただし「Recent Search」は直近 7 日のツイートのみで、 歴史的な傾向追跡には Academic Research API か別途データセットが必要。 「いいね数」は時間と共に増えるため、 取得タイミングで値が変わることに注意。

⚠️ よくある落とし穴

❌ 1. 規約違反スクレイピング
各SNSの利用規約とAPI制限を遵守。 訴訟例多数
❌ 2. 代表性バイアス
SNSユーザーは人口の一部、 さらに発言層は偏る。 「世論」と直結させない
❌ 3. ボット/自動投稿の混入
人間の意見と区別する必要。 ボット検出が前処理必須
❌ 4. 時系列の歪み
プラットフォームの仕様変更や検閲で過去比較が困難
❌ 5. プライバシー無配慮
個人特定可能な内容の公開研究はIRB審査・倫理委員会承認が必要

🐍 Python 実装(パイプライン全体)

テキストデータの基本処理を、 SSDSE のような数値データと組み合わせる典型例を示します。 仮想的に「都道府県名を含むツイートの感情極性」を集計するシナリオです。

🎯 目的:ツイート風 CSV(text, created_at, prefecture)を読み込み、 URL・@メンション・#ハッシュタグ記号を除去して clean 列を作る。 「日本語ツイートの前処理」の最初のステップ。
📥 入力data/raw/tweets_sample.csv (想定列:text, created_at, prefecture)。 parse_dates で datetime 化。 SSDSE と結合するキーは「prefecture」(都道府県名)。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import pandas as pd
import re

# (A) ツイート風のテキストを読み込み(CSV列: text, created_at, prefecture)
tweets = pd.read_csv('data/raw/tweets_sample.csv', encoding='utf-8',
                     parse_dates=['created_at'])
print(tweets.shape, tweets.dtypes)

# (B) 前処理:URL/メンション/ハッシュタグの除去
def clean_text(s: str) -> str:
    s = re.sub(r'https?://\S+', '', s)   # URL
    s = re.sub(r'@\w+', '', s)            # メンション
    s = re.sub(r'#(\w+)', r'\1', s)       # ハッシュタグの#を除く
    return s.strip()

tweets['clean'] = tweets['text'].astype(str).apply(clean_text)
print(tweets[['text','clean']].head(3))
📤 出力 (120, 3) ── text:object, created_at:datetime64[ns], prefecture:object text clean 0 https://t.co/abc 高齢化が… @user1 #社会 高齢化が… 社会 1 @news_bot 介護人材不足です #高齢化 介護人材不足です 高齢化 2 良いニュース! https://… #日本 良いニュース! 日本
💬 解釈:URL とメンションを除き、 ハッシュタグの「#」だけ取り除いて単語自体は残すのが SNS テキスト前処理の定石。 これだけで「TF-IDF や感情辞書ベース」の精度が大きく上がる。 ただし、 絵文字・顔文字・スラングは別途処理ロジックが必要。

感情極性は辞書ベースが導入として手軽:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
POS = {'良い','嬉しい','最高','素晴らしい','楽しい'}
NEG = {'悪い','悲しい','最悪','酷い','嫌い'}

def polarity(s: str) -> int:
    pos = sum(w in s for w in POS)
    neg = sum(w in s for w in NEG)
    return pos - neg  # 正:ポジ / 負:ネガ / 0:中立

tweets['polarity'] = tweets['clean'].apply(polarity)

# (C) 都道府県 × 日次で集計
daily = (tweets
   .groupby([tweets['created_at'].dt.date, 'prefecture'])
   ['polarity']
   .agg(['mean','count'])
   .reset_index())
print(daily.head())

SSDSE と結合すれば「人口規模 vs ツイート量・感情」の関係も検証可能:

1
2
3
4
5
6
7
ssdse = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
ssdse = ssdse[['都道府県','人口総数']].rename(columns={'都道府県':'prefecture'})

agg = (tweets.groupby('prefecture')['polarity'].mean()
       .reset_index(name='avg_polarity'))
merged = agg.merge(ssdse, on='prefecture', how='inner')
print(merged.corr(numeric_only=True))

📊 主要プラットフォームの特性比較

プラットフォーム 主な投稿形式 ユーザー層 分析適性 取得難度
X (Twitter)短文+画像幅広いが社会的関心が高い層時事・速報高(API 有料化)
YouTube動画+コメント10–50代中心コンテンツ評価
Reddit長文+投票欧米中心、専門コミュニティ深掘り議論分析
Instagram画像・短編動画10–30代ブランド・マーケ
TikTok短編動画Z世代中心トレンド検知
Mastodon短文+画像技術寄りニッチ研究用途
Bluesky短文+画像早期採用者新興分析中(成長中)

⚖️ 代表性バイアスとその対策

「SNS で多い意見=世論」ではありません。 次のバイアスを必ず文書化:

対策としては、 ① 公的統計や調査データと併用、 ② プラットフォーム別の比較、 ③ ユーザー特性で層別化、 ④ ボット検出フィルタ、 などが有効です。

❓ よくある質問

Q1. 学術利用なら API 無料枠で十分?

X はかつて Academic Research Track があったが現状大きく制限。 Reddit / Mastodon / Bluesky は緩やかで、 大学研究には現実的。 古いデータが必要なら学術データセット(GDELT 等)を検討。

Q2. 感情分析は辞書 vs 機械学習、どちらを使う?

初手は辞書(実装が単純)。 ニュアンスや皮肉が問題になるなら、 既訓練の BERT 系(日本語なら東北大ベース、 cl-tohoku/bert-base-japanese)か LLM API。 ただし計算コストとの兼ね合い。

Q3. 個人を特定できる投稿は引用してよい?

原則 No。 ID をハッシュ化または完全匿名化し、 引用が必要な場合は IRB 審査と本人同意が望ましい。 公人の公的発言は別ですが慎重に。

Q4. ハッシュタグ分析だけで十分か?

代表性が悪いことが多い。 ハッシュタグ非使用の投稿が大多数で、 ハッシュタグ付き投稿はキャンペーン参加者など特殊層に偏る。 補助的指標として使う。

Q5. 位置情報付き投稿の割合は?

プラットフォーム・年代により 1〜5% 程度。 災害分析等で重要だが、 自己選択バイアスが強いため数値的代表性は乏しい。 補完にプロフィール記載地域などを使う。

📚 関連グループ教材

この用語の全体像を学ぶには、 横断的な教材で文脈を掴むのが効率的です。

📊 公的統計データ(SSDSE)との比較

観点 SNS データ SSDSE / e-Stat
取得方法API・スクレイピングCSV ダウンロード
時間粒度秒オーダーまで可年次・月次中心
空間粒度位置情報があれば点単位都道府県・市区町村
代表性低(自己選択)高(悉皆/確率標本)
変数テキスト・画像中心数値中心
分析適性感情・トレンド・拡散構造・規模・推移
補完関係「いま起きていること」「全体像」

両者を組合せた研究が増えています。 例:SNS の感情指標 × 県別失業率(SSDSE)の相関、 災害発生時の SNS 言及量 × 人的被害(消防庁統計)の関係など。

💾 大量 SNS データの保存設計

SNS データは「テキスト+メタ+画像/動画リンク」と階層化されており、 単一の表に押し込めると非効率です。 典型的な3層設計:

投稿 ID(UNIQUE)と取得時刻(パーティション)が中核キー。 ハッシュタグやメンションは JSON 配列 → 配列展開ビューで結合。 グラフ部分(フォロー / RT)は Neo4j などのグラフ DB が向きます。

🎯 主要な応用領域

領域 代表タスク 活用される指標・手法
マーケティングブランド評判・キャンペーン効果SOV、 NSS、 ハッシュタグ参加数
公共政策政策に対する反応・分極化分析ネットワーククラスタリング、 感情分析
災害対応避難情報拡散、 被災状況把握位置情報集約、 緊急ハッシュタグ追跡
金融市場感情と株価の関係VADER、 ニュース感情指標
公衆衛生疾病流行の早期検知症状ハッシュタグの時空間集約
社会科学世論形成・抗議運動・分極化トピックモデル、 グラフ分析
教育学習者コミュニティの態度分析コメント分類、 感情分析

🔌 API 取得の詳細コード

Reddit (PRAW):研究用途で最も親切な API。 OAuth でアプリ登録するだけ。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import praw, pandas as pd

reddit = praw.Reddit(client_id='YOUR_ID',
                     client_secret='YOUR_SECRET',
                     user_agent='research-bot v0.1')

posts = []
for s in reddit.subreddit('japan').hot(limit=200):
    posts.append({'id': s.id, 'title': s.title,
                  'score': s.score, 'created_utc': s.created_utc,
                  'num_comments': s.num_comments,
                  'flair': s.link_flair_text})

df = pd.DataFrame(posts)
df['created_at'] = pd.to_datetime(df['created_utc'], unit='s', utc=True)
print(df.head())

YouTube Data API v3:動画コメントを取得。 クォータ単位で課金。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
from googleapiclient.discovery import build
import pandas as pd

yt = build('youtube', 'v3', developerKey='YOUR_KEY')

req = yt.commentThreads().list(part='snippet', videoId='VIDEO_ID',
                               maxResults=100, textFormat='plainText')
res = req.execute()

comments = [{
  'author': it['snippet']['topLevelComment']['snippet']['authorDisplayName'],
  'text':   it['snippet']['topLevelComment']['snippet']['textDisplay'],
  'likes':  it['snippet']['topLevelComment']['snippet']['likeCount'],
  'published': it['snippet']['topLevelComment']['snippet']['publishedAt'],
} for it in res['items']]

print(pd.DataFrame(comments).head())

Mastodon:分散インスタンスごとに API があり、 認証不要の public ストリームも利用可。

1
2
3
4
5
6
7
8
from mastodon import Mastodon

m = Mastodon(api_base_url='https://mastodon.social')

# パブリックタイムライン
toots = m.timeline_public(limit=40)
for t in toots[:5]:
    print(t['content'][:80].replace('<','<'))

🛠 NLP 技術スタック

SNS テキストの分析に頻出する技術と日本語用のおすすめライブラリ:

タスク 手法 日本語向け実装
形態素解析単語分割・品詞推定MeCab, Janome, fugashi+UniDic, SudachiPy
基本ベクトル化TF-IDF, Bag-of-Wordsscikit-learn TfidfVectorizer
単語埋め込みWord2Vec, fastTextgensim, Wikipedia 学習済モデル
文埋め込みBERT, Sentence-BERTcl-tohoku/bert-base-japanese (HF)
感情分析辞書 / 機械学習 / LLM日本語評価極性辞書, asari, BERT
トピック抽出LDA, BERTopic, NMFgensim LdaModel, bertopic
固有表現抽出NER(人名/組織/地名)GiNZA, spaCy 日本語モデル
対話/要約GPT, T5OpenAI / Claude API, Llama日本語版

📐 主要指標と計算式

指標 計算式 意味
エンゲージメント率(Like+RT+Reply) / Followersフォロワー比の反応強度
バイラル係数$R_0 = \beta/\gamma$1超で拡大、1未満で収束
SOV (Share of Voice)対象ブランド言及数 / 全言及数市場の声占有率
NSS(ポジ件数 − ネガ件数) / 全件純感情スコア
影響度$\log$(Followers) × Engagement単発リーチの規模
バースト度$|\Delta f|$ / 過去窓の平均話題の急上昇度

📖 ケーススタディ:選挙予測の試みと失敗

2010 年代前半、 Twitter の言及量から選挙結果を予測する論文が多数発表されました。 しかし 2016 年米大統領選では、 SNS 上では Clinton 支持の言及がトランプを大きく上回ったにもかかわらず、 トランプが勝利。 原因は 選択バイアス(Twitter ユーザーは民主党支持に偏在)と、 「沈黙の螺旋」(少数派は発言を控える)でした。

教訓:① SNS データ単独で集団全体を推定しない、 ② 公的調査と必ず突き合わせる、 ③ 「ない人」の声を補完する設計(重み付け、補完サンプリング)が必要。

🔬 情報拡散モデル(数式)

SNS 上の情報拡散は、 感染症の SIR モデルと近い構造を持ちます:

$$ \frac{dI}{dt} = \beta S I - \gamma I $$

$S$=未拡散ユーザー、 $I$=拡散済み、 $\beta$=拡散率、 $\gamma$=飽和率。 基本再生産数 $R_0 = \beta / \gamma$ が 1 を超えれば バイラル化。 ハッシュタグの時系列を当てはめると流行の最大規模を予測できます。

独立カスケード(IC)モデル、 線形閾値モデルなど、 ネットワーク上の拡散モデルが多数提案されています。 ネットワーク中心性(degree, betweenness, PageRank)が高いノードを特定すると、 効率的な情報伝搬経路や、 偽情報の発信源候補を見つけられます。

⚖️ 倫理・法規制チェックリスト

📜 歴史と発展

🔎 深掘り解説

主要データソースとアクセス手段

プラットフォーム取得方法制限
X (Twitter)API v2(有料化)、 Academic Track厳しいレート制限
YouTubeData API v3クォータあり
RedditPRAW(Python)比較的緩い
Mastodon公開API各インスタンスのポリシー
BlueskyATP / AT Protocol新興、 制限緩め

分析パイプライン

  1. 収集:API、 ストリーミング、 アーカイブ
  2. クレンジング:絵文字、 URL、 メンション処理
  3. 言語処理:トークン化、 形態素解析、 埋め込み
  4. 分析:感情、 トピック、 ネットワーク
  5. 可視化:時系列、 ワードクラウド、 ネットワーク図
  6. 解釈:代表性/バイアスを必ず議論

✅ 使う前のチェックリスト

📖 さらに学ぶには

本サイト内

外部リソース

困ったときは

  1. データの可視化(散布図、 ヒストグラム、 箱ひげ図)で異常を確認
  2. サンプルサイズ・欠損・外れ値を確認
  3. 仮定が満たされているか診断(正規性検定、 等分散性検定など)
  4. 類似研究での標準的な手法を確認
  5. 結果を複数手法でクロスチェック(頑健性確認)

🔎 深掘り解説

主要データソースとアクセス手段

プラットフォーム取得方法制限
X (Twitter)API v2(有料化)、 Academic Track厳しいレート制限
YouTubeData API v3クォータあり
RedditPRAW(Python)比較的緩い
Mastodon公開API各インスタンスのポリシー
BlueskyATP / AT Protocol新興、 制限緩め

分析パイプライン

  1. 収集:API、 ストリーミング、 アーカイブ
  2. クレンジング:絵文字、 URL、 メンション処理
  3. 言語処理:トークン化、 形態素解析、 埋め込み
  4. 分析:感情、 トピック、 ネットワーク
  5. 可視化:時系列、 ワードクラウド、 ネットワーク図
  6. 解釈:代表性/バイアスを必ず議論

✅ 使う前のチェックリスト

📖 さらに学ぶには

本サイト内

外部リソース

困ったときは

  1. データの可視化(散布図、 ヒストグラム、 箱ひげ図)で異常を確認
  2. サンプルサイズ・欠損・外れ値を確認
  3. 仮定が満たされているか診断(正規性検定、 等分散性検定など)
  4. 類似研究での標準的な手法を確認
  5. 結果を複数手法でクロスチェック(頑健性確認)