作者:Sorsa 编辑部

更新于 2026 年 7 月 8 日:把 Sorsa 的 100 次免费请求补进采集步骤和上手部分,并把采集成本改用每 1,000 条推文的批量费率表述。上一次更新刷新了 X API 定价和速率限制,加了一段在 Sentiment140 上训练分类器的走查,以及词云步骤。

核心要点: Twitter 情感分析用自然语言处理把推文分成正面、负面或中性。一条管道分两个阶段:先通过 API 或数据集采集推文,再用 VADER、TextBlob 或 RoBERTa 这类 transformer 给文本分类,其中 transformer 在英语推文上的准确率约为 88% 到 91%。

多数教程直接甩给你一份 2009 年的静态 CSV,跳过了最难的部分:拿到新鲜推文。本指南两半都讲。采集这一步用 Sorsa API,一个 Twitter/X API 替代服务商,理由是成本账很难反驳。调用一次 /search-tweets 接口最多返回 20 条推文,附完整作者资料,只算一次请求。所以 1 万条推文的数据集在 $199 的 Pro 套餐上大约花一美元,官方 X API 上则约 $150。接入只要请求头里一个 API 密钥,没有 OAuth,也不用等开发者账号审批,所有套餐统一 20 次/秒,价格最多可比官方 X API 便宜 50 倍。注册即送 100 次免费请求,无需绑卡,所以下面整条管道都能在花钱之前先跑通原型。

这个 API 是我们自己开发和运营的,下面的分类器也都在我们自己采集的数据上测过,所以这里的工作流就是我们实际在跑的。工具一直在变,架构多年没变:采集、清洗、分类、可视化。本指南剩下的部分用可运行的 Python 走一遍每个阶段。


目录


