打開一份包含 300 則原始貼文的試算表,問題很快就會浮現:複製、貼上、閱讀、瞇著眼辨認、猜測、重來——到最後,你還是不一定知道自己追蹤的這次發布,到底是讓大家喜歡,還是惹人反感。
這就是情緒分析存在的原因。不過,問題在於:大多數相關教學都還停留在 2022 年。它們假設你還能免費用 API、推薦那些一碰到反諷和表情符號就卡住的模型,還直接跳過真正決定結果有沒有意義的前處理步驟。我在 SaaS 與自動化領域投入了很多時間(也包括打造 Thunderbit),親眼看著情緒分析的版圖大幅改變。真正誠實、也符合最新情況的做法,必須同時涵蓋 Python 與無程式碼流程,並採用符合 2026 現實的資料蒐集方式與模型。
什麼是 Twitter 情緒分析?
Twitter 情緒分析,是指根據 X 上貼文的文字、表情符號與上下文,自動判斷其屬於正面、負面或中性。你可以把它想成教機器讀懂一則推文,然後回答:「這個人現在是開心、不開心,還是介於兩者之間?」
不過,情緒分析和一般的社群聆聽還是不一樣。社群聆聽重點在於追蹤大家在談什麼——主題、趨勢、聲量;情緒分析則是在此之上的評分與分類層,告訴你大家對所談內容的感受如何。這個概念可以追溯到數十年前的計算語言學與意見探勘研究,但直到近幾年,才真的變成主流商業工具。
常見的分類層級包括:
- 二元分類: 正面或負面(最簡單,但資訊最少)
- 三元分類: 正面、中性或負面(最常見的預設選項)
- 細緻分級: 從非常正面到非常負面(適合研究與深入的品牌追蹤)
另外,也有一些相關但不同的任務,例如情緒偵測(憤怒、悲傷、喜悅)、立場偵測(支持或反對某個主張)、層面級情緒分析(例如某人對「價格」和對「品質」的感受各不相同),以及反諷/戲謔偵測。TweetEval 基準 就把這些視為不同任務,這很合理:單一的情緒分數不可能回答所有商業問題。如果你在追蹤產品上市,通常會希望看層面級情緒(例如「喜歡相機,但討厭電池」);如果你在監控危機,情緒類型與聲量比單純正負更重要。
為什麼 Twitter 情緒分析對你的業務很重要
X 本身就是圍繞即時對話而設計,所以新品發布、直播活動與突發新聞的反應會很快累積。對企業來說,速度就是價值所在。情緒分析能把大量非結構化文字,轉成團隊可以直接檢視、也能採取行動的結構化資料。
常見應用大致如下:
| 應用場景 | 團隊 | 商業成效 |
|---|---|---|
| 品牌聲譽監控 | 公關、行銷 | 在負面聲量爆發前先發現 |
| 產品上市回饋 | 產品、行銷 | 即時掌握哪些有效、哪些無效 |
| 競品基準比較 | 策略、行銷 | 在相同時間窗口內比較品牌觀感與競品差異 |
| 危機偵測 | 公關、營運 | 當負面聲量暴增時觸發人工審查 |
| 活動成效評估 | 行銷 | 依創意、渠道或時間衡量情緒變化 |
| 市場/股市情緒 | 財務、研究 | 追蹤財報、事件或政策周邊的民眾情緒 |
| 政治與政策研究 | 研究、政府 | 大規模掌握民意走向 |
更具體來說,X 的 2026 超級盃回顧 顯示,單一活動就產生了 1,600 萬則 Posts、來自 400 萬位作者、50 億次曝光,以及 6.05 億次影片觀看,其中一半對話發生在即時時段。這種規模下,人工閱讀根本不可能,必須靠自動化情緒評分。
而且重點不只是量而已。X 自家的 BrandRanx 方法論 結合了聲量、互動與情緒,也再次證明:情緒分析如果能搭配其他訊號,效果最好,不能單獨使用。
結論很簡單:如果你的團隊是根據大眾觀感做決策——無論是產品、品牌、活動還是危機——那麼針對 X 資料做情緒分析,就是最快的回饋迴路之一。
2026 年 X API 的現況:到底要怎麼取得推文資料
這正是大多數教學會翻車的地方。若你曾照著 Tweepy 教學貼上程式碼,然後撞上付費牆或難懂的錯誤訊息,你不是唯一一個。以前的 Free / Basic / Pro 分級已經不在了。現在的 X API 改成按用量計費並預付點數,每個端點都有費用,使用量也可以即時追蹤。
以下是目前各種資料取得方式的誠實比較:
| 方法 | 成本(2026) | 規模 | 技能門檻 | 備註 |
|---|---|---|---|---|
| X API v2(按用量付費) | 每次讀取 Posts $0.005 | 自助方案每月最多 200 萬次 Post 讀取 | 中等(Python) | 官方、可重現、合規 |
| 完整封存搜尋 | 每則回傳 Post $0.005;每次完整封存計數請求 $0.010 | 可回溯至 2006 年 3 月 | 中等到進階 | 適用於按用量付費與企業方案 |
| 篩選式串流 | 依傳送時的 Post 讀取計費 | 即時、持續 | 中等到進階 | 最適合即時蒐集 |
| 預製資料集(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 與瀏覽器擴充套件,不能算是對 X API 存取的合規替代方案。
X API v2:你實際拿得到什麼
一筆標準的 Post 讀取費用是每則回傳 Post $0.005。User reads 則每次 $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 搜尋不再回傳 reposts,而 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) | 規則式詞典 | 弱 | 部分支援 emoji | 最低 | 非常低 |
| TextBlob | 基於 pattern | 弱 | 否 | 較低 | 非常低 |
| Naive Bayes/Logistic Regression(TF-IDF) | 傳統機器學習 | 否 | 否 | 中等 | 中等 |
| CardiffNLP RoBERTa | Transformer(以推文微調) | 較好(但不完美) | 是 | 這些模型中最高 | 中等(HuggingFace pipeline) |
VADER:快速簡單,但能力有限
VADER 是為社群文字設計的規則式詞典方法。它速度快、可解釋、無需訓練資料,並且能處理部分 emoji 與表情符號。它會考慮否定詞、程度副詞、標點與大小寫。若你只是想快速建立基準,或在乎運算成本與透明度,VADER 很實用。它的弱點在於:反諷、俚語、依情境而變的語意,以及任何需要超越單字層次理解的內容。它的預設 compound 分數門檻(≥0.05 為正面、≤-0.05 為負面)只是預設值,不是放諸四海皆準的商業標準——請在你自己的驗證集上調整。
TextBlob:更簡單,但也更受限
TextBlob 是一個非常輕量的教學型基準。它預設的 PatternAnalyzer 並不是針對推文風格文字訓練的。它適合第一次做 NLP 實驗,但不適合正式的推文分析。
傳統機器學習:Naive Bayes、Logistic Regression、SVM
結合詞與字元的 TF-IDF 流程,再搭配 logistic regression 或 LinearSVC,仍然是很有價值的監督式基準。它便宜、可解釋,而且常常能看出 transformer 是否真的值得為了更高複雜度付出成本。關鍵規則是:只能在切分完訓練/驗證集之後再 fit vectorizer,避免詞彙與 IDF 洩漏。
這些模型在大型標註資料集上,通常會勝過規則式方法,但仍然很難抓到上下文、反諷與俚語。
CardiffNLP RoBERTa:2026 年推文情緒分析的標準選擇
cardiffnlp/twitter-roberta-base-sentiment-latest 是一個持續維護、專門處理推文、三分類的模型,也是 2026 年相當合理的強勢基準。它先用大量推文預訓練,再針對情緒任務微調,因此在 emoji、俚語與非正式語言上的表現,遠勝規則式或傳統機器學習方法。
以下是一段最小化的 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)
幾個注意事項:
- 輸出的是模型分數,不是已校準的商業機率。請在當前標註樣本上做校準,或加上拒答門檻。
- 上下文模型通常在許多推文任務上表現優於規則系統,但反諷、混合目標、缺少對話串上下文、方言與 code-switching,仍然是結構性的錯誤來源。不要宣稱任何模型「真的懂反諷」——更準確的說法是,它只是處理得比較好,而不是完美。
- 其他可考慮的替代方案包括 BERTweet、TimeLMs,以及多語言 Twitter-XLM-R 模型,視語言與任務而定。
所以,Twitter 情緒分析真的能準確嗎?可以——但前提是模型、前處理、標籤定義與評估樣本都要符合任務需求。把 2019 年教學裡的 VADER 程式碼直接貼上去,只能算是基準,不是生產品質的證明。
真正的推文前處理流程(不只是 text.lower())

