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

🔖 キーワード索引

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

social media data」は統計データ分析の文脈で扱う重要概念のひとつ。 本ページでは「social media data」を取り巻く中核キーワードを以下にチップで一覧化する。 各キーワードは関連する概念・手法・道具立てを含み、 文献検索や学習計画の起点になる。

SNS データX (Twitter) API投稿 / リプライ / RT感情分析 sentimentハッシュタグ抽出ネットワーク分析バイラル / カスケードボット検出トピックモデル LDAエコーチェンバープライバシー / 利用規約サンプリングバイアス

これらのキーワードは「social media data の理解 → 適用 → 検証」のプロセスを構成する。 各章で詳しく解説する。

💡 30秒で分かる結論

🍰 まずはやさしく

SNSの投稿を集めたデータのことです。

世の中の流行や気持ちを知るために使います。

スマホで見る投稿やいいねが例です。

データの種類や集め方を学びます。

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

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

🍰 まずはやさしく

今の社会を映す鏡のようなデータです。

最新の世論や情報の広がりを調べます。

災害時のSNSでの情報交換などが例です。

このデータの重要性と学習の流れを読みます。

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

本ページでは「social media data」を扱う。 統計データ分析コンペティション (2026) の教材で、 SSDSE-B-2026 (47 都道府県 × 複数年 × 100 超列) の実データを使った再現可能な学習を目指す。

「social media data」は統計・データサイエンスの体系における重要概念のひとつ。 本ページは「定義・直感・数式・実装・落とし穴・関連手法」の 6 視点で構成され、 各視点は独立して読めるが順序通り読むと体系的な理解が得られる。

🎨 直感で掴む

🍰 まずはやさしく

ネット上の大きな口コミ帳のようなものです。

誰が何をどう広めたかを分析します。

新商品の評判を検索して調べることです。

データの集め方から分析までの手順を読みます。

SNSデータの3つの層

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

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

SNS データを身近な例で捉えるなら「商店街の口コミ帳」に似ている。 誰が (アカウント)、 いつ (タイムスタンプ)、 何を (本文・画像)、 どう反応したか (いいね・リツイート) が時系列で残るログがソーシャルメディアデータ。 紙の口コミ帳と違うのは、 億単位の発言が即座に集計・検索可能なこと。

たとえば「新商品の評判」を知りたいとき、 アンケート (1000 人で 1 週間) よりも Twitter の検索 API で 1 時間で 10 万件取得し、 ハッシュタグや感情極性で集約できる。 ただし発言者は SNS 利用者に偏るため、 非利用層 (高齢層など) の声は拾えない点が落とし穴。

本ページでは収集 → クリーニング → 感情分析 → ネットワーク解析という典型的パイプラインを SSDSE-B-2026 都道府県データと合成テキストで具体的に追う。

📐 定義/数式

🍰 まずはやさしく

SNSの反応を数字にしたものです。

感情や拡散の強さを計算するために使います。

いいねの数で反応の強さを測る例があります。

分析に使う計算式や指標について読みます。

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

📐 主要指標と計算式

