打开一份包含 300 条原始帖子 的表格,你会很快发现问题:复制、粘贴、阅读、眯眼、猜测、重复——最后你可能还是不知道自己追踪的新品发布到底是被喜欢还是被讨厌。
情绪分析之所以存在,就是为了解决这种问题。但现实是:网上大多数相关教程都还停留在 2022 年。它们默认你还能免费使用 API,推荐的模型却连讽刺和表情符号都处理不好,还会跳过那些真正决定结果是否靠谱的预处理步骤。我在 SaaS 和自动化领域投入了很多时间(也包括打造 Thunderbit),亲眼看着情绪分析的格局发生了巨大变化。真正诚实、而且更新后的做法,应该同时覆盖 Python 和无代码工作流,并采用符合 2026 现实的数据采集方式与模型。
什么是 Twitter 情绪分析?
Twitter 情绪分析,指的是根据帖子的文字、表情符号和上下文,自动判断 X 上的内容是正面、负面还是中性。你可以把它理解成:教机器读懂一条推文,并回答“这个人是在开心、沮丧,还是介于两者之间?”
不过,情绪分析和广义的社交聆听并不一样。社交聆听关注的是人们在讨论什么——话题、趋势、讨论量;而情绪分析是在此基础上的评分和分类层,它告诉你人们对自己说的话感受如何。这个概念可以追溯到几十年前的计算语言学和观点挖掘研究,但真正成为主流商业工具,也就是最近几年才发生的事。
常见的分类层级有:
- 二分类: 正面或负面(最简单,但会损失细节)
- 三分类: 正面、中性或负面(最常见的默认方式)
- 细粒度分类: 从“非常正面”到“非常负面”(适合研究和更精细的品牌追踪)
此外,还有一些相关但不同的任务,比如情绪识别(愤怒、悲伤、开心)、立场检测(支持还是反对某个观点)、方面级情绪分析(一个人对价格和质量分别怎么看),以及讽刺/反讽识别。TweetEval 基准 就把这些当作不同任务来处理,这很合理,因为单一的情绪分数无法回答所有商业问题。如果你在追踪产品发布,通常更需要方面级情绪分析(“喜欢相机,讨厌电池”);如果你在监测危机,更需要的是情绪和讨论量,而不只是正负极性。
为什么 Twitter 情绪分析对企业很重要
X 的设计就是围绕实时对话展开的,因此新品发布、直播事件和突发新闻的反应会迅速累积。对企业来说,这种速度正是价值所在。情绪分析能把一大堆非结构化文本,转化成团队可以查看和采取行动的结构化数据。
最常见的使用场景可以总结为:
| 使用场景 | 团队 | 商业结果 |
|---|---|---|
| 品牌声誉监测 | 公关、市场 | 在负面舆情爆发前发现异常波动 |
| 产品发布反馈 | 产品、市场 | 实时看出哪些有效,哪些无效 |
| 竞品对标 | 战略、市场 | 在相同时间窗口内比较品牌认知差异 |
| 危机检测 | 公关、运营 | 当负面讨论量激增时触发人工复核 |
| 活动表现评估 | 市场 | 按创意、渠道或时间衡量情绪变化 |
| 市场/股价情绪 | 金融、研究 | 追踪财报、事件或政策周围的公众情绪 |
| 政治与政策研究 | 研究、政府 | 大规模衡量公众对议题的态度 |
举个具体例子:X 的 2026 年超级碗回顾 显示,单一事件就带来了 1600 万条帖子、400 万作者、50 亿次展示和 6.05 亿次视频观看,其中一半讨论发生在实时阶段。这样的规模,人工阅读根本不可能完成,自动化情绪评分就变得不可或缺。
而且,它不只是“量大”而已。X 自家的 BrandRanx 方法论 会把讨论量、互动量和情绪一起考虑,这也说明:情绪分析最强的地方,在于和其他信号搭配使用,而不是单独看。
一句话总结:如果你的团队需要基于公众感知做决策——无论是产品、品牌、活动还是危机——那对 X 数据做情绪分析,都是最快的反馈回路之一。
2026 年 X API 的现实:到底该怎么拿到推文数据
这里就是大多数教程翻车的地方。如果你曾照着 Tweepy 教程写代码,结果碰到付费墙或莫名其妙的错误,那你并不孤单。过去的 Free / Basic / Pro 套餐已经取消了。现在 X API 采用的是按使用量计费并预充值,按端点收费,还能实时追踪用量。
下面是对当前所有数据采集方式的诚实对比:
| 方法 | 成本(2026) | 数据量 | 技能要求 | 说明 |
|---|---|---|---|---|
| X API v2(按量付费) | 每条 Post 读取 $0.005 | 自助方案每月最高 200 万次 Post 读取 | 中级(Python) | 官方、可复现、合规 |
| 全量归档搜索 | 每条返回 Post $0.005;每次全量归档计数请求 $0.010 | 可追溯到 2006 年 3 月 | 中级–高级 | 按量付费和企业方案可用 |
| 过滤流(Filtered Stream) | 按投递读取计费 | 实时、持续 | 中级–高级 | 最适合实时采集 |
| 预制数据集(Kaggle、Sentiment140) | $0 | 仅静态历史数据 | 初学者 | 适合学习,不适合实时分析 |
| snscrape、Twint、Twikit 等 | $0 | 不稳定 / 经常失效 | 高级 | snscrape 自 2023 年起就无法用于 X 搜索;Twint 已归档;Twikit 使用非官方方法 |
| 你自己的 X 归档 | $0 | 仅限你自己的帖子 | 初学者 | 适合个人分析 |
有几件事一定要知道:
- 旧的 Free / Basic / Pro 套餐已经没了。 别再照着把它们当成现行方案的教程去做。
- snscrape 对 X 已经失效。 维护者在 2024 年确认,Twitter 搜索抓取已经不能用了。Twint 也已归档。Twikit 使用的是非官方抓取和 cookies——“能访问”不等于“被允许”。
- X 的服务条款禁止在未获事先书面同意的情况下进行浏览器抓取。 这意味着 Selenium、Playwright 和浏览器插件都不能作为合规的 API 替代方案。
X API v2:你到底能得到什么
标准的 Post 读取费用是每条返回 Post $0.005。用户读取则是每次 $0.010。也就是说,10,000 次独立 Post 读取大约要花 $50,还没算其他资源成本。自助方案上限是每月 200 万次 Post 读取。费率可能会变化——务必以 Developer Console 为准。
做情绪分析时,你需要的不只是 id 和 text。一个实用的最小字段集包括:created_at、lang、author_id、conversation_id、referenced_tweets、entities、context_annotations 和 public_metrics。同时保存原始响应,以及你的查询、端点、UTC 时间窗口和分页 token 的不可变记录。没有这些,语料就无法复现。
还有一个额外变化:X 在 2026 年 5 月 4 日的搜索索引迁移 改变了可观察到的语料。关键词 REST 搜索不再返回转帖,而 Filtered Stream 不受影响。如果你在比较迁移前后的结果,统计的可能已经不是同一批样本了。
预制数据集:适合学习,不适合实时分析
Sentiment140(160 万条推文、远程监督标注)和各类 Kaggle 数据集都是免费的,适合教学和基准测试。但 Sentiment140 采集于 2009 年。TweetEval 的情绪子集使用的是 2013–2016 年的 SemEval 数据。它们都无法证明你的模型对 2026 年的语言、俚语或事件同样有效。
关于 Thunderbit 和 X 数据的说明
这里我想坦白一点,因为我们做了 Thunderbit:Thunderbit 是一个 AI 网页爬虫和自动化工具,可以用于很多兼容的网站。但 X 目前的条款禁止在未获同意的情况下进行浏览器抓取。所以我不会把 Thunderbit 描述成绕开 X API 成本或访问限制的办法——那样会误导你。对于 X 数据,应该使用官方 API、获授权的数据提供方,或者你自己的账号归档。Thunderbit 真正适合的,是在后续环节中帮你把已经通过合规途径采集到的数据进行结构化、标注和导出。后面我会继续展开。
如何选择合适的情绪模型:VADER、TextBlob 还是 RoBERTa

