By Sorsa Editorial

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?

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:

  1. Data source - tweets collected via API, a dataset, or scraping.
  2. Preprocessing - cleaning raw text to remove noise such as URLs, mentions, emojis, and slang.
  3. 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:

MethodAuthLive dataCost for 10,000 tweets (with author data)Monthly cap
Static dataset (Sentiment140)NoneNoFreen/a
Official X API (pay-per-use)OAuth 2.0Yes~$1502M post reads
Sorsa (Pro plan)API keyYes~$1Plan-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:

bash
pip install requests

This function collects tweets matching a search query and handles pagination:

python
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:5 to cut spam, or since:2026-04-01 to 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 under user. No extra call is needed for user data.
  • The next_cursor field 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:

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

  1. Keep emojis and use a classifier that understands them (VADER and RoBERTa both do).
  2. Convert emojis to text with the emoji library (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

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

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

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):
    """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.

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: 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.

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

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

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?

Here is a practical comparison based on published benchmarks and real-world use.

VADERTextBlobLogistic Regression (TF-IDF)RoBERTa (twitter-roberta-base)
Accuracy on Twitter data~73-75%~71-73%~80-82%~88-91%
Setup time2 minutes2 minutes30-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 requiredNoNoNoRecommended above 1K tweets
Handles emojisYes (natively)PoorlyOnly if in training dataYes (trained on 124M tweets)
Handles sarcasmPoorlyPoorlySomewhatBetter, still limited
Three-class (pos/neg/neutral)YesWith thresholdsDepends on labelsYes (native)
Custom domain trainingNo (fixed lexicon)No (fixed lexicon)YesYes (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:

  1. 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.
  2. Prototype your query in the free Search Builder, where you can test search operators and preview results without writing code.
  3. Copy the Python from this guide to start collecting and classifying. Collection to visualization fits in under 100 lines.
  4. 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.