什么是 Twitter 舆情分析? {#what-is-twitter-sentiment-analysis}

Twitter 情感分析,也叫观点挖掘,就是自动判断一条推文表达的是正面、负面还是中性观点。更高级的系统会把它扩展到具体情绪(比如愤怒、喜悦、悲伤),或者针对推文中点名的某个实体单独判断情绪。

每条管道都由三个组件搭起来:

  1. 数据源。 通过 API、数据集或爬取采集到的推文。
  2. 预处理。 清洗原始文本,去掉 URL、提及、表情符号和俚语这类噪音。
  3. 分类。 用基于规则的词典、训练好的机器学习模型,或预训练 transformer 打上情感标签。

输出是一个标签(正面、负面或中性),通常还带一个置信度分数。拿这个输出做什么取决于你的目标:品牌监测、市场研究、学术研究,或者实时告警。


为什么 Twitter 舆情分析在 2026 年仍然重要 {#why-twitter-sentiment-analysis-still-matters-in-2026}

X(原 Twitter)仍是少数几个能让公众意见实时、以短小可分类片段浮出水面的平台之一。由于 X 不再发布官方数字,各方估计有出入,但独立追踪机构认为截至 2026 年初这个平台约有 5.5 亿到 6 亿月活用户。这些用户对品牌、产品、政治和事件发表看法,格式从结构上非常适合 NLP。

有三个特性让这份数据格外有用:

量大且快。 一个热门话题几小时就能产生数百万条帖子,没有哪种问卷或焦点小组能这么快产出信号。

默认公开。 多数推文是公开的,可以通过 API 获取,省掉了 Facebook、Instagram 这类平台上让舆情工作变复杂的授权和访问门槛。

是反应,不是精心打磨的内容。 人们是当下发帖的。航班被取消时随手发的一条推文,比三天后写的润色评论更能反映真实的客户情绪。这种原始质感更难处理,但分析起来更诚实。


第 1 步:采集推文数据 {#step-1-collecting-tweet-data}

这一步是多数教程掉链子的地方。经典配方是:装 Tweepy、用 Twitter 免费 API 认证、拉推文。这条路在 2023 年 Twitter 取消免费 API 访问时就断了,成本此后一路攀升。

2026 年的数据采集格局

想把推文送进 Python 管道,现实中有三个选项。

选项 A:静态数据集。 下载预标注数据集,比如 Sentiment140(2009 年的 160 万条推文)或 TweetEval 基准。学习和做原型够用,但数据已经好几年了,分析不了当前事件,也分析不了你自己的品牌。

选项 B:官方 X API。 截至 2026 年,X 走按量付费,对新账号没有订阅套餐。帖子读取每条 $0.005,用户资料每份 $0.010,每月还有 200 万条帖子读取的硬性上限。一次返回 20 条推文的搜索要花 $0.10 的帖子读取,想要作者资料再加 $0.20。认证走 OAuth 2.0。一个 1 万条推文、带用户数据的数据集,大约要 $150。

选项 C:第三方 API。 Sorsa 这类服务商通过简单的 REST 接口提供同样的公开 Twitter 数据,按请求计费。调用一次搜索接口最多返回 20 条推文,含完整作者资料,无论结果多少都只算一次请求。在 Pro 套餐($199/月,含 10 万次请求)上,同样这 1 万条推文的数据集约 $1。认证是请求头里的一个 API 密钥,没有 OAuth 流程,也不用等审批。

下面把采集成本并排列出来,每个选项都带真实数字:

方法认证实时数据1 万条推文成本(含作者数据)每月上限
静态数据集(Sentiment140)免费不适用
官方 X API(按量付费)OAuth 2.0约 $150200 万条帖子读取
Sorsa(Pro 套餐)API 密钥约 $1按套餐(10 万次请求)

如果只是学建模,静态数据集够用。但凡涉及当下的内容,按请求计费的 Twitter/X API 能同时省掉成本尖峰和 OAuth 搭建。两家服务商的完整数字在我们的 Twitter/X API 定价拆解里。如果你还在比较采集方式,用 Python 拉取 X 数据对下面这套基于 requests 的写法讲得更细。

用 Python 采集推文

先装 requests 库:

bash
pip install requests

下面这个函数采集匹配某个搜索查询的推文,并处理分页:

python
import requests
import time

def collect_tweets(query, api_key, max_tweets=500):
    """
    从 Sorsa /search-tweets 接口采集推文。
    返回一个列表,每项是带文本、元数据和作者信息的推文 dict。
    """
    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)  # 保持在速率限制之下

    return all_tweets[:max_tweets]


# 用法
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_textcreated_at、互动指标(likes_countretweet_countreply_countview_count),以及嵌在 user 下的完整作者资料。用户数据不需要额外调用。
  • next_cursor 字段驱动分页,返回 null 就说明到底了。
  • 每页 20 条推文,500 条推文需要 25 次请求,在 Pro 套餐上约 $0.05。

大规模采集时,可以并行跑几个查询(不同关键词、日期窗口或账号),之后按推文 ID 去重。


第 2 步:清洗和预处理推文 {#step-2-cleaning-and-preprocessing-tweets}

原始推文很乱。一条帖子可能同时混着提及、URL、话题标签、表情符号、俚语、拼写错误,还不止一种语言。直接喂进分类器会把准确率拖下来。

下面这个函数处理最常见的噪音:

python
import re

def clean_tweet(text):
    """为情感分析清洗一条推文。"""
    text = re.sub(r'@\w+', '', text)          # 移除 @提及
    text = re.sub(r'https?://\S+', '', text)  # 移除 URL
    text = re.sub(r'^RT\s+', '', text)        # 移除 RT 前缀
    text = text.replace('#', '')              # 保留词,去掉井号
    text = re.sub(r'\s+', ' ', text).strip()  # 折叠空白
    return text


for tweet in tweets:
    tweet['clean_text'] = clean_tweet(tweet['full_text'])

表情符号怎么处理?

表情符号带着很强的情感信号。一条写着 “new update 💀🤡” 的推文语气明显是负面的,剥掉表情符号这个信号就没了。有两种合理做法:

  1. 保留表情符号,用能读懂它们的分类器(VADER 和 RoBERTa 都可以)。
  2. 把表情符号转成文本,用 emoji 库(pip install emoji),把 😊 变成 :smiling_face_with_smiling_eyes:。这对不原生支持表情符号的词典类工具很有帮助。

对 RoBERTa 这类 transformer 模型,表情符号原样保留即可,模型在训练时已经学过它们的含义。

要不要做词干提取或词形还原?

很多教程把词干提取和词形还原当成必做步骤,其实不是。如果用 TF-IDF 特征加传统模型(朴素贝叶斯、SVM),词干提取能缩小词汇量,确实有帮助。但如果用预训练 transformer 或 VADER 这类词典工具,直接跳过:这些工具内部就处理词形,激进的词干提取反而毁掉信号。“Unhappy” 被词干提取成 “unhappi”,词典就匹配不上了。


第 3 步:选择情感分类方法 {#step-3-choosing-a-sentiment-classification-method}

这是整条管道里最重要的架构决策。大体有四种方法,在准确率、速度、成本和搭建难度上各有取舍。

方法 1:基于规则的词典(VADER、TextBlob)

这类工具自带一份按极性打分的词典,配上处理否定和强调的规则,输出一个复合分数。

VADER(Valence Aware Dictionary and sEntiment Reasoner)专为社交媒体设计,能处理表情符号、俚语、大写(“GREAT” 比 “great” 分更高)和程度副词(“very good” 对比 “good”),而且即开即用,不用加载模型,也不用 GPU。

TextBlob 用的是从产品评论里提炼的词典,返回极性(-1 到 +1)和主观性(0 到 1)。比 VADER 简单,针对社交文本的调优也少。

什么时候用: 快速做原型、对延迟敏感的实时打分,或者你需要看清哪些词决定了分数。在语义含糊的文本上偏弱。

方法 2:传统机器学习分类器(朴素贝叶斯、SVM、逻辑回归)

用 TF-IDF 特征在标注好的推文上训练分类器,这是 transformer 出现之前的标准做法。你需要一份标注训练集(一般选 Sentiment140),模型从中学习词与情感的关联。TF-IDF 加逻辑回归在 Sentiment140 上通常能到 80% 到 82% 的准确率,几分钟就能训完。完整走查见下面的训练一节

什么时候用: 你有领域特定的标注数据,又想要一个不依赖 GPU 就能跑的轻量模型。

方法 3:预训练 transformer(RoBERTa)

Hugging Face 上的 cardiffnlp/twitter-roberta-base-sentiment-latest 模型在 2018 到 2021 年约 1.24 亿条推文上训练,并在 TweetEval 基准上做了微调。它把文本分成负面、中性和正面三类,准确率明显高于词典法和经典机器学习方法。已发表的基准显示,基于 RoBERTa 的模型在 Twitter 情感任务上约为 88% 到 91%,VADER 和 TextBlob 约为 73% 到 75%。

什么时候用: 准确率比速度更重要。需要 transformers 库,批处理最好配 GPU,不过数据量小的话 CPU 推理也够。

方法 4:商业平台(Sprinklr、Brandwatch、Meltwater)

自带情感分析的企业级社媒聆听工具,把采集、分类和看板打包在一起,定价通常每月数千美元。

什么时候用: 需要看板和多语言支持、又不想自己开发的企业团队。对只想交付一条聚焦管道的开发者来说是杀鸡用牛刀,而且你会失去对预处理和模型选择的控制权。


第 4 步:在 Python 里做情感分类 {#step-4-running-sentiment-analysis-in-python}

下面三种基于代码的方法,都跑在第 1 步采集到的推文上。

方法 1:VADER

bash
pip install vaderSentiment
python
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 很快,在笔记本上约每秒 1 万条推文。复合分数从 -1(最负面)到 +1(最正面),正负 0.05 是原论文推荐的阈值。

方法 2:TextBlob

bash
pip install textblob
python
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 慢一倍,但仍然很快。有一点要注意:它的词典来自产品评论,所以碰到词汇表外的俚语时,容易把俚语密集的推文一律标成中性。

方法 3:预训练 RoBERTa Transformer

bash
pip install transformers torch scipy
python
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):
    """把 @提及 和 URL 替换成模型期望的占位符。"""
    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])


# 喂原始文本,不要喂清洗过的版本:RoBERTa 自己做预处理
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 条以上。超过 1 万条推文,就上 GPU 批处理。


在有标注数据上训练自己的分类器 {#training-your-own-classifier-on-labeled-data}

预训练模型能覆盖大多数需求。只有当你的领域语言和普通推文差得很远(金融、医疗、法律、非英语),并且手上有标注样本时,才值得自己训练。所有教程级的管道都是同一个套路,所以端到端看一遍很有价值:加载标注推文、用 TF-IDF 向量化、训练分类器、读指标。

bash
pip install pandas scikit-learn
python
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:列依次是 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')

# 映射标签:0 保持负面,4 变成正面
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)  # 复用第 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' 用来防止标签数量倾斜
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}

原始标签有用,但情感趋势才可行动。下面是怎么把分类好的推文变成利益相关方能据此决策的东西。

python
import pandas as pd

df = pd.DataFrame(tweets)
df['created_at'] = pd.to_datetime(df['created_at'])

# 分布
print(df['roberta_label'].value_counts(normalize=True))

# 情感随时间变化(按小时分桶)
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_countretweet_countview_count,和我们在 Twitter 互动 API 指南里讲的回复、引用、转发用户的互动字段是同一套:

python
df['weighted_sentiment'] = df['vader_score'] * df['view_count']
print(f"Weighted sentiment index: {df['weighted_sentiment'].sum():.2f}")

词云是查看某个情感类别由什么驱动的最快方式。按标签拆开看,就能知道负面背后到底是什么抱怨:

python
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}