你选择的模型,比大多数教程说得更重要。而竞品指南里最大的缺口之一,就是几乎没人讲针对推文微调过的 transformer 模型——而这正是如今很多强力基线所在。
下面先做个直接对比。这里我刻意没有放统一的 F1 数值,因为不同数据集、划分方式、标签定义、时间段和评价指标都会影响分数。相反,我会说明相对表现,并告诉你去哪些基准里验证。
| 模型/库 | 方法 | 能处理讽刺吗? | 能处理俚语/表情符号吗? | 推文相对准确率 | 配置复杂度 |
|---|---|---|---|---|---|
| VADER(NLTK) | 规则词典法 | 较弱 | 部分支持表情符号 | 最低 | 很低 |
| TextBlob | 模式规则法 | 较弱 | 不支持 | 较低 | 很低 |
| 朴素贝叶斯 / 逻辑回归(TF-IDF) | 经典机器学习 | 不行 | 不行 | 中等 | 中等 |
| CardiffNLP RoBERTa | Transformer(针对推文微调) | 更好(但不完美) | 支持 | 这些里面最高 | 中等(HuggingFace pipeline) |
VADER:上手快,但能力有限
VADER 是一种面向社交文本的规则词典方法。它速度快、可解释、无需训练数据,还能处理部分表情符号和颜文字。它会考虑否定词、程度副词、标点和大小写。对于快速做个粗略基线,或者你很看重计算成本和可解释性时,VADER 很有用。但它的短板也很明显:讽刺、俚语、依赖上下文的含义,以及任何超出单词本身的理解,它都不擅长。它默认的复合分数阈值(≥0.05 为正面,≤-0.05 为负面)只是默认值,不是通用业务阈值——最好在自己的验证集上重新调。
TextBlob:更简单,也更受限
TextBlob 是一个很小的教学型基线。它默认的 PatternAnalyzer 并不是为推文风格文本训练的。适合你第一次做 NLP 小实验,但不适合生产环境中的推文分析。
经典机器学习:朴素贝叶斯、逻辑回归、SVM
基于单词和字符的 TF-IDF 流程,再配合 逻辑回归 或 LinearSVC,仍然是一个很有价值的监督式基线。它便宜、可解释,而且常常能帮助你判断 transformer 到底值不值得承担更高复杂度。关键规则是:一定要在划分训练集/验证集之后,再去拟合向量器,避免词汇表和 IDF 信息泄漏。
这类模型在大规模标注数据集上通常会优于规则法,但它们仍然很容易错过上下文、讽刺和俚语。
CardiffNLP RoBERTa:2026 年推文情绪分析的标准选择
cardiffnlp/twitter-roberta-base-sentiment-latest 是一个持续维护、专为推文设计的三分类模型,也是 2026 年一个非常合理的强基线。它在大规模推文语料上预训练,并针对情绪分析做了微调,因此比规则法或经典机器学习方法更能处理表情符号、俚语和非正式表达。
下面是一个最小化的 HuggingFace 调用示例:
from transformers import pipeline
classifier = pipeline(
"text-classification",
model="cardiffnlp/twitter-roberta-base-sentiment-latest",
top_k=None,
)
scores = classifier("@user Love waiting three hours for support 😒 http")
print(scores)
需要注意几点:
- 输出的是模型分数,不是经过校准的业务概率。最好在当前标注样本上做校准,或者设置一个拒判阈值。
- 上下文模型通常会比规则系统在很多推文任务上表现更好,但讽刺、混合对象、缺失的线程上下文、方言和隐晦表达,仍然是结构性错误来源。不要承诺任何模型“真正懂讽刺”——更准确的说法是:它能更好地处理,但并不完美。
- 其他可选方案还包括 BERTweet、TimeLMs,以及多语言 Twitter-XLM-R 模型,具体取决于语言和任务。
所以,Twitter 情绪分析真的能做到准确吗?答案是可以——前提是模型、预处理、标签定义和评估样本都要和任务匹配。把 2019 年教程里复制来的 VADER 脚本直接跑一遍,只能算基线,不能证明它适合生产环境。
一个真正像样的推文预处理流程(不只是 text.lower())

