Aspect-Based Sentiment Analysis Advanced

Aspect-Based Sentiment Analysis (ABSA) goes beyond document-level polarity to identify opinions about specific aspects of a product or service. For example, a restaurant review might express positive sentiment about the food but negative sentiment about the service.

What is ABSA?

ABSA involves two subtasks:

Subtask Description Example
Aspect Extraction Identify the aspects mentioned in text "Great camera but terrible battery life" → [camera, battery life]
Aspect Sentiment Determine sentiment for each aspect camera: positive, battery life: negative

Using Pretrained ABSA Models

Python
from transformers import pipeline

# Zero-shot classification can be used for ABSA
classifier = pipeline("zero-shot-classification")

review = "The food was amazing but the service was incredibly slow."
aspects = ["food quality", "service speed", "ambiance", "price"]

result = classifier(review, aspects, multi_label=True)
for label, score in zip(result["labels"], result["scores"]):
    print(f"{label}: {score:.3f}")

ABSA with LLMs

Large language models can perform ABSA in a zero-shot manner with structured output:

Python
from openai import OpenAI
import json

client = OpenAI()

review = """The laptop has a stunning display and the keyboard is
comfortable for long typing sessions. However, the fan noise
is unbearable and the battery barely lasts 3 hours."""

response = client.chat.completions.create(
    model="gpt-4",
    messages=[{
        "role": "user",
        "content": f"""Analyze the following review and extract aspects
with their sentiment (positive/negative/neutral) and a brief reason.
Return as JSON array.

Review: {review}"""
    }],
    response_format={"type": "json_object"}
)

aspects = json.loads(response.choices[0].message.content)
print(json.dumps(aspects, indent=2))
# {
#   "aspects": [
#     {"aspect": "display", "sentiment": "positive", "reason": "described as stunning"},
#     {"aspect": "keyboard", "sentiment": "positive", "reason": "comfortable for long use"},
#     {"aspect": "fan noise", "sentiment": "negative", "reason": "described as unbearable"},
#     {"aspect": "battery", "sentiment": "negative", "reason": "barely lasts 3 hours"}
#   ]
# }

Rule-Based ABSA with spaCy

Python
import spacy
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer

nlp = spacy.load("en_core_web_sm")
analyzer = SentimentIntensityAnalyzer()

# Define aspects to track
aspect_keywords = {
    "food": ["food", "meal", "dish", "taste", "flavor"],
    "service": ["service", "staff", "waiter", "server"],
    "price": ["price", "cost", "expensive", "cheap", "value"],
    "ambiance": ["ambiance", "atmosphere", "decor", "music"],
}

def analyze_aspects(review):
    doc = nlp(review)
    results = {}
    for sent in doc.sents:
        sent_text = sent.text.lower()
        for aspect, keywords in aspect_keywords.items():
            if any(kw in sent_text for kw in keywords):
                score = analyzer.polarity_scores(sent.text)["compound"]
                results[aspect] = score
    return results

review = "The food was delicious and well presented. The service was slow but friendly. Prices are a bit high for the portion size."
print(analyze_aspects(review))
# {'food': 0.65, 'service': 0.05, 'price': -0.34}

Aggregating Aspect Sentiments

For business insights, aggregate aspect sentiments across many reviews:

Python
import pandas as pd

# Analyze all reviews
all_aspects = []
for review in reviews:
    aspects = analyze_aspects(review)
    all_aspects.append(aspects)

# Create summary DataFrame
aspect_df = pd.DataFrame(all_aspects)
summary = aspect_df.describe().loc[["count", "mean"]]
print(summary)
# Shows average sentiment per aspect across all reviews
Practical Tip: For production ABSA, the LLM approach often gives the best results with the least development effort. Define your aspects, provide clear instructions with examples, and parse the structured output. It handles implicit aspects, sarcasm, and complex sentences much better than rule-based approaches.

Try It Yourself

Collect 50 restaurant reviews, define 4-5 aspects, and run both the rule-based spaCy approach and the LLM approach. Compare the quality of extracted aspects and sentiment accuracy.

Next: Best Practices →