2026年7月更新:Sorsa の100回分の無料リクエストを収集と始め方のステップに追加し、収集コストを1,000ツイートあたりのバッチレートで捉え直しました。以前の更新で、X API の料金とレート制限を刷新し、Sentiment140 での学習可能な分類器の案内と、ワードクラウドのステップを追加しました。
要点: Twitter感情分析は、自然言語処理でツイートをポジティブ、ネガティブ、またはニュートラルに分類します。パイプラインには2つの段階があります。API またはデータセットを通じてツイートデータを収集し、それからそのテキストを VADER、TextBlob、または RoBERTa のようなトランスフォーマーを使って分類することで、後者は英語のツイートでおよそ88〜91%の精度に達します。
ほとんどの感情分析のチュートリアルは、2009年の静的な CSV を手渡し、難しい部分、つまり新鮮なツイートを取ってくることを飛ばします。本ガイドは両方の半分を扱い、収集のステップには、代替の Twitter/X API プロバイダーである Sorsa API を使います。経済性が反論しがたいからです。/search-tweets エンドポイント への1回の呼び出しは、完全な作者プロフィールを添付した最大20ツイートを返し、1リクエストとして数えられるため、10,000ツイートのデータセットは$199の Proプランで約1ドル、公式 X API のおよそ$150に対してかかります。アクセスはヘッダーの1つの API キーで、OAuth も開発者アカウントの承認もなく、すべてのプランで一律の毎秒20リクエスト、そして公式 API より最大50分の1の料金です。最初の100リクエストは無料で、クレジットカード不要なので、以下のパイプライン全体は何も支払う前にプロトタイプできます。
当社はこの API をビルドして運用し、以下の分類器を自分たちで収集したデータに対してテストするため、ここのワークフローは実際に動かしているものです。ツールが変わってもアーキテクチャは何年も変わっていません。収集、クリーニング、分類、可視化です。本ガイドの残りは、実行可能な Python で各段階を案内します。
目次
- Twitter感情分析とは?
- 2026年になぜ Twitter感情分析が依然として重要か
- ステップ1:ツイートデータの収集
- ステップ2:ツイートのクリーニングと前処理
- ステップ3:感情分類の手法を選ぶ
- ステップ4:Python で感情分析を実行する
- ラベル付きデータで自分の分類器を学習させる
- ステップ5:結果の可視化と解釈
- どの手法を使うべきか?
- よくある落とし穴とエッジケース
- 実用的なユースケース
- これを完全なプロジェクトとして構築する
- よくある質問
- 始め方
Twitter感情分析とは? {#what-is-twitter-sentiment-analysis}
Twitter感情分析は、オピニオンマイニングとも呼ばれ、ツイートがポジティブ、ネガティブ、またはニュートラルな意見を表現しているかを検出する自動化されたプロセスです。より高度なシステムは、これを怒り、喜び、悲しみのような特定の感情に、またはツイートで名指しされた特定のエンティティに向けられた感情に拡張します。
すべてのパイプラインは3つの構成要素の上に載っています。
- データソース:API、データセット、またはスクレイピングを通じて収集されたツイート。
- 前処理:URL、メンション、絵文字、スラングのようなノイズを取り除くために生のテキストをクリーニングすること。
- 分類:ルールベースの辞書、学習させた機械学習モデル、または事前学習済みのトランスフォーマーを使って感情のラベルを割り当てること。
出力はラベル(ポジティブ、ネガティブ、またはニュートラル)と、通常は信頼度スコアです。その出力で何をするかは目標次第です。ブランド監視、市場調査、学術研究、またはリアルタイムのアラートです。
2026年になぜ Twitter感情分析が依然として重要か {#why-twitter-sentiment-analysis-still-matters-in-2026}
X(旧Twitter)は依然として、公共の意見がリアルタイムで、短く分類可能な断片で表面化する数少ないプラットフォームの1つです。X はもはや公式の数字を公表しないため推定はばらつきますが、独立したトラッカーは2026年初頭時点でプラットフォームをおよそ5億5,000万〜6億の月間アクティブユーザーに置き、ブランド、製品、政治、イベントについての意見を、NLP に構造的に理想的な形式で投稿しています。
3つの性質がそのデータを特に有用にします。
量と速度。 トレンドのトピックは数時間で数百万の投稿を生み出せます。どんな調査やフォーカスグループもそれほど速くシグナルを生み出しません。
デフォルトで公開。 ほとんどのツイートは公開で API を通じて到達可能で、それが Facebook や Instagram のようなプラットフォームで感情の作業を複雑にする同意とアクセスの障壁を取り除きます。
キュレーションされたコンテンツではなく反応データ。 人々はその瞬間に投稿します。キャンセルされたフライトについて放たれたツイートは、3日後に書かれた磨かれたレビューより、実際の顧客の感情について多くを語ります。その生の質は処理がより難しいですが、分析するにはより正直です。
ステップ1:ツイートデータの収集 {#step-1-collecting-tweet-data}
ここでほとんどのチュートリアルは期待を裏切ります。古典的なレシピはこうでした。Tweepy をインストールし、Twitter の無料 API で認証し、ツイートを引く。そのパイプラインは、Twitter が無料の API アクセスを削除した2023年に壊れ、コストはそれ以来上がっています。
2026年のデータ収集の状況
ツイートを Python のパイプラインに取り込むための3つの現実的な選択肢があります。
選択肢 A:静的なデータセット。 Sentiment140(2009年からの160万ツイート)や TweetEval ベンチマーク のような事前ラベル付けされたセットをダウンロードします。学習とプロトタイプには良いですが、データは何年も古いため、現在のイベントや自分のブランドを分析できません。
選択肢 B:公式 X API。 2026年時点で、X は新規アカウントにサブスクリプション層のない従量課金モデルを運用します。投稿読み取りごとに$0.005、ユーザープロフィールごとに$0.010を、月200万投稿読み取りのハードな上限で支払います。20ツイートを返す検索は投稿読み取りで$0.10、作者プロフィールが欲しいならさらに$0.20かかります。認証は OAuth 2.0 です。ユーザーデータ付きの10,000ツイートのデータセットには、およそ$150かかります。
選択肢 C:サードパーティ API。 Sorsa のようなプロバイダーは、同じ公開の Twitter データを、フラットなリクエスト単位の料金でプレーンな REST エンドポイントを通じて提供します。検索エンドポイントへの1回の呼び出しは、結果のサイズが何であれ、完全な作者プロフィールを含む最大20ツイートを返し、1リクエストとして数えられます。Proプラン(10万リクエストで月額$199)では、その同じ10,000ツイートのデータセットは約$1かかります。認証はヘッダーの1つの API キーで、OAuth のフローも承認の待ちもありません。
収集コストを、各選択肢の実際の数字とともに並べて示します。
| 方法 | 認証 | ライブデータ | 10,000ツイートのコスト(作者データ込み) | 月間上限 |
|---|---|---|---|---|
| 静的データセット(Sentiment140) | なし | 不可 | 無料 | 該当なし |
| 公式 X API(従量課金) | OAuth 2.0 | 可 | 約$150 | 200万投稿読み取り |
| Sorsa(Proプラン) | API キー | 可 | 約$1 | プラン依存(10万リクエスト) |
モデリングを学ぶには、静的なデータセットで問題ありません。現在に結びついた何かには、フラットレートの Twitter/X API がコストの急騰と OAuth のセットアップの両方を取り除きます。両プロバイダーの完全な数字は、Twitter/X API 料金の内訳 にあります。まだ収集のアプローチを比較しているなら、X データを引くための Python ワークフロー が以下の requests ベースのセットアップをより深く扱います。
Python でツイートを収集する
requests ライブラリをインストールします。
pip install requests
この関数は、検索クエリに一致するツイートを収集し、ページネーションを扱います。
import requests
import time
def collect_tweets(query, api_key, max_tweets=500):
"""
Collect tweets from the Sorsa /search-tweets endpoint.
Returns a list of tweet dicts with text, metadata, and author info.
"""
url = "https://api.sorsa.io/v3/search-tweets"
headers = {
"ApiKey": api_key,
"Content-Type": "application/json",
}
all_tweets = []
next_cursor = None
while len(all_tweets) < max_tweets:
payload = {"query": query, "order": "latest"}
if next_cursor:
payload["next_cursor"] = next_cursor
response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()
data = response.json()
tweets = data.get("tweets", [])
if not tweets:
break
all_tweets.extend(tweets)
next_cursor = data.get("next_cursor")
if not next_cursor:
break
time.sleep(0.05) # stay under the rate limit
return all_tweets[:max_tweets]
# Usage
API_KEY = "YOUR_API_KEY"
tweets = collect_tweets(
query='"iPhone 17" lang:en -filter:retweets',
api_key=API_KEY,
max_tweets=500,
)
print(f"Collected {len(tweets)} tweets")
この関数についていくつかの具体的な点:
- クエリは Twitter 検索コマンド を使って、英語のオリジナル投稿にフィルターしリツイートを落とします。スパムを切るには
min_faves:5を、日付範囲を区切るにはsince:2026-04-01を加えます。 - レスポンスの各ツイートは、
full_text、created_at、エンゲージメント指標(likes_count、retweet_count、reply_count、view_count)、そしてuserの下にネストされた完全な作者プロフィールを運びます。ユーザーデータに追加の呼び出しは要りません。 next_cursorフィールドが ページネーション を駆動します。それが null で返ってきたら、終わりに達しています。- 1ページ20ツイートで、500ツイートは25リクエストかかり、それは Proプランで約$0.05です。
大きな収集には、複数のクエリ(異なるキーワード、日付の窓、またはアカウント)を並行して実行し、後でツイート ID で重複排除します。
ステップ2:ツイートのクリーニングと前処理 {#step-2-cleaning-and-preprocessing-tweets}
生のツイートは雑然としています。1つの投稿が、メンション、URL、ハッシュタグ、絵文字、スラング、誤字、そして2つ以上の言語を混ぜられます。それをまっすぐ分類器に与えると精度が下がります。
この関数は最もよくあるノイズを扱います。
import re
def clean_tweet(text):
"""Clean a tweet for sentiment analysis."""
text = re.sub(r'@\w+', '', text) # remove @mentions
text = re.sub(r'https?://\S+', '', text) # remove URLs
text = re.sub(r'^RT\s+', '', text) # remove RT prefix
text = text.replace('#', '') # keep the word, drop the hash
text = re.sub(r'\s+', ' ', text).strip() # collapse whitespace
return text
for tweet in tweets:
tweet['clean_text'] = clean_tweet(tweet['full_text'])
絵文字はどうする?
絵文字は強い感情のシグナルを運びます。「new update 💀🤡」と読むツイートは、それらを取り除くと消える明確なネガティブなトーンを持っています。2つの合理的なアプローチ:
- 絵文字を保つ。 そしてそれらを理解する分類器を使います(VADER と RoBERTa は両方とも理解します)。
- 絵文字をテキストに変換する。
emojiライブラリ(pip install emoji)で、😊 を:smiling_face_with_smiling_eyes:に変え、それが絵文字をネイティブに読まない辞書ツールを助けます。
RoBERTa のようなトランスフォーマーのモデルには、絵文字をそのまま保ちます。モデルは学習中にその意味を学びました。
ステミングかレンマ化をすべき?
多くのチュートリアルは、ステミングとレンマ化を必須として扱います。そうではありません。TF-IDF の特徴と伝統的なモデル(ナイーブベイズ、SVM)では、ステミングは語彙のサイズを縮め、役立つことがあります。事前学習済みのトランスフォーマーや VADER のような辞書ツールでは、飛ばします。それらのツールは語形を内部で扱い、攻撃的なステミングはシグナルを破壊します。「Unhappy」を「unhappi」にステミングすると、その辞書の一致を失います。
ステップ3:感情分類の手法を選ぶ {#step-3-choosing-a-sentiment-classification-method}
これがパイプラインで最も重要なアーキテクチャの決定です。4つの広いアプローチがあり、それぞれ精度、速度、コスト、セットアップで異なるトレードオフを持ちます。
アプローチ1:ルールベースの辞書(VADER、TextBlob)
これらは、極性についてスコア付けされた語の辞書を同梱し、否定と強調のルールを適用し、複合スコアを出力します。
VADER(Valence Aware Dictionary and sEntiment Reasoner)はソーシャルメディアのために作られました。絵文字、スラング、大文字化(「GREAT」は「great」より高くスコア付けされる)、そして程度の修飾語(「very good」対「good」)を扱い、モデルの読み込みや GPU なしで即座に動きます。
TextBlob は製品レビューから導かれた辞書を使い、極性(-1〜+1)と主観性(0〜1)を返します。VADER より単純で、ソーシャルテキストへのチューニングは弱いです。
使うべきとき: 素早いプロトタイプ、レイテンシーが重要なリアルタイムのスコアリング、またはどの語がスコアを駆動したかを検査する必要があるとき。曖昧なテキストには弱いです。
アプローチ2:伝統的な ML 分類器(ナイーブベイズ、SVM、ロジスティック回帰)
TF-IDF の特徴を使ってラベル付きのツイートで分類器を学習させます。これはトランスフォーマー以前の標準でした。ラベル付きの学習セット(Sentiment140 が通常の選択)が必要で、モデルはそこから語と感情の関連を学びます。TF-IDF 付きのロジスティック回帰は、Sentiment140 で通常およそ80〜82%の精度に達し、数分で学習します。完全な案内は下の 学習のセクション にあります。
使うべきとき: ドメイン固有のラベル付きデータを持ち、GPU インフラなしで動く軽量なモデルが欲しいとき。
アプローチ3:事前学習済みのトランスフォーマー(RoBERTa)
Hugging Face の cardiffnlp/twitter-roberta-base-sentiment-latest モデルは、2018年から2021年のおよそ1億2,400万ツイートで学習され、TweetEval ベンチマークでファインチューニングされました。テキストをネガティブ、ニュートラル、ポジティブに、辞書や古典的な ML のアプローチより著しく高い精度で分類します。公表されたベンチマークは、RoBERTa ベースのモデルを Twitter の感情タスクで88〜91%前後に置き、VADER と TextBlob のおよそ73〜75%に対しています。
使うべきとき: 精度が速度より重要なとき。transformers ライブラリと、バッチ作業には理想的には GPU を必要としますが、より小さいセットには CPU の推論で問題ありません。
アプローチ4:商用プラットフォーム(Sprinklr、Brandwatch、Meltwater)
組み込みの感情分析を持つエンタープライズのソーシャルリスニングのツール。収集、分類、ダッシュボードをまとめ、月数千の料金です。
使うべきとき: 何も構築せずにダッシュボードと多言語のサポートを必要とするエンタープライズのチーム。焦点を絞ったパイプラインを出荷する開発者には過剰で、前処理とモデルの選択への制御を手放します。
ステップ4:Python で感情分析を実行する {#step-4-running-sentiment-analysis-in-python}
以下の3つのコードベースのアプローチは、ステップ1で収集したツイートで動きます。
方法1:VADER
pip install vaderSentiment
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
analyzer = SentimentIntensityAnalyzer()
def vader_sentiment(text):
scores = analyzer.polarity_scores(text)
compound = scores['compound']
if compound >= 0.05:
return 'positive', compound
elif compound <= -0.05:
return 'negative', compound
else:
return 'neutral', compound
for tweet in tweets:
label, score = vader_sentiment(tweet['clean_text'])
tweet['vader_label'] = label
tweet['vader_score'] = score
from collections import Counter
print(Counter(t['vader_label'] for t in tweets))
VADER は速いです。ラップトップでおよそ毎秒10,000ツイートです。複合スコアは -1(最もネガティブ)から +1(最もポジティブ)まで動き、元の論文が推奨するプラスマイナス0.05のしきい値です。
方法2:TextBlob
pip install textblob
from textblob import TextBlob
def textblob_sentiment(text):
polarity = TextBlob(text).sentiment.polarity
if polarity > 0:
return 'positive', polarity
elif polarity < 0:
return 'negative', polarity
else:
return 'neutral', polarity
for tweet in tweets:
label, score = textblob_sentiment(tweet['clean_text'])
tweet['textblob_label'] = label
tweet['textblob_score'] = score
TextBlob は VADER のおよそ2倍遅いですが、それでも速いです。1つの注意点:その辞書は製品レビューから来たため、語がその語彙の外に落ちるとき、スラングの多いツイートをニュートラルとマークする傾向があります。
方法3:事前学習済みの RoBERTa トランスフォーマー
pip install transformers torch scipy
from transformers import AutoModelForSequenceClassification, AutoTokenizer
from scipy.special import softmax
import numpy as np
MODEL = "cardiffnlp/twitter-roberta-base-sentiment-latest"
tokenizer = AutoTokenizer.from_pretrained(MODEL)
model = AutoModelForSequenceClassification.from_pretrained(MODEL)
labels_map = {0: 'negative', 1: 'neutral', 2: 'positive'}
def preprocess_for_roberta(text):
"""Replace @mentions and URLs with the placeholders the model expects."""
out = []
for token in text.split():
token = '@user' if token.startswith('@') and len(token) > 1 else token
token = 'http' if token.startswith('http') else token
out.append(token)
return ' '.join(out)
def roberta_sentiment(text):
processed = preprocess_for_roberta(text)
encoded = tokenizer(processed, return_tensors='pt', truncation=True, max_length=512)
scores = model(**encoded).logits[0].detach().numpy()
probs = softmax(scores)
idx = int(np.argmax(probs))
return labels_map[idx], float(probs[idx])
# Feed the original text, not the cleaned version: RoBERTa does its own preprocessing
for tweet in tweets:
label, confidence = roberta_sentiment(tweet['full_text'])
tweet['roberta_label'] = label
tweet['roberta_confidence'] = confidence
RoBERTa は自分の前処理を期待します。メンションは @user に、URL は http になります。それを学習した文脈を見るように、元のツイートのテキストを与えます。CPU ではおよそ毎秒5〜15ツイートを処理し、控えめな GPU でさえそれは200を超えて跳ね上がります。10,000ツイートを超えたら、GPU でバッチします。
ラベル付きデータで自分の分類器を学習させる {#training-your-own-classifier-on-labeled-data}
事前学習済みのモデルはほとんどのニーズをカバーします。自分のを学習させるのは、ドメインの言語が一般的なツイートから遠く離れて座り(金融、医療、法律、非英語)、ラベル付きの例を持つときだけです。すべてのチュートリアルレベルのパイプラインは同じ形に従うので、端から端まで見る価値があります。ラベル付きのツイートを読み込み、TF-IDF でベクトル化し、分類器を学習させ、指標を読みます。
pip install pandas scikit-learn
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
# Sentiment140: columns are polarity, id, date, query, user, text
cols = ['polarity', 'id', 'date', 'query', 'user', 'text']
df = pd.read_csv('sentiment140.csv', header=None, names=cols, encoding='latin-1')
# Map labels: 0 stays negative, 4 becomes positive
df = df[df['polarity'].isin([0, 4])].copy()
df['label'] = df['polarity'].map({0: 0, 4: 1})
df['clean_text'] = df['text'].apply(clean_tweet) # reuse the cleaner from Step 2
X_train, X_test, y_train, y_test = train_test_split(
df['clean_text'], df['label'], test_size=0.2, random_state=42
)
vectorizer = TfidfVectorizer(max_features=5000, ngram_range=(1, 2))
X_train_vec = vectorizer.fit_transform(X_train)
X_test_vec = vectorizer.transform(X_test)
# class_weight='balanced' guards against skewed label counts
clf = LogisticRegression(max_iter=1000, class_weight='balanced')
clf.fit(X_train_vec, y_train)
print(classification_report(y_test, clf.predict(X_test_vec)))
新しいツイートを分類するには、clf.predict を呼ぶ前に、それらを同じクリーナーとベクトライザーに通します。ラベルが大きく不均衡なら(実際のブランドデータではよくあり、ニュートラルが支配する)、class_weight='balanced' を保つか、モデルを多数派クラスに崩れさせる代わりに SMOTE で少数派クラスをオーバーサンプリングします。
ほとんどのチームが使う実用的な近道:小さなサンプルを手で、または事前学習済みの RoBERTa モデルでラベル付けし、質を見直し、それから結果でファインチューニングします。そのラベル付きセットを、検索エンドポイントで収集したライブデータから構築できるため、ステップ1の同じ収集コードが事前学習済みとカスタムの両方の道を養います。学習コーパスを組み立てラベル付けするより充実した案内は、機械学習用の Twitter データセットを構築する ガイドをご覧ください。
ステップ5:結果の可視化と解釈 {#step-5-visualizing-and-interpreting-results}
生のラベルは有用です。感情のトレンドは行動可能です。分類されたツイートを、ステークホルダーが行動できる何かに変える方法はこうです。
import pandas as pd
df = pd.DataFrame(tweets)
df['created_at'] = pd.to_datetime(df['created_at'])
# Distribution
print(df['roberta_label'].value_counts(normalize=True))
# Sentiment over time (hourly buckets)
df.set_index('created_at', inplace=True)
hourly = df.groupby([pd.Grouper(freq='h'), 'roberta_label']).size().unstack(fill_value=0)
hourly.plot(kind='area', stacked=True, figsize=(14, 6), title='Sentiment Over Time')
ブランド監視には、最も行動可能な指標は、しばしば全体の比率ではなくその変化です。通常60%のポジティブで動くブランドが40%に落ちることは、絶対の数字がまだほとんどポジティブに見えるときでも、調査に値する問題を示します。
騒がしいツイートがより多く数えられるように、感情をリーチで重み付けします。API のレスポンスは、すべてのツイートに likes_count、retweet_count、view_count を含み、Twitter エンゲージメント API ガイド が返信、引用、リツイート者についてカバーするのと同じエンゲージメントのフィールドです。
df['weighted_sentiment'] = df['vader_score'] * df['view_count']
print(f"Weighted sentiment index: {df['weighted_sentiment'].sum():.2f}")
ワードクラウドは、感情のクラスを駆動しているものを見る最も速い方法です。それをラベルで分けると、ネガティブの背後の実際の不満が分かります。
from wordcloud import WordCloud
negative_text = " ".join(
t['clean_text'] for t in tweets if t.get('roberta_label') == 'negative'
)
WordCloud(width=1200, height=600, background_color='white') \
.generate(negative_text).to_file('negative_wordcloud.png')
どの手法を使うべきか? {#which-approach-should-you-use}
公表されたベンチマークと実世界の使用に基づく実用的な比較はこうです。
| VADER | TextBlob | ロジスティック回帰(TF-IDF) | RoBERTa(twitter-roberta-base) | |
|---|---|---|---|---|
| Twitter データでの精度 | 約73〜75% | 約71〜73% | 約80〜82% | 約88〜91% |
| セットアップ時間 | 2分 | 2分 | 30〜60分(学習データが必要) | 10分(事前学習済み) |
| 速度(CPU) | 約10,000ツイート/秒 | 約5,000ツイート/秒 | 約8,000ツイート/秒 | 約5〜15ツイート/秒 |
| GPU が必要 | 不要 | 不要 | 不要 | 1,000ツイート超で推奨 |
| 絵文字の扱い | はい(ネイティブに) | 不得意 | 学習データにある場合のみ | はい(1億2,400万ツイートで学習) |
| 皮肉の扱い | 不得意 | 不得意 | ある程度 | より良いが依然限定的 |
| 3クラス(ポジ/ネガ/ニュートラル) | はい | しきい値ありで | ラベル次第 | はい(ネイティブ) |
| カスタムドメインの学習 | 不可(固定辞書) | 不可(固定辞書) | 可 | 可(ファインチューニング) |
精度の数字は、TweetEval データセットと Sentiment140 のベンチマークから来ています。自分のデータでの実際の性能は、ドメイン、言語の混ざり、そして曖昧または皮肉なテキストの割合で変わります。
実際には、まず素早いベースラインのために VADER から始めます。精度が重要になったら、事前学習済みの RoBERTa モデルに切り替えます。ドメインの言語(医療、法律、非英語)が事前学習済みの選択肢を本当に打ち負かすときだけ、カスタムモデルを学習させます。
よくある落とし穴とエッジケース {#common-pitfalls-and-edge-cases}
これらは、感情のプロジェクトを横断して何度も何度も出てくる問題です。
皮肉の検出
「Great, another app update that breaks everything I use daily.」すべての辞書とほとんどの ML モデルは、「great」のせいでこれをポジティブと読みます。トランスフォーマーは皮肉をより頻繁に捕らえますが、どれも信頼できません。皮肉が自分のドメイン(テック Twitter、政治的な論評)でよくあるなら、皮肉のレイヤーを加えるか、しばしばバイラルな皮肉の投稿を隠す「高エンゲージメントのポジティブ」のクラスターを手で見直します。
ボットとスパムの混入
自動化されたアカウントは分布を歪めます。協調したキャンペーンは、トピックを圧倒的にポジティブまたはネガティブに見せられます。エンゲージメントのしきい値(検索クエリの min_faves:1)でフィルターし、アカウントをまたぐ重複またはほぼ重複のテキストをチェックします。
リツイートのバイアス
リツイートを含めると、5万回リツイートされた1つのバイラルなネガティブツイートがデータセットを支配します。-filter:retweets コマンドはネイティブのリツイートを取り除きます。論評を加える引用ツイートには、それらを保ちますが引用のテキストだけをスコア付けします。
言語の混ざり
Twitter はグローバルです。lang:en でさえ、コードスイッチングされたツイート(「this movie was vraiment terrible」)や翻字されたテキストにぶつかります。ツイートのレスポンスの lang フィールドはほとんどのケースで信頼できますが、短いまたは絵文字の多い投稿は誤分類されます。純度が重要なら、langdetect で二次のチェックを加えます。
否定の扱い
「Not bad」はポジティブです。「Not good at all」はネガティブです。VADER は基本的な否定をよく扱い、TextBlob は苦戦し、RoBERTa は孤立した語をスコア付けするのではなく完全な文を読むため、複雑な否定を両者より良く扱います。
実用的なユースケース {#practical-use-cases}
ブランド監視
感情分析は、ほとんどの ソーシャルリスニング プログラムの背後のエンジンです。自社のブランド名、製品、またはキャンペーンのハッシュタグを巡る感情をリアルタイムで追跡します。最小のエンゲージメントと日付範囲のフィルターをサポートする Sorsa の /mentions エンドポイント を通じてメンションを収集し、それらを RoBERTa に通し、ネガティブな感情がしきい値を越えたときにチームにアラートします。同じパターンが、ほとんどの リアルタイムの Twitter 監視 のセットアップを支えます。
金融市場の感情
暗号資産と株式のデスクは、Twitter の感情を代替データのシグナルとして使います。感情のスコアを、キャッシュタグの検索($TSLA、$BTC)とエンゲージメントの重み付けと組み合わせて感情の指数を構築します。Sorsa の Score エンドポイントは、暗号資産のエコシステム内でアカウントの影響力をスコア付けするレイヤーを加えるため、誰が投稿しているかでシグナルを重み付けできます。
学術研究
選挙、健康の危機、または社会運動を研究する研究者は、大きく時間で区切られたデータセットを必要とします。日付範囲のコマンド(since:2026-01-01 until:2026-03-01)を使って正確なスライスを収集します。過去のアーカイブは、アーカイブの追加料金なしで2006年まで遡ります。古い投稿を照会するより充実した案内は、過去の Twitter データを検索する ガイドをご覧ください。
顧客フィードバックの分析
感情をトピック抽出と組み合わせて、顧客が不満であることだけでなく、何について不満かを見つけます。ネガティブなツイートをキーワードでクラスタリングし、それから上位のクラスターを手で見直します。これは定量的なスコアリングと定性的な洞察を橋渡しします。
実践
協力したおよそ12人の市場調査チームは、公式 X API でブランドのメンションを引いていて、月末の前に200万投稿読み取りの上限に当たり続け、それが製品ローンチが最も多くのカバレッジを必要とするまさにそのときに収集を絞ることを強いました。収集のレイヤーをフラットレートの Twitter/X API に移すことで上限の問題が取り除かれ、月間のデータ料金が大幅に削られました。リクエスト単位のモデルはリソース単位の課金より最大50分の1のコストなので、その状況のチームは通常、同じ量に対して収集の支出が同様の係数で下がります。このチームの分類器のスタックはまったく変わりませんでした。ツイートのソースだけが変わりました。
これを完全なプロジェクトとして構築する {#building-this-as-a-complete-project}
上の5つの段階はすでにポートフォリオ級のプロジェクトを形作り、それが「twitter sentiment analysis」がそれほどよくある卒業制作や研究のビルドである理由です。スニペットの集合ではなく1つの首尾一貫したプロジェクトとしてパッケージするには、分析する単一のトピック(製品、ワクチン、選挙、株)を選び、検索エンドポイントで数千のツイートをそれについて収集し、それらをクリーナーと選んだ分類器に通し、ステップ5の時系列のチャートとワードクラウドで仕上げます。
再現可能な報告のために、3つのことを記録します。正確な検索クエリと日付範囲、分類器とそのバージョン、そして最終的に得たラベルの分布です。その3つ組が、誰でも同じ分析を再実行することを可能にし、それがまさにレビュアー(と採点者)が探すものです。デプロイ可能な表面が欲しいなら、パイプラインを小さな Streamlit または Flask のアプリに包んで、非技術のユーザーがキーワードを入力して感情の内訳を見られるようにします。データのレイヤーが、通常人々をつまずかせる唯一の部分で、フラットレートの 代替 X API が、学生や研究の予算のためにそのレイヤーを安く承認不要に保ちます。
よくある質問 {#faq}
Twitter感情分析にはどの Python ライブラリが必要?
収集には、REST API を使うなら requests で十分です。分類には、3つのよくあるライブラリが vaderSentiment(ルールベース、ソーシャルメディア向けにチューニング)、textblob(ルールベース、汎用)、そして Hugging Face の transformers(RoBERTa のような事前学習済みモデル用)です。データの処理に pandas を、可視化に matplotlib または wordcloud を加えます。1行のインストール:pip install requests vaderSentiment textblob transformers torch pandas matplotlib wordcloud。
Twitter感情分析はどれくらい正確?
精度は手法に完全に依存します。VADER のようなルールベースのツールは、標準の Twitter ベンチマークでおよそ73〜75%に達します。伝統的な ML 分類器(TF-IDF 付きのロジスティック回帰または SVM)は約80〜82%に達します。twitter-roberta-base-sentiment-latest のような事前学習済みのトランスフォーマーは88〜91%に当たります。どの手法も皮肉や重い文脈を信頼して扱えないため、本番ではエッジケースの10〜15%を手で見直すことを見込みます。
Twitter 開発者アカウントなしで感情分析用のライブツイートを収集する最も簡単な方法は?
2026年の最も単純な経路はサードパーティの REST API です。Sorsa API は、ヘッダーの1つの API キーを使って /search-tweets エンドポイントから完全な作者プロフィール付きのライブツイートを返し、OAuth も開発者アカウントの承認もありません。最初の100リクエストは無料で、クレジットカード不要かつ有効期限なしなので、何かを支払う前に最初のバッチを収集し分類できます。1回の呼び出しは最大20ツイートを返し、一律の毎秒20リクエストの制限に対して1リクエストとして数えられ、コードを書く前に無料の検索ビルダーでクエリを先にプロトタイプできます。
ツイートの感情分析には VADER と TextBlob のどちらが良い?
VADER は Twitter に特化してより良いです。ソーシャルメディアのテキストのために設計され、TextBlob のレビューベースの辞書が見逃す絵文字、スラング、大文字化の強調、そして程度の修飾語(「very good」対「good」)を扱います。比較研究では、VADER はソーシャルテキストで TextBlob をおよそ2〜3%ポイント上回ります。TextBlob を使うのは、その主観性スコアも欲しいか、より形式的なテキストを扱っているときだけにします。
英語以外の言語のツイートをどう扱う?
本ガイドの英語のツール(VADER、TextBlob、Cardiff の RoBERTa モデル)は英語専用です。多言語の感情には、Hugging Face の cardiffnlp/twitter-xlm-roberta-base-sentiment を使い、それは多くの言語をサポートします。収集するとき、lang: コマンド(たとえばスペイン語には lang:es、フランス語には lang:fr)で言語をフィルターし、その言語で学習された分類器を選びます。
感情分析のためにツイートを収集するのにいくらかかる?
公式 X API(2026年時点で従量課金)では、各投稿読み取りが$0.005、各ユーザープロフィールが$0.010かかるため、作者データ付きの10,000ツイートはおよそ$150かかります。Sorsa のようなフラットレートのプロバイダーでは、同じ10,000ツイートは$199の Proプランで約$1かかります。1回の検索リクエストがプロフィール込みで最大20ツイートを返すからです。そのギャップは、読み取りの重い作業では最大50分の1のコストにまで開き、それがほとんどの感情のパイプラインが量が増えるとリソース単位の課金から移る理由です。
Twitter感情分析は皮肉を検出できる?
どの現行のツールでも、信頼しては検出できません。皮肉は文脈、文化的な知識、ときには作者の履歴に依存し、そのどれも単一のツイートのテキストは提供しません。RoBERTa のようなトランスフォーマーは、辞書ツールより明白な皮肉をより頻繁に捕らえますが、ベンチマークは最良のモデルでさえ専用の皮肉の検出で約70〜75%にしか達しないことを示します。重要な作業には、ラベルがエンゲージメントと矛盾するツイート(怒った返信のある「ポジティブ」なツイート)にフラグを立て、それらを見直します。
Twitter 感情分類器の学習に最適なデータセットは?
Sentiment140(ポジティブまたはネガティブとラベル付けされた160万ツイート)は最も広く使われる学習セットですが、そのデータは2009年からで、ニュートラルのクラスがありません。3クラスの作業には、Cardiff NLP の TweetEval ベンチマークが現行の標準で、twitter-roberta-base-sentiment モデルがファインチューニングされたものです。ドメイン固有の作業には、自分のセットをラベル付けします。事前学習済みのモデルを使って大きなコーパスをラベル付けし、サンプルを見直し、それから結果でファインチューニングします。
始め方 {#getting-started}
ライブの Twitter データで感情のパイプラインを構築するには、最も速い道はこうです。
- API キーを取得します。 Sorsa ダッシュボード から。最初の100リクエストは無料です。1回限り、クレジットカード不要、有効期限なし、そして40個のエンドポイントのすべてが含まれ、それは何かを支払う前に最大10,000ツイートまたは20,000プロフィールを引くのに十分です。その後、バッチ収集は1,000ツイートあたり$0.02から動作し、有料プラン は10,000リクエストで月額$49から始まり、承認のステップなしで数分でセットアップできます。
- クエリをプロトタイプします。 無料の 検索ビルダー で、コードを書かずに検索コマンドをテストし結果をプレビューできます。
- Python をコピーします。 本ガイドから、収集と分類を始めます。収集から可視化まで100行未満に収まります。
- ドキュメントを読みます。 docs.sorsa.io で、エンドポイントの詳細、ページネーション、そして一律の毎秒20リクエストの レート制限 について。
バッチエンドポイントや大規模な収集のためのカスタムプランは、Sorsa について または 営業に相談 をご覧ください。
監修:Keksich(Sorsa創業者、マーケター兼X APIリサーチャー)
これをどう組み立てたか:本ガイドは、代替の Twitter/X API をビルドして運用する Sorsa 自身の実地の作業と、上の分類器を自分たちで収集するライブデータに対して動かすことに基づいています。技術的な詳細を Sorsa API のドキュメント と、精度の数字が TweetEval ベンチマークまで遡る cardiffnlp/twitter-roberta-base-sentiment-latest の Hugging Face のモデルカードに対して確認しました。公式 X API の価格と200万投稿読み取りの上限は、本記事の更新中に現行の公開の料金に対して再確認しました。4つの分類のアプローチを端から端まで比較しました。最終確認2026年7月8日。