下面是基于已发表基准和真实使用情况的横向对比。

VADERTextBlob逻辑回归(TF-IDF)RoBERTa(twitter-roberta-base)
Twitter 数据上的准确率约 73-75%约 71-73%约 80-82%约 88-91%
搭建时间2 分钟2 分钟30-60 分钟(需训练数据)10 分钟(预训练)
速度(CPU)约每秒 1 万条推文约每秒 5,000 条推文约每秒 8,000 条推文约每秒 5-15 条推文
是否需要 GPU超过 1,000 条推文建议用
表情符号处理是(原生支持)仅当训练数据里有是(在 1.24 亿条推文上训练)
讽刺处理一般更好,但仍有限
三分类(正/负/中性)需设阈值取决于标签是(原生支持)
自定义领域训练否(固定词典)否(固定词典)是(可微调)

准确率数字来自 TweetEval 数据集和 Sentiment140 上的基准。在你自己的数据上,实际表现会随领域、语言混合程度,以及含糊或讽刺文本的占比而变化。

实际操作中,我们先用 VADER 拉一条快速基线。准确率要紧时,就切到预训练 RoBERTa 模型。只有当领域语言确实让自训练模型打赢预训练模型时(医疗、法律、非英语),我们才自己训。


常见陷阱和边缘情况 {#common-pitfalls-and-edge-cases}

下面这些问题在舆情项目里反复出现。

讽刺检测

“Great, another app update that breaks everything I use daily.”(太好了,又一次把日常要用的东西全搞坏的应用更新。)所有词典和多数机器学习模型都会因为 “great” 把这句读成正面。Transformer 抓到讽刺的概率更高,但没有一个可靠。如果讽刺在你的领域里很常见(科技圈 Twitter、政治评论),就加一层讽刺检测,或者人工复查“高互动的正面”簇,爆款讽刺帖往往藏在那里。

机器人和垃圾内容污染

自动化账号会扭曲分布,一次有组织的活动能让某个话题看起来压倒性地正面或负面。按互动阈值过滤(搜索查询里加 min_faves:1),并检查跨账号是否存在重复或高度相似的文本。

转发偏差

一旦把转发算进来,一条被转发 5 万次的爆款负面推文就会主导整个数据集。-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 情绪当作另类数据信号。把情感分数与 cashtag 搜索($TSLA$BTC)以及互动加权结合起来,就能构建一个情绪指数。Sorsa Score 接口再加一层,给加密生态里的账号影响力打分,这样就能按“谁在发帖”给信号加权。

学术研究

研究选举、公共卫生危机或社会运动的研究者,需要大规模、按时间界定的数据集。用日期范围操作符(since:2026-01-01 until:2026-03-01)可以精确取到需要的切片。历史存档可回溯到 2006 年,且不收存档附加费。查询较旧帖子的完整做法,见我们的搜索历史 Twitter 数据

客户反馈分析

把情感和话题提取结合起来,就能查明客户到底对什么不满,而不只是知道他们不满。按关键词给负面推文聚类,再人工复查排在前面的几个簇。这一步在定量打分和定性洞察之间搭了座桥。

实战

我们合作过的一个约 12 人的市场研究团队,一直在官方 X API 上拉品牌提及,每个月不到月底就撞上 200 万条帖子读取上限。结果就是每次产品发布、最需要覆盖度的时候,采集反而被掐住。把采集层换成按请求计费的 Twitter/X API 之后,上限问题消失了,月度数据账单也大幅下降。按请求计费最多可比按资源计费便宜 50 倍,处在这个位置的团队,同样的量级通常能看到采集费用降低差不多的倍数。他们的分类器技术栈一点没动,变的只是推文的来源。


做成一个完整项目 {#building-this-as-a-complete-project}

上面五个阶段本身就构成一个作品集级别的项目,这也是 “twitter sentiment analysis” 成为热门毕业设计和研究选题的原因。想把它打包成一个连贯的项目,而不是一堆零散片段,可以这样做。先挑一个具体话题(某个产品、某种疫苗、某场选举、某支股票),用搜索接口采集几千条相关推文。然后过一遍清洗函数和你选定的分类器,最后用第 5 步的时间序列图和词云收尾。

想让报告可复现,记录三件事:确切的搜索查询和日期范围、分类器及其版本,以及你最终得到的标签分布。有这三样,任何人都能重跑你的分析,这也正是审阅者和评分者要找的东西。如果你还想要一个能部署的界面,把整条管道包进一个小的 Streamlit 或 Flask 应用,让非技术用户输入关键词就能看到情感分布。数据层通常是唯一卡住人的环节,而按请求计费的 X API 替代方案能让这一层对学生或研究预算来说既便宜又免审批。


常见问题 {#faq}

做 Twitter 情感分析需要哪些 Python 库?

采集方面,如果走 REST API,requests 就够了。分类方面常用三个库:vaderSentiment(基于规则,针对社交媒体调优)、textblob(基于规则,通用),以及 Hugging Face 的 transformers(提供 RoBERTa 这类预训练模型)。再加 pandas 做数据处理,matplotlibwordcloud 做可视化。一行装完:pip install requests vaderSentiment textblob transformers torch pandas matplotlib wordcloud

Twitter 情感分析有多准确?

准确率完全取决于方法。VADER 这类基于规则的工具,在标准 Twitter 基准上约为 73% 到 75%。传统机器学习分类器(TF-IDF 加逻辑回归或 SVM)约为 80% 到 82%。twitter-roberta-base-sentiment-latest 这类预训练 transformer 能到 88% 到 91%。没有哪种方法能可靠处理讽刺或强上下文依赖的内容,所以生产环境里要预留 10% 到 15% 的边缘情况做人工复查。

不用 Twitter 开发者账号,采集实时推文做情感分析最简单的办法是什么?

2026 年最简单的路线是用第三方 REST API。Sorsa API 通过请求头里的单个 API 密钥,从 /search-tweets 接口返回带完整作者资料的实时推文,没有 OAuth,也不用开发者账号审批。注册即送 100 次免费请求,无需绑卡,永不过期,所以在花钱之前就能采集并分类第一批数据。一次调用最多返回 20 条推文,只占一次请求,速率限制是统一的 20 次/秒;写代码之前还能先在免费的搜索生成器里把查询调好。

给推文做情感分析,VADER 和 TextBlob 哪个更好?

针对 Twitter,VADER 更好。它是为社交媒体文本设计的,能处理表情符号、俚语、大写强调和程度副词(“very good” 对比 “good”),这些恰恰是 TextBlob 那套基于评论的词典会漏掉的。在对比研究中,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,所以 1 万条带作者数据的推文约 $150。在 Sorsa 这类按请求计费的服务商上,同样这 1 万条推文在 $199 的 Pro 套餐上约 $1,因为一次搜索请求最多返回 20 条带资料的推文。这个差距在读密集型工作上最高可达 50 倍,也正是多数舆情分析管道一旦上量就离开按资源计费的原因。

Twitter 情感分析能检测讽刺吗?

用现有任何工具都不可靠。讽刺依赖上下文、文化背景,有时还依赖作者的历史发言,而单条推文的文本这些都提供不了。RoBERTa 这类 transformer 抓到明显讽刺的概率比词典工具高,但基准显示,即便最好的模型在专门的讽刺检测任务上也只有约 70% 到 75%。关键场景下,可以把标签与互动明显矛盾的推文标记出来复查,比如一条“正面”推文下面全是愤怒回复。

训练 Twitter 情感分类器最好的数据集是什么?

Sentiment140(160 万条标为正面或负面的推文)是使用最广的训练集,不过数据来自 2009 年,而且没有中性类。做三分类的话,Cardiff NLP 的 TweetEval 基准是当前标准,twitter-roberta-base-sentiment 模型就是在它上面微调的。做领域特定的工作,就自己标注:先用预训练模型标注一个大语料库,抽样审查,再在结果上微调。


如何开始 {#getting-started}

想在实时 Twitter 数据上搭一条舆情分析管道,最快的路径是这样:

  1. 拿一个 API 密钥,在 Sorsa 控制台。创建账号,领取 100 次免费请求(无需绑卡,永不过期),40 个接口全部包含在内,足够在花钱之前拉最多 1 万条推文或 2 万份用户资料。之后批量采集每 1,000 条推文 $0.02 起,付费套餐 $49/月起,含 1 万次请求,没有审批环节,几分钟就能配好。
  2. 先调查询,在免费的搜索生成器里测试搜索语法并预览结果,不用写代码。
  3. 复制本指南里的 Python 代码,直接开始采集和分类。从采集到可视化,100 行以内装得下。
  4. 看文档,在 docs.sorsa.io 查接口细节、分页,以及统一 20 次/秒的速率限制

需要批量接口或大规模采集的定制套餐,见关于 Sorsa联系销售


审校:Keksich(Sorsa 创始人,X API 研究者)

本文是怎么写成的:内容取材于我们亲手开发并运营 Twitter/X API 替代方案的经验,以及在我们自己采集的实时数据上跑上面这些分类器的结果。技术细节对照 Sorsa API 文档cardiffnlp/twitter-roberta-base-sentiment-latest 的 Hugging Face 模型卡核验过,准确率数字可追溯到 TweetEval 基准;官方 X API 价格和 200 万条帖子读取上限,在更新本文时对照当前公开定价重新核对。四种分类方法我们做过端到端对比。最后核验于 2026 年 7 月 8 日。