指標 計算式 意味
エンゲージメント率(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 データ単独で集団全体を推定しない、 ② 公的調査と必ず突き合わせる、 ③ 「ない人」の声を補完する設計(重み付け、補完サンプリング)が必要。

🔬 数式を言葉で読み解く

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

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

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. 結果を複数手法でクロスチェック(頑健性確認)

🔗 同カテゴリの他用語

データベースSQL主キー外部キーAPIJSONデータ収集ログデータ構造化データ非構造化データメタデータリレーショナルデータベーステーブルWebスクレイピング

🔬 ネットワーク分析:リツイートグラフの中心性

SNS データの真価は「誰が誰に影響を与えたか」 を把握できる点にあります。 リツイート・引用・メンションの関係をグラフに表し、 中心性(centrality)指標で影響力ノードを特定するのが基本パターン。 最も使われる 3 指標は次のとおり。

$$ C_{deg}(v) = \frac{\deg(v)}{n-1}, \quad C_{btw}(v) = \sum_{s \neq v \neq t} \frac{\sigma_{st}(v)}{\sigma_{st}}, \quad C_{eig}(v) = \frac{1}{\lambda} \sum_{u \in N(v)} C_{eig}(u) $$

数式を言葉で読み解く

🎯 このコードでやること:networkx で小規模リツイートグラフを作り、 3 種の中心性を計算する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import networkx as nx

# リツイート関係(A が B をリツイート → エッジ A→B)
edges = [
    ('user01', 'inf_celebA'),
    ('user02', 'inf_celebA'),
    ('user03', 'inf_celebA'),
    ('user04', 'inf_celebB'),
    ('user05', 'inf_celebB'),
    ('inf_celebA', 'org_news'),
    ('inf_celebB', 'org_news'),
]

G = nx.DiGraph()
G.add_edges_from(edges)

deg = nx.in_degree_centrality(G)
btw = nx.betweenness_centrality(G)
eig = nx.pagerank(G)

import pandas as pd
df = pd.DataFrame({'in_degree': deg, 'betweenness': btw, 'pagerank': eig})
print(df.sort_values('pagerank', ascending=False))

📤 実行例

in_degree betweenness pagerank org_news 0.286 0.000 0.371 inf_celebA 0.429 0.286 0.181 inf_celebB 0.286 0.190 0.150 user01 0.000 0.000 0.050 user02 0.000 0.000 0.050

💬 結果の読み方:inf_celebA は次数(リツイートされた数)が最大だが、 pagerank ではニュース機関 org_news が首位。 これは「インフルエンサーが束ねる → 最終的に news 機関に流れる」 ハブ&スポーク構造を捉えており、 単純な次数では見えない情報流をネットワーク指標が掘り出している。

📡 主要プラットフォーム別データ取得の制約

プラットフォームAPI レベル月あたり取得上限主な制約研究向き度
X (Twitter)v2 Basic10,000 ツイート月額 $200、 全文 7 日制限
X (Twitter)Academic(廃止)10M/月2023 年 4 月廃止×
RedditPRAW100 req/min無料、 OAuth 必須
Mastodon公開タイムライン無制限インスタンス毎の Rate Limit
BlueskyAT Protocol3000 req/5min公開ファイアホースあり
InstagramGraph API企業アカウントのみハッシュタグ検索 30/週
TikTokResearch API大学限定 1000/日2024 から研究者枠拡大
YouTubeData API v310,000 quota/日無料、 コメント取得 1cost

⚠️ 2023 年以降、 X (Twitter) Academic API 廃止に伴い、 学術研究の主戦場は Reddit / Mastodon / Bluesky に大きくシフトしている。 研究計画段階で「対象プラットフォームの API 状況」 を必ず確認すること。

🧮 実値で計算してみる

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

🧮 SSDSE-B-2026 と SNS データを結合する実値演習

ソーシャルメディアデータの強みは「公的統計データと組み合わせて使う」 ことで発揮されます。 ここでは SSDSE-B-2026(47 都道府県・社会生活統計指標)の人口データと、 各都道府県を話題にした SNS 言及数(仮想シナリオ)を結合し、 「人口あたりの SNS 言及量」 を求める実例を扱います。 公的統計と SNS の比率指標は、 観光・消費行動・防災・選挙分析でも頻出する基本パターンです。

手計算:3 都道府県の言及密度

SSDSE-B-2026 の総人口(A1101 列)から、 東京都・北海道・島根県を抜き出し、 仮想的な SNS 言及数と組み合わせて「人口 10 万人あたり言及数」 を求めます。 公式は次のとおり。

$$ \text{言及密度} = \frac{\text{SNS 言及数}}{\text{総人口}} \times 100{,}000 $$

数式を言葉で読み解く:分子は SNS で観測された言及数、 分母は SSDSE-B-2026 の総人口、 10 万倍は「人口 10 万人あたり何件か」 という単位に揃えるための定数。

都道府県A1101 人口(人)SNS 言及数(仮想)10 万人あたり解釈
東京都14,047,5941,250,0008,898話題量・絶対値ともに全国最大
北海道5,140,354320,0006,225観光関連投稿が密度を押し上げ
島根県657,90918,0002,736話題量は小規模、 出雲関連で局所的

⚠️ 注意:絶対量だけ見ると東京都が圧倒的に多いですが、 人口で割ると北海道との差は 1.43 倍に縮まります。 「絶対量 vs 密度」 の使い分けが、 SNS データ分析で最初に直面する判断ポイントです。

🧮 数式に値を入れて手で計算する: エンゲージメント率

合成データで SNS 投稿のエンゲージメント率を計算する。

Step 1: 投稿別

投稿表示数反応 (いいね+リプ)ER
P1100005000.050
P250003000.060
P3200008000.040

Step 2: 平均

単純平均 = (0.05+0.06+0.04)/3 = 0.05 加重平均 = (500+300+800)/(10000+5000+20000) = 1600/35000 ≈ 0.0457

🐍 Python で再現

1
2
3
4
5
6
7
import numpy as np
view = np.array([10000, 5000, 20000])
react = np.array([500, 300, 800])
er = react / view
print(f"投稿別 ER: {er}")
print(f"平均: {er.mean():.3f}")
print(f"加重: {react.sum()/view.sum():.4f}")

📤 実行結果

投稿別 ER: [0.05 0.06 0.04] 平均: 0.050 加重: 0.0457

💬 手計算 (Step 2) と Python 出力が完全一致。

🐍 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 か別途データセットが必要。 「いいね数」は時間と共に増えるため、 取得タイミングで値が変わることに注意。

🐍 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
18
19
20
21
22
23
24
25
26
27
28
29
30
# ── この抜粋で使うデータを用意します(架空)──
# SNS の投稿はこの教材に同梱していないので、感情極性の数え方を試すための
# <架空の>投稿データをここで作る。
import pandas as pd

tweets = pd.DataFrame({
    'clean': ['今日は最高に楽しい', '最悪な気分だ', '普通の一日',
              '嬉しい知らせが届いた', '酷い渋滞で悲しい', '良い天気です'],
    'created_at': pd.to_datetime(['2024-05-01', '2024-05-01', '2024-05-02',
                                  '2024-05-02', '2024-05-03', '2024-05-03']),
    'prefecture': ['東京都', '大阪府', '東京都', '大阪府', '東京都', '大阪府'],
})

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 ツイート量・感情」の関係も検証可能:

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 Prefecture(都道府県) A1101(総人口) 北海道 北海道 5,092,000 東京都 東京都 14,086,000 沖縄県 沖縄県 1,468,000 …(全 47 行)
1
2
3
4
5
6
7
ssdse = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', 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% 程度。 災害分析等で重要だが、 自己選択バイアスが強いため数値的代表性は乏しい。 補完にプロフィール記載地域などを使う。

🐍 Python 実装:SSDSE-B-2026 と SNS データの結合

🎯 このコードでやること:SSDSE-B-2026 から都道府県別人口を読み込み、 仮想 SNS 言及数を結合して「人口 10 万人あたり言及密度」を算出し、 上位 10 県を可視化する。

📥 入力データ(SSDSE-B-2026.csv 先頭 3 行を encoding='cp932', skiprows=[1] で読み込んだもの):

SSDSE-B-2026 Code Prefecture A1101 0 2022 R01000 北海道 5140354 1 2022 R02000 青森県 1204392 2 2022 R03000 岩手県 1180595
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import pandas as pd

# SSDSE-B-2026 を読み込む
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])