如果你把原始 URL、@提及與 HTML 實體直接丟進情緒模型,就算模型不差,也可能吐出垃圾結果。大多數教學(包括那些排名很前面的)只會在餵模型前把文字轉成小寫。這其實是在默默破壞準確率——尤其是傳統機器學習,前處理品質的重要性有時甚至不亞於模型選擇。
要清理哪些內容,以及為什麼重要
| 元素 | 處理方式 | 原因 |
|---|---|---|
| URL | 以像 http 這樣的占位符替換 | URL 對情緒通常是雜訊;直接刪掉周邊文字會破壞上下文 |
| @提及 | 將帳號替換成 @user | 保留結構,同時去除作者身分洩漏 |
| Emoji/表情符號 | 對現代 tokenizer 保留;對稀疏模型則測試是否轉成文字 | Emoji 帶有強烈情緒訊號,刪掉等於丟資料 |
| Hashtag | 保留 token;必要時另外加入拆詞版本(例如 #ClimateChangeIsReal → Climate Change Is Real) | Hashtag 往往直接包含觀點 |
| 否定詞 | 保留 not、no、never、縮寫與轉折詞 | 一般 stop word 清單常把它們刪掉,導致情緒反轉 |
| 大小寫/標點 | 對 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 |
| Emoji 轉文字後(供稀疏模型) | @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 來說,你應該保留 emoji、標點與大小寫——因為模型就是用這種風格的文字訓練的。若是 TF-IDF 模型,你可能會選擇把 emoji 轉文字、轉小寫並做詞形還原。
可直接複製使用的 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 轉文字(使用 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 則 Posts,大約是 $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 + Logistic Regression 的傳統機器學習
這是「先理解基本原理」的路徑。先切分資料,vectorizer 只能在訓練集上 fit,接著訓練 logistic regression 分類器:
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 搭配 logistic regression 通常表現還不錯——但要記住,這個資料集來自 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:測試邊界案例
挑幾則能測試反諷、emoji 與俚語的推文:
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("情緒")
plt.ylabel("推文數")
plt.title("情緒分布")
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("日期")
plt.ylabel("平均情緒分數")
plt.title("情緒隨時間變化")
plt.axhline(0, color="gray", linestyle="--")
plt.show()
如果上市當天突然下滑?那就是你該深入負面推文、找出問題出在哪裡的訊號。
混淆矩陣熱圖
前面的評估步驟已經示範過。重點在於:看你的模型在哪些地方把正面誤判為負面,或反過來。這些推文最值得人工閱讀。
給非工程人員:在 Google Sheets 或 Notion 畫圖
如果你已經把情緒標註資料匯出到試算表,就可以直接在 Google Sheets、Notion 或任何 BI 工具中建立情緒分布與趨勢圖,不需要 Python。
Twitter 情緒分析的常見陷阱,以及如何避開
在真實世界的情緒工作流程中,總是反覆出現同樣的錯誤。
反諷與戲謔
這是準確率最大的殺手。「Love waiting three hours for support 😒」對規則式模型看起來像正面。Transformer 模型確實好一些,但反諷本身在結構上就很難處理——尤其是當貼文本身缺少上下文(對話串、作者歷史、事件背景)時。對高風險用途,請把模型輸出與人工抽查結合起來。
Emoji 與俚語盲點
如果你的前處理把 emoji 直接刪掉,而不是在稀疏模型中轉成文字、或在 transformer 中保留,那你其實是在丟掉資料裡最強的情緒訊號之一。俚語也是一樣——像「ngl this slaps」是正面,但只看正式英文訓練的模型不一定懂。
過時的 API 教學與壞掉的爬蟲
如果教學還在用 API v1.1 的 Tweepy,那就過時了。如果它推薦 snscrape,請注意:它自 2023 年起就無法搜尋 X。跟著任何教學前,都要先看發佈日期與 API 版本。
對單一資料集過度擬合
Sentiment140 很適合拿來訓練,但它畢竟是 2009 年的資料。2024 年 EMNLP 對 20 個社群媒體資料集的稽核發現,移除重複資料後,有 14 個(共 19 個測試資料集)F1 分數下降,且有 17 個(共 19 個)資料集的模型排名發生變化。請使用以時間為基礎、事件彼此不重疊,且最好作者也不重疊的切分方式。再用近期推文測試,看模型是否真的能泛化。
把情緒分數當成真值
模型分數不是已校準的機率。不要只根據情緒標籤就自動觸發回應,或做對外決策。凡是會影響個人、或涉及危機應對的決策,都必須保留人工審查。
隱私、平台政策與負責任使用
這一段不是可有可無。
X 的 Developer Policy 強調隱私、使用者控制、內容刪除,以及對 off-X 對應的限制。實務規則如下:
- 只蒐集必要欄位。
- 回報時以彙總結果為主,不要直接公開原始帳號。
- 保留 Post ID 與取得時間,以符合法規與稽核要求。
- 在內容刪除、保護設定變更或符合理據的請求出現後,刪除或更新已儲存內容。
- 不要推斷個人的敏感特徵。
- 沒有合法依據與同意,不要把情緒分數與 CRM 身分資料串接。
- 在 restricted-use rules 禁止的情況下,不要用 X Content 訓練或微調 foundation model。
- 記錄樣本數、查詢詞、時間窗口、語言篩選與排除條件。
- 絕不要只根據情緒分數,自動對外做公開回應。
情緒分析很強大,但也伴隨真實責任。請嚴肅看待。
結論與重點摘要
在 2026 年,Twitter 情緒分析確實能用,但前提是你必須用符合現況的方法。過去那套配方——免費 API、只做小寫化前處理、VADER 或 Naive Bayes、完全不評估——已經失效。真正有效的是:
- 透過合法途徑取得資料。 使用 X API v2(按用量付費)、授權供應商,或透明的資料集。不要依賴壞掉的爬蟲或瀏覽器繞道方案。
- 前處理要為模型服務,不只是做樣子。 對 transformer 保留 emoji、否定詞與大小寫;URL 與提及要正規化;流程要和模型訓練資料匹配。
- 把便宜的基準模型和推文專用 transformer 做比較。 TF-IDF + logistic regression 仍然是很好的 sanity check。CardiffNLP RoBERTa 是目前推文情緒分析很強的預設選擇。
- 誠實評估。 報告 macro F1、各類別指標與混淆矩陣。使用最新、人工標註的樣本,並為模糊案例設定拒答門檻。
- 視覺化是為了決策,不只是裝飾。 情緒隨時間變化的圖與文字雲,能講出分類報告講不出的故事。
- 保留人工介入。 沒有任何模型能在反諷、混合目標或依上下文變化的語意上做到完美。對高風險用途,請把模型結果與人工審核結合。
如果你剛開始入門,可以先抓一份免費資料集、打開 Google Colab,直接跑 HuggingFace pipeline。不到十分鐘,你就能得到可用的情緒分數。如果你想在工作流程的其他部分,不寫程式就蒐集並結構化網頁資料,Thunderbit 也能在你有權限自動化的相容頁面上幫上忙。
如果你是為作品集或面試而做這個專案:加入 transformer 比較、完整前處理流程,以及情緒隨時間變化圖,會立刻讓你的作品比一般訓練營範本更有差異。
延伸閱讀
- 如何使用 Thunderbit 精通自動化資料抓取
- 2026 年 6 款最佳 Twitter(x.com)爬蟲
- 如何在 2025 年使用 Python 抓取 Twitter 貼文
- 如何運用 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 工具指南。