如果你把原始 URL、@提及和 HTML 实体直接喂给情绪模型,就算是还不错的模型也可能输出一堆垃圾。很多教程(包括排名靠前的那些)在送入模型前只做了小写化处理。这个做法会悄悄拖垮准确率——尤其是对经典机器学习而言,预处理质量的重要性有时和模型选择一样高。
该清理什么,以及为什么重要
| 元素 | 该怎么处理 | 原因 |
|---|---|---|
| URL | 替换成类似 http 的占位符 | URL 本身对情绪判断没帮助;但把周围文本一起删掉会破坏上下文 |
| @提及 | 把账号统一替换成 @user | 保留结构,避免作者身份泄漏 |
| 表情符号/颜文字 | 对现代 tokenizer 保留;对稀疏模型可测试转文本版本 | 表情符号携带强烈情绪信号,删掉等于丢数据 |
| Hashtag | 保留该 token;也可以额外加一个拆分版本(例如 #ClimateChangeIsReal → Climate Change Is Real) | Hashtag 往往直接包含观点 |
| 否定词 | 保留 not、no、never、缩写和转折词 | 常见停用词表会把这些删掉,导致情绪方向翻转 |
| 大小写/标点 | 对 VADER 及兼容模型保留 | VADER 会把大小写和标点当作特征 |
| RT 前缀 | 删除 RT 标记 | 这是元数据,不是情绪 |
| 转帖/重复内容 | 在划分数据前识别完全重复和近似重复 | 训练集和测试集重复会造成泄漏 |
预处理前后:一条推文到底发生了什么变化
下面是一个具体例子:
| 阶段 | 文本 |
|---|---|
| 原始推文 | RT @BrandX: Wow, #CustomerServiceFail 😡😡 https://t.co/abc123 I've been waiting 3 hrs ngl this is awful |
| 去除 URL 后 | RT @BrandX: Wow, #CustomerServiceFail 😡😡 http I've been waiting 3 hrs ngl this is awful |
| 归一化提及后 | RT @user: Wow, #CustomerServiceFail 😡😡 http I've been waiting 3 hrs ngl this is awful |
| 去除 RT 后 | @user: Wow, #CustomerServiceFail 😡😡 http I've been waiting 3 hrs ngl this is awful |
| 拆分 hashtag 后 | @user: Wow, #CustomerServiceFail Customer Service Fail 😡😡 http I've been waiting 3 hrs ngl this is awful |
| 表情转文本后(用于稀疏模型) | @user: Wow, #CustomerServiceFail Customer Service Fail angry_face angry_face http I've been waiting 3 hrs ngl this is awful |
| 最终版(用于 CardiffNLP RoBERTa) | @user Wow, #CustomerServiceFail Customer Service Fail 😡😡 http I've been waiting 3 hrs ngl this is awful |
注意:对于 CardiffNLP RoBERTa 这类 transformer,应该保留表情、标点和大小写——因为它训练时看到的文本就长这样。对于 TF-IDF 模型,则可能需要转表情为文本、小写化、词形还原等处理。
可直接复制的 Python 预处理代码
下面是一个干净、模块化的函数,适用于 transformer:
import html
import re
import unicodedata
URL_RE = re.compile(r"https?://\S+|www\.\S+", re.I)
MENTION_RE = re.compile(r"(?<!\w)@[A-Za-z0-9_]+")
def normalize_social_text(text: str) -> str:
"""将推文文本规范化为适合 transformer 情绪模型的格式。"""
text = html.unescape(text)
text = unicodedata.normalize("NFC", text)
text = URL_RE.sub("http", text)
text = MENTION_RE.sub("@user", text)
text = re.sub(r"\bRT\b", "", text)
return " ".join(text.split())
如果是经典机器学习流程,你还可以继续加上小写化、表情转文本(用 emoji 或 demoji 库)、hashtag 拆分(用 wordninja 或 ekphrasis)、俚语标准化、停用词移除,以及词形还原(通过 spaCy 或 NLTK)。核心原则只有一个:预处理要和模型匹配。 例如 BERTweet 就有自己文档化的规范化约定,不要把所有模型都硬塞进同一条流水线。
Python 实战:一步步做 Twitter 情绪分析
下面是完整工作流,把前面的内容串起来。你可以从头到尾直接照着做。
开始前:
- 难度: 中级(默认你会一点 Python)
- 耗时: 完整流程约 30–60 分钟;快速 transformer 路径约 10 分钟
- 你需要: Python 3.8+、免费的 Google Colab 或本地环境、
pandas、transformers、scikit-learn、matplotlib、seaborn,以及可选的wordcloud
第 1 步:收集你的推文数据
本教程我使用 Sentiment140 数据集(免费,160 万条推文,可在 Kaggle 找到)。它很适合学习和基准测试,尽管它是历史数据。
如果你想用实时数据,请使用 X API v2 的按量付费层级。标准的 Post 读取费用是每条 $0.005。如果有 10,000 条 Post,大约需要 $50。
加载数据集:
import pandas as pd
columns = ["target", "id", "date", "flag", "user", "text"]
df = pd.read_csv(
"training.1600000.processed.noemoticon.csv",
encoding="latin-1",
names=columns,
)
# 标签:Sentiment140 中 0 = negative,4 = positive
df["label"] = df["target"].map({0: "negative", 4: "positive"})
print(df[["text", "label"]].head())
你应该会看到一个包含原始推文文本和标签列的 DataFrame。
第 2 步:清洗并预处理你的推文
应用前面提到的预处理函数:
df["clean_text"] = df["text"].apply(normalize_social_text)
print(df[["text", "clean_text"]].head())
检查几行数据,确认 URL 已替换、提及已标准化、RT 前缀已移除。
第 3 步:选择模型并分类情绪
路径 A:TF-IDF + 逻辑回归的经典机器学习
这是“先理解基础原理”的路径。先拆分数据,只在训练集上拟合向量器,然后训练逻辑回归分类器:
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
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=50000, ngram_range=(1, 2))
X_train_tfidf = vectorizer.fit_transform(X_train)
X_test_tfidf = vectorizer.transform(X_test)
clf = LogisticRegression(max_iter=1000)
clf.fit(X_train_tfidf, y_train)
y_pred = clf.predict(X_test_tfidf)
print(classification_report(y_test, y_pred))
你应该会看到一份分类报告,包含每个类别的 precision、recall 和 F1。在 Sentiment140 上,TF-IDF + 逻辑回归通常表现还不错——但要记住,这个数据集来自 2009 年,而且是远程监督标注(用颜文字当标签),所以不要把这些数值当成你的生产环境基准。
路径 B:通过 HuggingFace 使用 CardiffNLP RoBERTa
如果你想在推文文本上尽量拿到更好的准确率,建议使用这个预训练 transformer:
from transformers import pipeline
classifier = pipeline(
"text-classification",
model="cardiffnlp/twitter-roberta-base-sentiment-latest",
top_k=None,
)
sample_tweets = [
"@user Love waiting three hours for support 😒 http",
"@user This new update is absolutely fantastic, best one yet!",
"@user The event was okay, nothing special.",
]
for tweet in sample_tweets:
result = classifier(tweet)
print(f"Tweet: {tweet}\nScores: {result}\n")
你会看到每条推文对应的标签分数列表(negative、neutral、positive)。那条带讽刺意味的推文(“Love waiting three hours...”)应该会比规则模型更偏负面——不过没有任何模型能在这里做到完美。
第 4 步:评估结果
接下来,为经典机器学习路径生成一个混淆矩阵热力图:
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred, labels=["negative", "positive"])
sns.heatmap(cm, annot=True, fmt="d", xticklabels=["negative", "positive"],
yticklabels=["negative", "positive"], cmap="Blues")
plt.xlabel("Predicted")
plt.ylabel("Actual")
plt.title("Confusion Matrix: Logistic Regression on Sentiment140")
plt.show()
如果走 transformer 路径,建议手工标注一小批当前样本(50–100 条推文),再运行模型并比较结果。报告 macro F1、每类的 precision 和 recall,以及混淆矩阵。如果这是一个真实项目,还要检查校准情况,并为模糊案例设置拒判阈值。
第 5 步:测试边缘案例
试几条能检验讽刺、表情和俚语的推文:
edge_cases = [
"Oh great, another update that breaks everything 🙄",
"ngl this product slaps 🔥🔥🔥",
"The camera is amazing but the battery life is trash",
"Just got my order. It's... fine. I guess.",
]
for tweet in edge_cases:
clean = normalize_social_text(tweet)
result = classifier(clean)
print(f"Tweet: {tweet}\nScores: {result}\n")
看看模型哪里做对了,哪里仍然吃力。“相机很棒但电池很差”这种混合对象的推文,本来就是已知难点——方面级情绪分析是另一个单独任务。
不写代码也能做 Twitter 情绪分析
不是每个人都想写 Python,这完全没问题。如果你是市场人员、品牌经理或运营负责人,只想在不碰代码的前提下获取情绪洞察,也有办法。
先说明一个现实:无代码工具的代价是牺牲一部分定制能力来换速度。它们很适合快速做品牌监测,但不适合研究级分析或自定义模型训练。
无代码方案速览
| 工具 | 最适合 | 自带情绪分析吗? | 价格区间 |
|---|---|---|---|
| AWS Comprehend | 企业级文本分析 | 是 | 按量付费 |
| Brandwatch / Sprinklr | 全套社交聆听平台 | 是 | 企业定价 |
| Google Sheets + NLP 插件 | 快速轻量分析 | 通过插件实现 | 免费–低价 |
| Thunderbit + 表格 | 对兼容页面的数据结构化和标注 | 可用 AI Field Prompt 做探索性标签 | 有免费套餐 |
无代码流程:采集数据,在表格里分类
下面是一个适合已经拿到推文数据的人使用的实用流程(数据来源可以是官方 X API、获授权的数据提供方,或者自己的归档):
- 把推文数据导出到表格。 如果你用的是 X API,可以把 JSON 导出为 CSV;也可以使用像 Thunderbit 这样的工具,在你有权限自动化的兼容页面上做结构化和导出。
- 打开 Google Sheets。 把推文文本复制或导入到某一列中。
- 应用情绪分类器。 使用 Google Sheets 的 NLP 插件(请到插件市场查看最新可用选项),或者用 AWS Comprehend 之类的服务。有些插件可以直接在单元格公式里做情绪分类。
- 查看并可视化。 利用 Google Sheets 自带图表功能,做情绪分布柱状图或按时间变化的折线图。
Thunderbit 的 AI Field Prompt 也可以在抓取时,为兼容页面增加基于提示词的情绪标签——这对探索性监测很有用。但如果是需要审计或风险较高的决策,仍然应该先抽样验证,并使用有文档记录的模型。
什么时候用无代码,什么时候用 Python
| 场景 | 推荐路径 |
|---|---|
| 快速品牌检查、小数据量 | 无代码(表格 + 插件) |
| 团队仪表盘、每周报告 | 无代码或低代码 |
| 大规模分析、自定义模型 | Python |
| 学术研究、要求可复现 | Python |
| 大规模实时监测 | Python + API + 定时流水线 |
如何可视化 Twitter 情绪分析结果