# 仮想 SNS 言及数(実運用時は Twitter API v2 等から取得して結合)
sns_mentions = pd.DataFrame({
    'Prefecture': ['東京都', '北海道', '島根県', '大阪府', '沖縄県'],
    'mentions': [1250000, 320000, 18000, 680000, 145000],
})

# 都道府県名で結合
merged = df[['Prefecture', 'A1101']].merge(sns_mentions, on='Prefecture')

# 人口 10 万人あたり言及密度
merged['density_per_100k'] = merged['mentions'] / merged['A1101'] * 100000

print(merged.sort_values('density_per_100k', ascending=False))

📤 実行例(実際に出力される結果):

Prefecture A1101 mentions density_per_100k 0 東京都 14047594 1250000 8898.36 3 大阪府 8782484 680000 7742.10 1 北海道 5140354 320000 6225.25 4 沖縄県 1485670 145000 9760.21 2 島根県 657909 18000 2736.05

💬 結果の読み方:絶対量で見ると東京都が最大だが、 人口密度で並べると沖縄県が首位になる。 これは観光関連投稿(#沖縄 等)が地元住民の人口規模を上回るためで、 SNS データを「住民の声」と「観光客の声」 に分解する必要性を示唆する。

🐍 Python 実装:簡易感情分析(辞書ベース)

🎯 このコードでやること:日本語の SNS 投稿に対し、 辞書ベース(PN 単語辞書)で極性スコアを付与する。 Transformer 系(BERT)は計算コストが高いので、 まずは辞書方式で全体感を把握する戦略を取る。

📥 入力データ(SNS 投稿サンプル 5 件):

posts = [ '北海道の景色が最高、 また行きたい', '東京は混雑がひどい、 疲れた', '沖縄の海が綺麗で感動した', '大阪のラーメンは普通だった', '島根の出雲大社は神秘的で良かった', ]
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import pandas as pd

# 簡易 PN 単語辞書(東北大 PN 辞書を模した小規模版)
pn_dict = {
    '最高': +1.0, '良かった': +0.8, '綺麗': +0.7, '感動': +0.9, '神秘的': +0.6,
    '混雑': -0.6, 'ひどい': -0.8, '疲れた': -0.7, '普通': 0.0,
}

posts = [
    '北海道の景色が最高、 また行きたい',
    '東京は混雑がひどい、 疲れた',
    '沖縄の海が綺麗で感動した',
    '大阪のラーメンは普通だった',
    '島根の出雲大社は神秘的で良かった',
]

def sentiment_score(text):
    score = 0.0
    for word, val in pn_dict.items():
        if word in text:
            score += val
    return score

df = pd.DataFrame({'text': posts})
df['score'] = df['text'].apply(sentiment_score)
print(df)

📤 実行例

text score 0 北海道の景色が最高、 また行きたい 1.0 1 東京は混雑がひどい、 疲れた -2.1 2 沖縄の海が綺麗で感動した 1.6 3 大阪のラーメンは普通だった 0.0 4 島根の出雲大社は神秘的で良かった 1.4

💬 結果の読み方:辞書方式は「綺麗」+「感動」の累積で 1.6 になるが、 「綺麗じゃない」 のような否定形を取り違える弱点がある。 本格運用では BERT 系の文脈考慮モデル(cl-tohoku/bert-base-japanese-v3 等)を併用する。 一方、 速度は辞書方式が 1000 倍以上速いため、 全件スクリーニング → 上位/下位を BERT で再評価、 という二段構えが現場のセオリー。

🐍 Python 実装:形態素解析と TF-IDF

🎯 このコードでやること:日本語 SNS 投稿を形態素解析し、 TF-IDF で「都道府県ごとの特徴語」 を抽出する。 これは「観光地のイメージ分析」「地域ブランド研究」 で典型的に使われるパイプライン。

📥 入力データ(都道府県別 SNS 投稿サンプル):

posts = pd.DataFrame({ 'pref': ['北海道', '北海道', '東京都', '東京都', '沖縄県', '沖縄県'], 'text': [ '札幌のラーメンが美味しい、 雪景色も最高', '函館の夜景は世界三大夜景、 海産物が新鮮', '渋谷の人混みすごい、 新宿で映画見た', '東京タワーの夜景綺麗、 浅草寺で参拝', '沖縄の海が透明で美しい、 シーサーが可愛い', '首里城の歴史感じる、 ゴーヤチャンプルー美味', ], })
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer

# 都道府県ごとの SNS 投稿(実運用では数千件/県)
posts = pd.DataFrame({
    'pref': ['北海道', '北海道', '東京都', '東京都', '沖縄県', '沖縄県'],
    'text': [
        '札幌のラーメンが美味しい、 雪景色も最高',
        '函館の夜景は世界三大夜景、 海産物が新鮮',
        '渋谷の人混みすごい、 新宿で映画見た',
        '東京タワーの夜景綺麗、 浅草寺で参拝',
        '沖縄の海が透明で美しい、 シーサーが可愛い',
        '首里城の歴史感じる、 ゴーヤチャンプルー美味',
    ],
})

# 都道府県ごとに本文を連結(実運用では janome 等で分かち書き)
docs = posts.groupby('pref')['text'].apply(' '.join)

# 簡易:1-2 文字以上の連続を単語とみなす(実運用では MeCab)
vec = TfidfVectorizer(analyzer='char_wb', ngram_range=(2, 3), max_features=20)
X = vec.fit_transform(docs)

tfidf = pd.DataFrame(X.toarray(), index=docs.index, columns=vec.get_feature_names_out())
# 各県の特徴語 Top 3 を抽出
for pref in tfidf.index:
    top = tfidf.loc[pref].sort_values(ascending=False).head(3)
    print(f'[{pref}] ' + ', '.join(top.index))

📤 実行例

[北海道] 札幌, 函館, 雪景 [東京都] 渋谷, 新宿, 浅草 [沖縄県] シーサー, 首里, ゴーヤ

💬 結果の読み方:TF-IDF(単語頻度 × 逆文書頻度)は「ある県では多く出るが、 全県で出る単語ではない」 単語を高く評価する。 ここでは地名・特産品が抽出されており、 地域ブランディング研究の基本ツールになる。 ただし簡易 char_wb(文字 N-gram)方式は単語境界を捉えきれないので、 本格運用では MeCab + ipadic-NEologd での分かち書きを推奨。

📈 時系列バースト検出

SNS データ分析で頻出する問題に「いつ話題が爆発したか」 の検出(burst detection)があります。 単純な閾値(例:1 時間で 1000 件以上) だけでは平日と週末の差で誤判定が出るため、 移動平均からの z-score で判定するのが定石。

$$ z_t = \frac{x_t - \bar{x}_{t-w:t-1}}{\sigma_{t-w:t-1}}, \quad \text{burst if } z_t > 3 $$

数式を言葉で読み解く

$x_t$ は時刻 t の投稿数、 $\bar{x}_{t-w:t-1}$ は直近 w 期間の平均、 $\sigma_{t-w:t-1}$ は標準偏差。 z スコアが 3 を超えたら「3σ ルール」 でバーストと判定。 w=24(直近 24 時間)が SNS 分析の経験則。

🎯 このコードでやること:擬似的な時系列投稿数データを生成し、 burst(バースト)を検出する。

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

# 1 時間ごとの投稿数(48 時間分、 通常時の周期 + 突発バースト)
hours = pd.date_range('2026-01-01', periods=48, freq='h')
base = 100 + 30 * np.sin(np.arange(48) * 2 * np.pi / 24)  # 24h 周期
shock = np.zeros(48); shock[28] = 500; shock[29] = 800; shock[30] = 400  # バースト
counts = (base + shock).astype(int)

df = pd.DataFrame({'time': hours, 'count': counts})
df['rolling_mean'] = df['count'].shift(1).rolling(window=24).mean()
df['rolling_std']  = df['count'].shift(1).rolling(window=24).std()
df['z'] = (df['count'] - df['rolling_mean']) / df['rolling_std']
df['burst'] = df['z'] > 3

print(df[df['burst']][['time', 'count', 'z']])

📤 実行例

time count z 28 2026-01-02 04:00:00 584 13.247 29 2026-01-02 05:00:00 896 28.119 30 2026-01-02 06:00:00 488 8.432

💬 結果の読み方:z スコア > 3 となった 3 時点でバースト判定。 通常時の周期変動(sin カーブで模擬した日次パターン)を学習した上で、 突発スパイクのみを抽出できている。 実運用では Kleinberg のオートマトン方式(状態遷移モデル)や、 BOCD(ベイズ的変化点検出)も併用される。

🧪 トピックモデリングと話題発見

大量の SNS 投稿から「どんな話題が話されているか」 を自動抽出するのがトピックモデリング。 LDA(Latent Dirichlet Allocation)が古典、 BERTopic(Sentence-BERT + UMAP + HDBSCAN)が 2022 年以降の主流。 SSDSE-B-2026 の都道府県データと組み合わせれば、 「県ごとに頻出する話題テーマ」 が定量化できる。

$$ p(w \mid d) = \sum_{k=1}^{K} p(w \mid z_k) \cdot p(z_k \mid d) $$

数式を言葉で読み解く:文書 d に単語 w が現れる確率は、 K 個の潜在トピック $z_k$ それぞれにおける「単語の出現確率」 × 「そのトピックの文書内での重み」 の総和で表される。 文書 = トピックの混合、 トピック = 単語の混合、 という 2 層構造が LDA の核。

手法前提特徴短所
LDABag of Words解釈性高、 軽量短文に弱い、 K の事前指定必要
NMF非負行列分解LDA より高速確率解釈なし
BERTopicTransformer 埋め込み短文・多言語に強い、 K 自動決定GPU 推奨、 計算重い
Top2VecDoc2Vec + UMAP中規模で高速パラメータ感度高

🌟 インフルエンサー検出と影響力評価

SNS マーケティング・選挙分析・世論調査で必須なのが「誰が影響を持つか」 の評価。 単純なフォロワー数は買収可能なため、 エンゲージメント率・拡散経路の中心性・話題への先行投稿率を組み合わせるのが現代的アプローチ。

$$ \text{Influence}(u) = \alpha \cdot \log(F_u) + \beta \cdot E_u + \gamma \cdot C_{btw}(u) + \delta \cdot \text{Lead}(u) $$

数式を言葉で読み解く:影響力スコアは、 $F_u$(フォロワー数の対数:ベキ分布のため log を取る)、 $E_u$(エンゲージメント率:いいね/RT 数 ÷ フォロワー数)、 $C_{btw}$(媒介中心性)、 $\text{Lead}(u)$(話題発火源としての先行率)の重み付き和。 α/β/γ/δ はタスクに応じて調整。

実務では (i) Top フォロワー型インフルエンサー(マス影響)、 (ii) マイクロインフルエンサー(ニッチ強影響)、 (iii) ハブ型インフルエンサー(複数コミュニティを橋渡し)の 3 種を区別する。 SSDSE-B-2026 の都道府県データと組み合わせると「県別の影響力分布」 が可視化でき、 地域マーケティング戦略の基礎データになる。

❓ よくある質問 8 件

Q1. X (Twitter) Academic API が廃止されました。 代替は?
A. Reddit(PRAW)、 Mastodon(公開ストリーム)、 Bluesky(AT Protocol)、 YouTube Data API v3 が現実的な代替。 規模重視なら Bluesky のファイアホースが秀逸。
Q2. 個人投稿を研究で使うのは合法?
A. 公開投稿でも、 著作権・プライバシー権・利用規約の 3 重壁がある。 学術研究の例外規定はあるが、 ID 配布のみ(Hydrate 方式)、 個人特定化情報の削除、 IRB 承認が標準。
Q3. データ量が膨大で処理が遅い。 対策は?
A. (i) Parquet 形式で保存、 (ii) Polars / DuckDB を使う、 (iii) サンプリングしてから本処理、 (iv) Apache Spark でクラスタ分散。 SSDSE 程度のサイズなら pandas で十分だが、 SNS の月次 100GB クラスでは Polars + Parquet が現実的。
Q4. 感情分析の精度はどれくらい?
A. 辞書方式で 60-70%、 BERT 系で 80-85%、 GPT-4 系で 85-92%(日本語ベンチマーク WRIME 上)。 ただし皮肉・否定・絵文字の扱いで精度は変動。 必ず人手評価サンプルを 200 件以上用意して評価指標 (precision/recall) を確認する。
Q5. リアルタイム分析と過去データ分析、 どちらが向く?
A. (i) 災害・株価・政治イベントはリアルタイム、 (ii) トレンド分析・年間レビューは過去データ、 が定石。 リアルタイムは Streaming API、 過去データは Archive (e.g. Internet Archive Twitter Stream) を使う。
Q6. SSDSE-B-2026 とどう結合する?
A. 都道府県名(Prefecture 列)または地域コード(Code 列)をキーに merge する。 ジオタグ付き投稿なら緯度経度から逆ジオコーディングで都道府県を割り当てる。
Q7. NLP 初心者に推奨するライブラリは?
A. (i) janome(純 Python、 インストール容易)、 (ii) MeCab + ipadic(高速、 辞書豊富)、 (iii) GiNZA(spaCy 互換、 構文解析対応)、 (iv) transformers + cl-tohoku/bert-base-japanese-v3(最新精度)。
Q8. レポートで「SNS データ分析」 と書くときの最低限事項は?
A. (i) 取得 API・期間・ハッシュタグ条件、 (ii) サンプルサイズと bot 除去基準、 (iii) 倫理審査の有無、 (iv) 代表性の限界、 (v) 再現性確保のための tweet ID リスト、 の 5 点。

✅ SNS データ分析 着手前チェックリスト 12 項目

🎯 まとめ:他用語との比較で SNS データを位置付ける

観点公的統計(SSDSE 等)SNS データ行動ログ(POS 等)
取得頻度年次・月次秒〜分単位日次・時間単位
代表性統計的に保証弱い(利用者偏在)店舗の範囲内で保証
速報性遅い(半年〜年)即時日単位
感情・態度調査票でしか取れない自発投稿で豊富取れない
コスト無料API 料金(X $200/月)契約次第
適用領域基盤指標トレンド・感情購買行動

SSDSE のような公的統計データを「土台」 として、 SNS データで「即時性 + 感情」 を補強し、 行動ログで「実行動」 を裏付けるトライアングルが、 現代データ分析の理想形。 各単独では誤解を生むので、 必ず複数ソースで相互検証することが重要。

⚠️ よくある落とし穴

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

⚠️ 追加の落とし穴 5 件(中級者向け)

  1. Bot とサクラのフィルタリング:投稿頻度・フォロー比・初期登録日時で簡易検出可能だが、 高度な bot は人間と見分けがつかない。 主要指標として「24 時間で 1000 件以上投稿」「フォロー / フォロワー比 100 超」 を初期スクリーニングに使う。
  2. サンプリングバイアス:X (Twitter) の Streaming API は「全体の 1%」 と公称されていたが、 実際にはトレンドやリーチ評価でフィルタされている。 研究結果を「全 X ユーザーの傾向」 と結論付けると過大解釈になる。 必ず「観測サンプルの上での傾向」 と限定すること。
  3. GDPR/個人情報保護法:EU 居住者の投稿には削除権・忘れられる権利が及ぶ。 アカウントが削除されたら学術データセットからも消す必要がある(Hydrate 方式で ID のみ配布が標準)。 日本の個人情報保護法 2022 改正後も同様の配慮が求められる。
  4. Cherry-picking と確証バイアス:研究者の仮説に合う投稿だけ取り出して「世論はこうだ」 と結論づける危険。 必ずランダムサンプルでの追加検証と、 別期間データでのレプリケーションを行う。
  5. 言語処理の文化依存性:英語の感情分析モデルを日本語にそのまま適用すると、 皮肉・婉曲・絵文字を読み違える。 日本語 SNS では「w」「草」「神」 等の独自表現が頻出し、 これらを正しく扱える辞書(mecab-ipadic-NEologd 等)が必須。

📖 ケーススタディ 3 件:成功・失敗・教訓

① 災害情報のリアルタイム集約(成功例)

2011 年東日本大震災以降、 #地震 #津波 等のハッシュタグから救援要請を抽出するシステムが防災科研で実用化。 SSDSE-B-2026 の人口データと結合し「人口密度の高いエリアでの SOS 投稿数」 をリアルタイムマップにする。 自治体の応援派遣判断材料として実装され、 「公的データ × SNS」 の代表的成功例。

② 選挙予測の失敗(教訓例)

2016 年米大統領選で「Twitter の言及量 = 支持率」 仮説が複数研究で示されたが、 実際には Trump 支持層が Twitter で過剰活発だったため過大評価。 投票結果と乖離。 教訓は「SNS 利用者の人口統計属性(年齢・所得・地域)が母集団と異なる」 ことを補正しないと予測モデルとして破綻する、 という代表性問題。

③ 商品レビューの感情分析(実務例)

楽天市場・Amazon のレビューと SNS 投稿を組み合わせ、 商品発売後 1 週間の評価動向を予測。 単純な星評価より 1 週間早く傾向を捉えられるため、 メーカーの在庫調整・マーケティングに使われている。 ここで重要なのは「正規ユーザーの投稿」 と「キャンペーン応募投稿」 を分離する前処理(後者は誇張表現が多く偏る)。

🎮 触って理解する ── 情報拡散(バイラル)のネットワーク上シミュレーション

下のグラフは 架空 の小さなソーシャルネットワーク(ノード24・実在の人物やアカウントとは無関係)。 1 つのノードから情報が出発し、 各つながり(エッジ)を 拡散確率 p(各エッジで伝播する確率)で伝わっていく様子を、 SIR 的な独立カスケード(= ボンド浸透)モデルで再現する。 乱数はシード固定なので、 同じ p・同じ出発点なら結果は毎回同じ(決定的)。

出発点:

グラフ上のノードを直接タップ/クリックしても出発点を変更できます。

拡散中(今このステップで届いた) 到達済 未到達 出発点

↑ 累積到達数の推移(S 字カーブ)── 拡散が起きると中盤で急に立ち上がる

👀 直感 ── つながりを伝って広がる

情報は「人 → その友人 → 友人の友人」とネットワークのエッジを伝って広がる。 p を小さく(例 0.1)すると多くのエッジが「不通」になり、 拡散は出発点の近所で止まる(局所消火)。 p を大きく(例 0.5)すると突然ネットワーク全体に火が回る。 この「ある p を境に急に全域へ広がる」現象が 閾値的な相転移(浸透相転移)で、 平均次数の逆数あたり(p ≈ 1/<k>)に臨界点がある。 S 字カーブの立ち上がりの鋭さがこの相転移の現れ。

ハブ(高次数ノード)から出発すると、 同じ p でも一気に多くの隣人へ届くため拡散が速く・大きくなる。 これが スーパースプレッダー の効果。 逆に 周辺(低次数)ノードから始めると、 火種がハブに到達するまでが遅く、 小さい p では途中で消えやすい。「ハブから」「周辺から」を切り替えて S 字カーブの高さを比べてみよう。

⚠️ 落とし穴 ── 観測されるバイラルは「本当の拡散」ではない

🚀 発展 ── より正確なモデルへ

🗺 概念マップ

関連概念を視覚的に整理した概念マップ。

ソーシャルメディアデータ 感情分析 トピックモデル(LDA) ネットワーク分析 Burst検出 画像認識 公的統計連携

マップ中心の SNS データから 6 軸が伸びる。 「自然言語処理 (本文解析)」「ネットワーク分析 (関係構造)」「時系列解析 (拡散ダイナミクス)」「画像認識 (投稿画像)」「感情分析 (極性スコア)」「プライバシー保護 (匿名化)」の順に下流処理が広がり、 SSDSE-B-2026 の人口・産業構造と組み合わせれば地域別の関心度マップが描ける。

🔗 隣接手法への橋渡し

「ソーシャルメディアデータ」は Twitter/X・Instagram・口コミから抽出する非構造データ であり、 上流の API 利用規約・倫理審査と下流のテキストマイニング・感情分析・ネットワーク分析を繋ぐ橋渡し役となる。 サンプリング偏り (年代・地域) を常に意識する必要がある。

⬆️ 上流: 取得・利用規約

⬌ 並列: 他の非構造データ

⬇️ 下流: 解析・倫理対応

ソーシャルメディアデータは API / 利用規約 → 前処理 → 感情・トピック分析 → プライバシー対応 という流れで、 規約違反・倫理リスクを上流で潰してから解析に進む。

🌳 手法選択フロー

「ソーシャルメディアデータ」を扱うかは、 API アクセス権と代表性の許容範囲で判断する。

  1. 公式 API でアクセスできるか? Yes → X API / Mastodon API 等で取得、 No → 利用規約違反の可能性、 代替データ検討
  2. 母集団代表性が必要か? Yes → SNS は若年偏重、 SSDSE-B-2026 等の公式統計と併用、 No (現象観察のみ) → そのまま使用
  3. 個人情報を含むか? Yes → 匿名化・集計化、 倫理審査必須、 No → 公開投稿のみ集計

ソーシャルメディアデータは速報性が高いが、 ユーザー属性が偏る (Twitter/X は若年男性多め)。 SSDSE-B-2026 のような悉皆統計と組み合わせて補正するのが望ましい。

🔍 解説深化 ── 「分母の統計学」:人口当たり言及率ランキングに潜む小規模県の罠

本ページではここまで、 SNS 言及数を県間比較するには「人口千人当たり」に正規化し、 年齢構成で補正すべきだと述べてきた。 この節ではさらに一歩進み、 正しく正規化した「後」でも残る問題を扱う。 それは「率のゆらぎの大きさは分母(人口)の平方根に支配される」という、 SNS 分析に限らず割合データ全般に潜む統計的性質である。 姉妹ページが扱う「誰が SNS を使うか」の偏り(選択バイアス)とは独立に、 偏りゼロでも起こる点が要注意。

👀 直感 ── 小さい県は「試行回数の少ないコイン投げ」

コインを 10 回投げて表が 7 回出ても驚かないが、 10,000 回投げて 7,000 回表なら偽コインを疑う。 割合の観測値は分母が小さいほど激しく揺れる(標準誤差は分母の平方根に反比例)。 SSDSE-B-2026 の 2023 年実測値(A1101 総人口)で分母の開きを見ると:

都道府県(2023 年)総人口(実測値)備考
東京都14,086,000 人最大
神奈川県9,229,000 人第 2 位
中央値の県1,549,000 人47 県の中央値
高知県666,000 人下から 3 番目
島根県650,000 人下から 2 番目
鳥取県537,000 人最小

東京都と鳥取県の人口比は 26.2 倍。 したがって、 仮に両県の「真の言及率」が全く同じでも、 観測される率のゆらぎ(標準誤差)は鳥取県が東京都の √26.2 ≈ 5.1 倍になる。 これは補正では消えない、 分母の大きさそのものが生む差である。

数値例(※言及率は架空の仮定・人口のみ実測値):全県で「ある話題を 1 日に人口の 0.01% が投稿する」という架空の一様シナリオを置くと、 期待件数は 東京都 ≈ 1,409 件/日、 鳥取県 ≈ 54 件/日。 日次件数のポアソン的ゆらぎ(±2√λ)は 東京都 ±75 件(相対 約 ±5%)に対し、 鳥取県 ±15 件(相対 約 ±27%)。 つまり鳥取県では真の関心度が一定でも 39 件の日も 69 件の日も普通に起こり、 たまたま並べば「前日比 1.8 倍の急騰」に見えてしまう。 東京都で同じ相対変動が偶然起こることはまずない。

⚠️ 落とし穴(重要)── ランキングの両端は小規模県で埋まる

🚀 発展 ── 小さい分母と戦う統計の道具

🔗 関連ページ