Updated June 2026: refreshed X API pricing and rate limits, added a trainable-classifier walkthrough on Sentiment140, a word cloud step, and updated platform usage figures.
Key Takeaway: Twitter sentiment analysis classifies tweets as positive, negative, or neutral with natural language processing. A pipeline has two stages: collecting tweet data through an API or dataset, then classifying that text using VADER, TextBlob, or a transformer like RoBERTa, which reaches roughly 88 to 91 percent accuracy on English tweets.
Most sentiment tutorials hand you a static CSV from 2009 and skip the hard part: getting fresh tweets. This guide covers both halves, and for the collection step it uses Sorsa API, an alternative Twitter/X API provider, because the economics are hard to argue with. One call to the /search-tweets endpoint returns up to 20 tweets with full author profiles attached and counts as a single request, so a 10,000-tweet dataset costs about a dollar on the $199 Pro plan, against roughly $150 on the official X API. Access is a single API key in a header, with no OAuth and no developer-account approval, a flat 20 requests per second on every plan, and pricing that runs up to 50x cheaper than the official API.
We build and operate this API, and we test the classifiers below against data we collect ourselves, so the workflow here is the one we actually run. The architecture has not changed in years even as the tools have: collect, clean, classify, visualize. The rest of this guide walks through each stage with runnable Python.
Table of Contents
- What Is Twitter Sentiment Analysis?
- Why Twitter Sentiment Analysis Still Matters in 2026
- Step 1: Collecting Tweet Data
- Step 2: Cleaning and Preprocessing Tweets
- Step 3: Choosing a Sentiment Classification Method
- Step 4: Running Sentiment Analysis in Python
- Training Your Own Classifier on Labeled Data
- Step 5: Visualizing and Interpreting Results
- Which Approach Should You Use?
- Common Pitfalls and Edge Cases
- Practical Use Cases
- Building This as a Complete Project
- FAQ
- Getting Started
What Is Twitter Sentiment Analysis?
Twitter sentiment analysis, also called opinion mining, is the automated process of detecting whether a tweet expresses a positive, negative, or neutral opinion. More advanced systems extend this to specific emotions such as anger, joy, or sadness, or to sentiment directed at a particular entity named in the tweet.
Every pipeline rests on three components:
- Data source - tweets collected via API, a dataset, or scraping.
- Preprocessing - cleaning raw text to remove noise such as URLs, mentions, emojis, and slang.
- Classification - assigning a sentiment label using a rule-based lexicon, a trained machine-learning model, or a pre-trained transformer.
The output is a label (positive, negative, or neutral) and usually a confidence score. What you do with that output depends on the goal: brand monitoring, market research, academic study, or real-time alerting.
Why Twitter Sentiment Analysis Still Matters in 2026
X (formerly Twitter) is still one of the few platforms where public opinion surfaces in real time and in short, classifiable fragments. Estimates vary because X no longer publishes official figures, but independent trackers put the platform at roughly 550 to 600 million monthly active users as of early 2026, posting opinions about brands, products, politics, and events in a format that is structurally ideal for NLP.
Three properties make that data especially useful:
Volume and velocity. A trending topic can generate millions of posts in hours. No survey or focus group produces signal that fast.
Public by default. Most tweets are public and reachable through an API, which removes the consent and access barriers that complicate sentiment work on platforms like Facebook or Instagram.
Reaction data, not curated content. People post in the moment. A tweet fired off about a cancelled flight tells you more about real customer sentiment than a polished review written three days later. That raw quality is harder to process but more honest to analyze.
Step 1: Collecting Tweet Data
This is where most tutorials fail you. The classic recipe was: install Tweepy, authenticate with Twitter's free API, pull tweets. That pipeline broke in 2023 when Twitter removed free API access, and the cost has climbed since.
The Data Collection Landscape in 2026
You have three realistic options for getting tweets into a Python pipeline:
Option A: Static datasets. Download a pre-labeled set like Sentiment140 (1.6M tweets from 2009) or the TweetEval benchmark. Good for learning and prototyping, but the data is years old, so you cannot analyze current events or your own brand.
Option B: Official X API. As of 2026, X runs a pay-per-use model with no subscription tiers for new accounts. You pay $0.005 per post read and $0.010 per user profile, with a hard cap of 2 million post reads per month. A search returning 20 tweets costs $0.10 in post reads, plus another $0.20 if you want author profiles. Authentication is OAuth 2.0. For a 10,000-tweet dataset with user data, that runs roughly $150.
Option C: Third-party API. Providers such as Sorsa serve the same public Twitter data through plain REST endpoints with flat per-request pricing. One call to the search endpoint returns up to 20 tweets with full author profiles included and counts as a single request, whatever the result size. On the Pro plan ($199 per month for 100,000 requests), that same 10,000-tweet dataset costs about $1. Authentication is one API key in a header, with no OAuth flow and no approval wait.
Here is the collection cost laid out side by side, with real numbers for each option:
| Method | Auth | Live data | Cost for 10,000 tweets (with author data) | Monthly cap |
|---|---|---|---|---|
| Static dataset (Sentiment140) | None | No | Free | n/a |
| Official X API (pay-per-use) | OAuth 2.0 | Yes | ~$150 | 2M post reads |
| Sorsa (Pro plan) | API key | Yes | ~$1 | Plan-based (100K requests) |
For learning the modeling, a static dataset is fine. For anything tied to the present, a flat-rate Twitter/X API removes both the cost spike and the OAuth setup. Full numbers for both providers are in our Twitter/X API pricing breakdown. If you are still weighing collection approaches, our guide on how to scrape Twitter compares the methods that still work in 2026, and the Python workflow for pulling X data covers the requests-based setup below in more depth.
Collecting Tweets with Python
Install the requests library:
pip install requests
This function collects tweets matching a search query and handles pagination:
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")
A few specifics about this function:
- The query uses Twitter search operators to filter for English original posts and drop retweets. Add
min_faves:5to cut spam, orsince:2026-04-01to bound the date range. - Each tweet in the response carries
full_text,created_at, engagement metrics (likes_count,retweet_count,reply_count,view_count), and the full author profile nested underuser. No extra call is needed for user data. - The
next_cursorfield drives pagination. When it comes back null, you have reached the end. - At 20 tweets per page, 500 tweets take 25 requests, which is about $0.05 on the Pro plan.
For large collections, run several queries in parallel (different keywords, date windows, or accounts) and deduplicate by tweet ID afterward.
Step 2: Cleaning and Preprocessing Tweets
Raw tweets are messy. A single post can mix mentions, URLs, hashtags, emojis, slang, misspellings, and more than one language. Feeding that straight into a classifier drags accuracy down.
This function handles the most common noise:
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'])
What About Emojis?
Emojis carry strong sentiment signal. A tweet reading "new update ๐๐คก" has a clear negative tone that vanishes if you strip them. Two reasonable approaches:
- Keep emojis and use a classifier that understands them (VADER and RoBERTa both do).
- Convert emojis to text with the
emojilibrary (pip install emoji), turning ๐ into:smiling_face_with_smiling_eyes:, which helps lexicon tools that do not read emoji natively.
For transformer models like RoBERTa, keep emojis as they are. The model learned their meaning during training.
Should You Stem or Lemmatize?
Many tutorials treat stemming and lemmatization as mandatory. They are not. With TF-IDF features and a traditional model (Naive Bayes, SVM), stemming shrinks vocabulary size and can help. With a pre-trained transformer or a lexicon tool like VADER, skip it: those tools handle word forms internally, and aggressive stemming destroys signal. "Unhappy" stemmed to "unhappi" loses its lexicon match.
Step 3: Choosing a Sentiment Classification Method
This is the most important architectural decision in the pipeline. Four broad approaches, each with different tradeoffs in accuracy, speed, cost, and setup.
Approach 1: Rule-Based Lexicons (VADER, TextBlob)
These ship with a dictionary of words scored for polarity, apply rules for negation and emphasis, and output a compound score.
VADER (Valence Aware Dictionary and sEntiment Reasoner) was built for social media. It handles emojis, slang, capitalization ("GREAT" scores higher than "great"), and degree modifiers ("very good" versus "good"), and it runs instantly with no model loading or GPU.
TextBlob uses a lexicon derived from product reviews and returns polarity (-1 to +1) and subjectivity (0 to 1). Simpler than VADER, less tuned for social text.
When to use: quick prototyping, real-time scoring where latency matters, or when you need to inspect which words drove a score. Weaker on ambiguous text.
Approach 2: Traditional ML Classifiers (Naive Bayes, SVM, Logistic Regression)
Train a classifier on labeled tweets using TF-IDF features. This was the standard before transformers. You need a labeled training set (Sentiment140 is the usual choice), and the model learns word-to-sentiment associations from it. Logistic Regression with TF-IDF typically reaches around 80 to 82 percent accuracy on Sentiment140 and trains in minutes. The full walkthrough is in the training section below.
When to use: you have domain-specific labeled data and want a lightweight model that runs without GPU infrastructure.
Approach 3: Pre-Trained Transformers (RoBERTa)
The cardiffnlp/twitter-roberta-base-sentiment-latest model from Hugging Face was trained on roughly 124 million tweets from 2018 to 2021 and fine-tuned on the TweetEval benchmark. It classifies text into negative, neutral, and positive with markedly higher accuracy than lexicon or classic ML approaches. Published benchmarks put RoBERTa-based models around 88 to 91 percent on Twitter sentiment tasks, against roughly 73 to 75 percent for VADER and TextBlob.
When to use: accuracy matters more than speed. Needs the transformers library and ideally a GPU for batch work, though CPU inference is fine for smaller sets.
Approach 4: Commercial Platforms (Sprinklr, Brandwatch, Meltwater)
Enterprise social-listening tools with built-in sentiment analysis. They bundle collection, classification, and dashboards, with pricing in the thousands per month.
When to use: enterprise teams that need dashboards and multi-language support without building anything. Overkill for a developer shipping a focused pipeline, and you give up control over preprocessing and model choice.
Step 4: Running Sentiment Analysis in Python
The three code-based approaches below run on the tweets collected in Step 1.
Method 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 is fast: roughly 10,000 tweets per second on a laptop. The compound score runs from -1 (most negative) to +1 (most positive), with the plus or minus 0.05 thresholds recommended by the original paper.
Method 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 is about twice as slow as VADER but still fast. One caveat: its lexicon came from product reviews, so it tends to mark slang-heavy tweets as neutral when the words fall outside its vocabulary.
Method 3: Pre-Trained RoBERTa Transformer
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 expects its own preprocessing: mentions become @user, URLs become http. Feed it the original tweet text so it sees the context it was trained on. On CPU it processes roughly 5 to 15 tweets per second; on even a modest GPU that jumps past 200. Above 10,000 tweets, batch on GPU.
Training Your Own Classifier on Labeled Data
Pre-trained models cover most needs. Train your own only when your domain language sits far from general tweets (finance, medical, legal, non-English) and you have labeled examples. Every tutorial-grade pipeline follows the same shape, so it is worth seeing end to end: load labeled tweets, vectorize with TF-IDF, train a classifier, and read the metrics.
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)))
To classify new tweets, run them through the same cleaner and vectorizer before calling clf.predict. If your labels are heavily imbalanced (common in real brand data, where neutral dominates), keep class_weight='balanced' or oversample the minority class with SMOTE rather than letting the model collapse onto the majority class.
The practical shortcut most teams use: label a small sample by hand or with a pre-trained RoBERTa model, review it for quality, then fine-tune on the result. You can build that labeled set from live data collected with the search endpoint, so the same collection code from Step 1 feeds both the pre-trained and the custom path. For a fuller walkthrough of assembling and labeling a training corpus, see our guide on building a Twitter dataset for machine learning.
Step 5: Visualizing and Interpreting Results
Raw labels are useful. Sentiment trends are actionable. Here is how to turn classified tweets into something a stakeholder can act on.
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')
For brand monitoring, the most actionable metric is often not the overall ratio but the change in it. A brand that normally runs 60 percent positive dropping to 40 percent signals a problem worth investigating, even when the absolute numbers still look mostly positive.
Weight sentiment by reach so loud tweets count more. The API response includes likes_count, retweet_count, and view_count for every tweet, the same engagement fields our Twitter engagement API guide covers for replies, quotes, and retweeters:
df['weighted_sentiment'] = df['vader_score'] * df['view_count']
print(f"Weighted sentiment index: {df['weighted_sentiment'].sum():.2f}")
A word cloud is the fastest way to see what is driving a sentiment class. Splitting it by label tells you the actual complaints behind the negatives:
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?
Here is a practical comparison based on published benchmarks and real-world use.
| VADER | TextBlob | Logistic Regression (TF-IDF) | RoBERTa (twitter-roberta-base) | |
|---|---|---|---|---|
| Accuracy on Twitter data | ~73-75% | ~71-73% | ~80-82% | ~88-91% |
| Setup time | 2 minutes | 2 minutes | 30-60 minutes (needs training data) | 10 minutes (pre-trained) |
| Speed (CPU) | ~10,000 tweets/sec | ~5,000 tweets/sec | ~8,000 tweets/sec | ~5-15 tweets/sec |
| GPU required | No | No | No | Recommended above 1K tweets |
| Handles emojis | Yes (natively) | Poorly | Only if in training data | Yes (trained on 124M tweets) |
| Handles sarcasm | Poorly | Poorly | Somewhat | Better, still limited |
| Three-class (pos/neg/neutral) | Yes | With thresholds | Depends on labels | Yes (native) |
| Custom domain training | No (fixed lexicon) | No (fixed lexicon) | Yes | Yes (fine-tuning) |
Accuracy figures come from benchmarks on the TweetEval dataset and Sentiment140. Real performance on your data will vary with domain, language mix, and the share of ambiguous or sarcastic text.
In practice, we start with VADER for a quick baseline. When accuracy matters, we switch to the pre-trained RoBERTa model. We only train a custom model when domain language (medical, legal, non-English) genuinely defeats the pre-trained options.
Common Pitfalls and Edge Cases
These are the issues that come up again and again across sentiment projects.
Sarcasm Detection
"Great, another app update that breaks everything I use daily." Every lexicon and most ML models read this as positive because of "great." Transformers catch sarcasm more often, but none is reliable. If sarcasm is common in your domain (tech Twitter, political commentary), add a sarcasm layer or manually review the "positive with high engagement" cluster, which often hides viral sarcastic posts.
Bot and Spam Contamination
Automated accounts distort distributions. A coordinated campaign can make a topic look overwhelmingly positive or negative. Filter by engagement thresholds (min_faves:1 in your search query) and check for duplicate or near-duplicate text across accounts.
Retweet Bias
Include retweets and a single viral negative tweet retweeted 50,000 times will dominate your dataset. The -filter:retweets operator strips native retweets. For quote tweets, which add commentary, keep them but score only the quote text.
Language Mixing
Twitter is global. Even with lang:en, you will hit code-switched tweets ("this movie was vraiment terrible") and transliterated text. The lang field in the tweet response is reliable for most cases, but short or emoji-heavy posts get misclassified. Add a secondary check with langdetect if purity matters.
Negation Handling
"Not bad" is positive. "Not good at all" is negative. VADER handles basic negation well, TextBlob struggles, and RoBERTa handles complex negation better than both because it reads the full sentence rather than scoring isolated words.
Practical Use Cases
Brand Monitoring
Sentiment analysis is the engine behind most social listening programs. Track sentiment around your brand name, product, or campaign hashtag in real time. Collect mentions through Sorsa's /mentions endpoint, which supports filters for minimum engagement and date ranges, run them through RoBERTa, and alert your team when negative sentiment crosses a threshold. The same pattern underpins most real-time Twitter monitoring setups, and our guide on how to track Twitter mentions walks through the query side in detail.
Financial Market Sentiment
Crypto and equity desks use Twitter sentiment as an alternative-data signal. Combine sentiment scores with cashtag searches ($TSLA, $BTC) and engagement weighting to build a sentiment index. The Sorsa Score endpoints add a layer by scoring account influence within the crypto ecosystem, so you can weight signal by who is posting.
Academic Research
Researchers studying elections, health crises, or social movements need large, time-bounded datasets. Use date-range operators (since:2026-01-01 until:2026-03-01) to collect precise slices. The historical tweet archive reaches back to 2006 with no archive surcharge. For a fuller walkthrough of querying older posts, see our guide on searching historical Twitter data.
Customer Feedback Analysis
Combine sentiment with topic extraction to find out what customers are unhappy about, not just that they are. Cluster negative tweets by keyword, then review the top clusters by hand. This bridges quantitative scoring and qualitative insight.
In Practice
A roughly 12-person market-research team we worked with had been pulling brand mentions on the official X API and kept hitting the 2 million post-read cap before month end, which forced them to throttle collection right when a product launch needed the most coverage. Moving the collection layer to a flat-rate Twitter/X API removed the cap problem and cut their monthly data bill substantially: because the per-request model is up to 50x cheaper than per-resource billing, a team in that position typically sees its collection spend fall by a similar factor for the same volume. Their classifier stack did not change at all; only the source of the tweets did.
Building This as a Complete Project
The five stages above already form a portfolio-grade project, which is why "twitter sentiment analysis" is such a common capstone and research build. To package it as one coherent project rather than a set of snippets, pick a single topic to analyze (a product, a vaccine, an election, a stock), collect a few thousand tweets on it with the search endpoint, run them through the cleaner and your chosen classifier, and finish with the time-series chart and word cloud from Step 5.
For a reproducible writeup, log three things: the exact search query and date range, the classifier and its version, and the label distribution you ended up with. That trio lets anyone rerun your analysis and is exactly what reviewers (and graders) look for. If you want a deployable surface, wrap the pipeline in a small Streamlit or Flask app so a non-technical user can enter a keyword and see the sentiment breakdown. The data layer is the only part that usually trips people up, and a flat-rate alternative X API keeps that layer cheap and approval-free for a student or research budget.
FAQ
What Python libraries do you need for Twitter sentiment analysis?
For collection, requests is enough if you use a REST API. For classification, the three common libraries are vaderSentiment (rule-based, tuned for social media), textblob (rule-based, general purpose), and transformers from Hugging Face (for pre-trained models like RoBERTa). Add pandas for data handling and matplotlib or wordcloud for visualization. One install line: pip install requests vaderSentiment textblob transformers torch pandas matplotlib wordcloud.
How accurate is Twitter sentiment analysis?
Accuracy depends entirely on the method. Rule-based tools like VADER reach roughly 73 to 75 percent on standard Twitter benchmarks. Traditional ML classifiers (Logistic Regression or SVM with TF-IDF) reach about 80 to 82 percent. Pre-trained transformers like twitter-roberta-base-sentiment-latest hit 88 to 91 percent. No method handles sarcasm or heavy context reliably, so expect to review 10 to 15 percent of edge cases by hand in production.
What is the easiest way to collect live tweets for sentiment analysis without a Twitter developer account?
The simplest route in 2026 is a third-party REST API. Sorsa API returns live tweets with full author profiles from its /search-tweets endpoint using a single API key in the header, with no OAuth and no developer-account approval. One call returns up to 20 tweets and counts as one request against a flat 20 requests-per-second limit, and you can prototype queries first in the free Search Builder before writing any code.
Is VADER or TextBlob better for tweet sentiment analysis?
VADER is better for Twitter specifically. It was designed for social-media text and handles emojis, slang, capitalization emphasis, and degree modifiers ("very good" versus "good") that TextBlob's review-based lexicon misses. In comparative studies, VADER outperforms TextBlob on social text by roughly 2 to 3 percentage points. Use TextBlob only when you also want its subjectivity score or are working with more formal text.
How do you handle tweets in languages other than English?
The English tools in this guide (VADER, TextBlob, the Cardiff RoBERTa model) are English-only. For multilingual sentiment, use cardiffnlp/twitter-xlm-roberta-base-sentiment from Hugging Face, which supports many languages. When collecting, filter by language with the lang: operator (for example lang:es for Spanish, lang:fr for French) and pick a classifier trained on that language.
How much does it cost to collect tweets for sentiment analysis?
On the official X API (pay-per-use as of 2026), each post read costs $0.005 and each user profile $0.010, so 10,000 tweets with author data run roughly $150. On a flat-rate provider like Sorsa, the same 10,000 tweets cost about $1 on the $199 Pro plan, since one search request returns up to 20 tweets with profiles included. That gap, up to 50x on read-heavy work, is why most sentiment pipelines move off per-resource billing once volume grows.
Can Twitter sentiment analysis detect sarcasm?
Not reliably with any current tool. Sarcasm depends on context, cultural knowledge, and sometimes the author's history, none of which a single tweet's text provides. Transformers like RoBERTa catch obvious sarcasm more often than lexicon tools, but benchmarks show even the best models reach only about 70 to 75 percent on dedicated sarcasm detection. For critical work, flag tweets where the label contradicts engagement (a "positive" tweet with angry replies) and review them.
What is the best dataset for training a Twitter sentiment classifier?
Sentiment140 (1.6 million tweets labeled positive or negative) is the most widely used training set, though its data is from 2009 and it has no neutral class. For three-class work, the TweetEval benchmark from Cardiff NLP is the current standard and is what the twitter-roberta-base-sentiment model was fine-tuned on. For domain-specific work, label your own set: use a pre-trained model to label a large corpus, review a sample, then fine-tune on the result.
Getting Started
To build a sentiment pipeline on live Twitter data, here is the fastest path:
- Get an API key from the Sorsa dashboard. Every endpoint is available on all plans, starting at $49 per month for 10,000 requests, with no approval step and setup in a few minutes.
- Prototype your query in the free Search Builder, where you can test search operators and preview results without writing code.
- Copy the Python from this guide to start collecting and classifying. Collection to visualization fits in under 100 lines.
- Read the docs at docs.sorsa.io for endpoint details, pagination, and the flat 20 requests-per-second rate limits.
For batch endpoints or custom plans for large-scale collection, see about Sorsa or talk to sales.
Reviewed by Keksich, founder of Sorsa, marketer and X API researcher.
How we put this together: this guide draws on our hands-on work building and operating an alternative Twitter/X API and on running the classifiers above against live data we collect ourselves. We verified the technical details against the Sorsa API documentation and the Hugging Face model card for cardiffnlp/twitter-roberta-base-sentiment-latest, whose accuracy figures trace back to the TweetEval benchmark; the official X API prices and the 2 million post-read cap were re-checked against current public pricing while updating this piece. We compared four classification approaches end to end. Last verified June 8, 2026.