大多数教程做到分类报告就停了。但如果你想向团队传达结论,或者据此做决策,就需要图表。
情绪分布柱状图
这是最基础、但几乎人人都用得上的输出:
import matplotlib.pyplot as plt
import seaborn as sns
sentiment_counts = df["label"].value_counts()
sns.barplot(x=sentiment_counts.index, y=sentiment_counts.values, palette="coolwarm")
plt.xlabel("Sentiment")
plt.ylabel("Tweet Count")
plt.title("Sentiment Distribution")
plt.show()
按情绪类别生成词云
分别为正面和负面推文生成词云,可以看出人们到底在说什么:
from wordcloud import WordCloud
for sentiment in ["positive", "negative"]:
text = " ".join(df[df["label"] == sentiment]["clean_text"])
wc = WordCloud(width=800, height=400, background_color="white").generate(text)
plt.figure(figsize=(10, 5))
plt.imshow(wc, interpolation="bilinear")
plt.axis("off")
plt.title(f"Word Cloud: {sentiment.capitalize()} Tweets")
plt.show()
随时间变化的情绪:别人通常不会给你看的图
这才是把原始数据变成故事的图表。如果你有时间戳,就能追踪某个事件、发布或危机期间情绪如何变化:
df["date"] = pd.to_datetime(df["date"])
df["day"] = df["date"].dt.date
sentiment_map = {"positive": 1, "neutral": 0, "negative": -1}
df["score"] = df["label"].map(sentiment_map)
daily = df.groupby("day")["score"].mean()
plt.figure(figsize=(12, 5))
daily.plot()
plt.xlabel("Date")
plt.ylabel("Average Sentiment Score")
plt.title("Sentiment Over Time")
plt.axhline(0, color="gray", linestyle="--")
plt.show()
如果发布当天突然下滑?那就是你该深入查看负面推文,找出问题所在的信号。
混淆矩阵热力图
前面的评估步骤已经展示过了。关键是:找出模型把正面误判成负面(或反过来)的地方。那些推文最值得人工阅读。
给非程序员:在 Google Sheets 或 Notion 里做图表
如果你已经把带情绪标签的数据导出到表格里,就可以直接在 Google Sheets、Notion 或任何 BI 工具里做情绪分布和趋势图,不需要 Python。
Twitter 情绪分析中的常见坑,以及如何避开
在真实世界的情绪工作流里,同样的错误总是在重复出现。
讽刺和反讽
这是准确率杀手中的头号选手。“Love waiting three hours for support 😒” 对规则模型来说看上去甚至像正面。Transformer 模型表现更好,但讽刺本身结构上就很难——尤其是帖子本身缺少上下文(线程、作者历史、事件背景)时。对于高风险场景,最好把模型输出和人工抽查结合起来。
表情和俚语的盲区
如果你的预处理是直接删除表情,而不是把它们转成文本(适合稀疏模型)或保留下来(适合 transformer),那你其实是在扔掉数据里最强的情绪信号。俚语也是一样——“ngl this slaps” 明明是正面,但没在正式英语语料上训练过的模型可能根本不知道。
过时的 API 教程和失效的爬虫
如果某个教程还在用 Tweepy 的 API v1.1,那它已经过时了。如果它推荐 snscrape,说明它也不靠谱,因为自 2023 年起就无法用于 X 搜索。跟教程之前,务必检查发布日期和 API 版本。
对单一数据集过拟合
Sentiment140 很适合训练,但它来自 2009 年。2024 年 EMNLP 对 20 个社交媒体数据集的审计发现,去重后有 19 个测试数据集中的 14 个 F1 降低,而且在 19 个数据集中的 17 个里模型排名发生了变化。应该使用按时间划分、事件互斥,最好还能按作者互斥的切分方式。一定要用近期推文测试模型是否真的能泛化。
把情绪分数当真值
模型分数不是经过校准的概率。不要只凭一个情绪标签就自动触发响应,或者直接做面向公众的决定。凡是会影响个人或涉及危机响应的决策,都必须有人复核。
隐私、平台政策与负责任使用
这一部分不是可选项。
X 的 Developer Policy 强调隐私、用户控制、内容删除,以及对站外匹配的限制。实践上应遵守以下规则:
- 只收集必要字段。
- 结果应聚合后再发布,不要公开原始账号句柄。
- 保留 Post ID 和抓取时间戳,以满足合规要求。
- 当内容被删除、保护状态变更或收到合格请求时,删除或更新已存储内容。
- 不要推断个人的敏感属性。
- 不要在没有许可和合法依据的情况下,把情绪分数与 CRM 身份数据关联。
- 除非 restricted-use rules 允许,否则不要基于 X Content 训练或微调基础模型。
- 记录样本量、查询词、时间窗口、语言过滤条件和排除项。
- 绝不要仅凭情绪分数自动发布公开回复。
情绪分析是一种强大的工具,但也伴随着真实的责任。请务必认真对待。
结论与要点总结
到了 2026 年,Twitter 情绪分析依然可行——但前提是你要把方法升级到符合当前现实。旧套路(免费 API、只做小写化、VADER 或朴素贝叶斯、不做评估)已经不行了。真正有效的是:
- 通过合规途径获取数据。 使用 X API v2(按量付费)、获授权的数据提供方,或者透明的数据集。不要依赖失效的爬虫或浏览器绕过方案。
- 预处理要服务模型,而不是只做个样子。 对 transformer 保留表情、否定词和大小写;规范化 URL 和提及;让流程与模型训练数据保持一致。
- 把便宜基线和推文专用 transformer 做对比。 TF-IDF + 逻辑回归依然是很好的 sanity check。CardiffNLP RoBERTa 仍是当前推文情绪分析的强默认方案。
- 诚实评估。 报告 macro F1、各类别指标和混淆矩阵。使用当前的人工标注样本。为模糊案例设置拒判阈值。
- 可视化是为了决策,不只是为了好看。 随时间变化的情绪图和词云,能讲出分类报告讲不出来的故事。
- 始终保留人工介入。 没有任何模型能完美处理讽刺、混合对象或依赖上下文的含义。高风险场景下,一定要把模型输出和人工复核结合起来。
如果你刚开始入门,可以先找一个免费数据集,打开 Google Colab,跑一遍 HuggingFace pipeline。你能在 10 分钟内得到可用的情绪分数。如果你想在工作流的其他部分无代码地采集和结构化网页数据,前提是你有自动化权限, Thunderbit 可以在兼容页面上提供帮助。
如果你是为了作品集或面试而做这个项目:加入 transformer 对比、真实的预处理流程,以及一张随时间变化的情绪图,能立刻让你的项目从训练营模板里脱颖而出。
了解更多
- 如何使用 Thunderbit 掌握自动化数据抓取
- 2026 年 6 款最佳 Twitter(x.com)爬虫
- 如何用 Python 抓取 Twitter 推文(2025 版)
- 如何利用 Twitter AI 抓取提升数据洞察
- Twitter(X)统计数据 2026:用户、人口结构与广告
常见问题
Twitter 情绪分析准确吗?
这取决于模型以及你的评估方式。像 VADER 这样的规则工具,在推文数据上的表现通常偏低。像 CardiffNLP RoBERTa 这样的 transformer 模型会好得多——但具体分数仍会因数据集、划分方式、标签定义和指标而不同。预处理质量也很关键。不要只相信一个基准分数,一定要在当前人工标注样本上评估。
我能免费做 Twitter 情绪分析吗?
可以。你可以使用免费的数据集(Kaggle 上的 Sentiment140)、免费的 Python 环境(Google Colab)以及预训练的 HuggingFace 模型。对于实时数据,X API 按每条 Post 读取 $0.005 收费,所以小规模采集其实负担不大。Thunderbit 也为兼容页面上的数据结构化提供免费套餐。
做 Twitter 情绪分析,最好的 Python 库是什么?
如果是快速原型:用 NLTK 里的 VADER。若要在推文上追求更高准确率:用 HuggingFace 的 transformers 库配合 CardiffNLP 的 RoBERTa 模型。若要做经典机器学习基线:用 scikit-learn 加 TF-IDF。具体选哪个,要看你的数据量、准确率要求和算力预算。
做 Twitter 情绪分析时,怎么处理讽刺?
Transformer 模型比规则法或经典机器学习更能处理讽刺,因为它们会理解上下文,而不只是单个词。但没有任何模型能完美识别讽刺——研究 表明,即使是人工标注者,对讽刺意图也常常意见不一。对于关键场景,建议把模型输出和人工复核结合起来,并考虑使用专门的讽刺数据集来评估。
不写代码也能分析 Twitter 情绪吗?
可以。先通过允许的途径(X API、获授权的数据提供方或你的个人归档)拿到数据,导入 Google Sheets,然后通过 Sheets 的 NLP 插件或 AWS Comprehend 这类服务使用无代码情绪分类器。Thunderbit 也可以在兼容页面的数据结构化过程中,基于提示词添加情绪标签。想了解更多无代码数据工作流,可以看看我们关于 Google Sheets AI 工具 的指南。


