Use case

Aspect-based sentiment analysis with calibrated confidence

Product and support teams learn what customers actually like and dislike, not just an average star rating. Laya asks one question per aspect, such as delivery, price or support, and returns a probability for every label, so you can aggregate sentiment honestly and send only the unclear reviews to a person.

7 min readLast updated

Swiss-hosted inference. Nothing you send is ever stored.Swiss data residency

In 30 seconds

  • Instead of one positive or negative label, each review gets a verdict per topic, such as product, billing or support.
  • Every verdict has a probability, so totals across thousands of reviews stay honest.
  • Unclear reviews can be flagged for a person to read.
  • It works in 100+ languages through automatic routing.

Code and dense tables are folded away. Open any of them on demand.

Live demo · no signup

Try this use case

Edit the text if you like, then press run. Laya answers every question at once, with a probability for each option.

1 more question in the full request.252/600

The questions it answers

  • overallchoiceWhat is the overall sentiment of `text`?
  • product_sentimentchoiceHow does `text` describe the product itself (features, speed, design)?
  • billing_sentimentchoiceHow does `text` describe billing, pricing or charges?
  • emotionchoiceWhich emotion is strongest in `text`?

The answers appear here as bars: the longer the bar, the more likely Laya thinks that option is.

Show the full API request· JSON
POST https://api.laya.studio/v1/systemonejson
{
  "state": {
    "source": "app_store_review",
    "rating": 3,
    "text": "The new dashboard is genuinely faster and I like the dark mode. But I was charged for two seats after removing one, and support took four days to reply. Probably not renewing unless billing gets sorted."
  },
  "questions": {
    "overall": {
      "type": "choice",
      "instructions": "What is the overall sentiment of `text`?",
      "criteria": {
        "A": "mostly positive",
        "B": "mixed: clear positives and clear negatives",
        "C": "mostly negative",
        "D": "neutral or purely factual"
      }
    },
    "product_sentiment": {
      "type": "choice",
      "instructions": "How does `text` describe the product itself (features, speed, design)?",
      "criteria": {
        "A": "positive about the product",
        "B": "negative about the product",
        "C": "the product is not discussed"
      }
    },
    "billing_sentiment": {
      "type": "choice",
      "instructions": "How does `text` describe billing, pricing or charges?",
      "criteria": {
        "A": "positive about billing or price",
        "B": "negative about billing or price",
        "C": "billing and price are not discussed"
      }
    },
    "emotion": {
      "type": "choice",
      "instructions": "Which emotion is strongest in `text`?",
      "criteria": [
        "joy",
        "sadness",
        "anger",
        "fear",
        "love",
        "surprise"
      ]
    },
    "churn_signal": {
      "type": "choice",
      "instructions": "Does `text` suggest the customer may cancel or not renew?",
      "criteria": {
        "A": "yes, cancellation or non-renewal is suggested",
        "B": "no such suggestion"
      }
    }
  }
}

What is aspect-based sentiment analysis?

Aspect-based sentiment analysis finds how a customer feels about each part of their experience, such as the product, billing or support, instead of giving the whole review one score. Laya answers one typed question per aspect in a single API call and attaches a probability to every label, so you can act on each topic separately.

Most feedback pipelines reduce a review to one number: positive, negative, or a 1–5 rating. The example review on this page is a three-star rating that contains praise for the product, a billing error, a slow support response and a renewal risk. A single polarity label throws away every one of those facts, and a product team reading an average of such labels learns almost nothing.

Aspect-based sentiment asks separate questions per aspect: how does the customer feel about the product, about billing, about support? It is the version of sentiment analysis that actually drives decisions, but it multiplies the number of classifications per review. With an LLM, that means either one long structured-output call per review (slow, expensive, and fragile to parse) or several calls. With a fine-tuned classifier, it means training and maintaining one head per aspect.

The other half of the problem is aggregation. Dashboards average predictions across thousands of reviews. If the classifier's probabilities are not calibrated, a systematic over-confidence on one class silently skews the aggregate. Averaging calibrated probabilities is one of the few ways to get a sentiment trend you can defend.

Why a decision model rather than an LLM for sentiment

  • Several aspects, one pass. Laya answers every question in a request in a single forward pass. The model card reports 84.5 ms for five questions on the English checkpoint and 40.1 ms on the multilingual one on a T4 GPU, against 39.5 ms and 32.8 ms for one question. Network time to the hosted API is extra.
  • Typed answers. Each aspect returns exactly one of your labels plus a probability per label. There is no JSON for an LLM to half-produce and nothing for it to invent. The label can still be wrong; it cannot be outside your schema.
  • Calibration that survives aggregation. Laya is trained with RLCD: exploration noise on the logits and a reward from a strictly proper scoring rule, under which reporting honest probabilities maximizes expected reward. After per-bucket temperature scaling the model card reports ECE of 0.081 on the English checkpoint. Summing calibrated probabilities gives an unbiased count estimate; summing argmax labels does not.
  • Emotion as well as polarity. On DAIR Emotion (six labels: sadness, joy, love, anger, fear, surprise) the model card reports 0.595 accuracy for routed Laya against a published 0.480 for TypeSafe Jev, and notes Jev assigned zero probability to the true label on 16% of examples. Six-way emotion is hard for everyone; 0.595 is a useful signal, not ground truth.
  • Cost. 1 credit = 1 input token. Each question reads the review once, so the five-question example costs about five times the review's tokens. See pricing.

Designing sentiment questions: aspects, neutral keys and emotion

The example uses only choice questions, and that is deliberate.

Polarity uses neutral keys. The obvious design would be a noul such as "is the review positive?". The model card documents that on the English checkpoint, noul can follow its false:/true: option labels instead of the text and return a confident "no" for clearly positive input (issue #156). Its recommended workaround is a choice question with neutral keys (A, B) and the yes/no wording in the descriptions. The example applies that to every polarity and yes/no question.

Every aspect has a "not discussed" option. Without it, a review that never mentions billing is forced into positive or negative. That is the most common source of garbage in aspect sentiment.

Mixed is an explicit label. For overall sentiment, "mixed: clear positives and clear negatives" is a real category, not a failure to decide. If you leave it out, mixed reviews show up as low-confidence positives or negatives, which is harder to report.

Avoid a five-level score for sentiment. It is tempting to model "very negative … very positive" as a score question. The model card flags score as the weakest primitive and cites 0.372 on SST-5, the five-class sentiment benchmark. If you need intensity, use three well-separated levels or a choice question, and check the confusion matrix.

Emotion as a list of labels. Criteria can be a plain list when the label names are self-explanatory. The six labels above match the DAIR Emotion set, which is the only emotion benchmark the model card reports.

Keep aspect questions to the aspects your team acts on. Each one re-reads the review, so each adds its input tokens to the bill.

Thresholds and escalation for sentiment pipelines

Sentiment pipelines use confidence in two ways: to decide which individual reviews need a human, and to weight aggregates.

Per-review gating. Use confidence. For choice questions it is one minus the normalized entropy of the probabilities, so it falls when mass is spread across labels. Do not gate on action.act_probability: the model card and issue #185 report that it reads close to 1.0 for almost every input and that its raw logits run against correctness (AUROC 0.30 on 396 labelled decisions, against 0.77 for confidence). Log it so you can switch it on when a checkpoint fixes it.

A starting policy to tune on your own labels:

ConditionAction
churn_signal = A with confidence ≥ 0.5Create a retention task, even if overall is positive
Any aspect B (negative) with confidence ≥ 0.6Tag the owning team
overall confidence < 0.3Send to manual review sample
Everything elseAggregate only

Aggregation. For dashboards, sum probabilities rather than counting argmax labels: the expected number of negative billing mentions is the sum of probabilities.B across reviews. This is only honest if the probabilities are calibrated, so fit temperatures first. The model card reports the English checkpoint's mean ECE falling from 0.466 to 0.081 after one temperature per (question type, option count), and the multilingual checkpoint from 0.314 to 0.106. Check the result with a reliability diagram.

Show technical details· python sample
python
def negative_billing_estimate(results):
    # expected count of reviews negative about billing
    return sum(r["billing_sentiment"]["probabilities"]["B"] for r in results)

Integration: scoring reviews through /v1/systemone

Show technical details· bash sample
bash
curl -s https://api.laya.studio/v1/systemone \
  -H "Authorization: Bearer $LAYA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"state": {"text": "Faster dashboard, but I was double charged and support took four days."},
       "questions": {"billing_sentiment": {"type": "choice",
         "instructions": "How does text describe billing, pricing or charges?",
         "criteria": {"A": "positive about billing or price", "B": "negative about billing or price",
                      "C": "billing and price are not discussed"}}}}'
Show technical details· python sample
python
import os, requests

def score_review(text: str, questions: dict) -> dict:
    r = requests.post(
        "https://api.laya.studio/v1/systemone",
        headers={"Authorization": "Bearer " + os.environ["LAYA_API_KEY"]},
        json={"state": {"text": text}, "questions": questions},
        timeout=5,
    )
    r.raise_for_status()
    return r.json()["answers"]
Show technical details· typescript sample
typescript
export async function scoreReview(text: string, questions: object) {
  const res = await fetch("https://api.laya.studio/v1/systemone", {
    method: "POST",
    headers: { Authorization: "Bearer " + process.env.LAYA_API_KEY, "Content-Type": "application/json" },
    body: JSON.stringify({ state: { text }, questions }),
  });
  if (!res.ok) throw new Error("laya " + res.status);
  const { answers, routing } = await res.json();
  return { answers, checkpoint: routing?.model };
}

Reviews in other languages need no extra code: leave model unset and the router sends non-English text to the multilingual checkpoint. For backfills of historical reviews, send requests concurrently rather than one at a time; each request is billed per question either way. Sign up for a key or see the docs.

Limitations of decision-model sentiment analysis

  • Fine-grained intensity is weak. Five-level sentiment is where the model card reports its weakest number (SST-5, 0.372). Prefer coarse, well-described categories.
  • Emotion is hard. 0.595 on six-label DAIR Emotion beats the published Jev figure but still means roughly four in ten top labels are wrong. Use emotion for trends and routing hints, not for decisions about individuals.
  • Sarcasm and domain slang are classic failure modes for any classifier. Label a sample of your own reviews that contain them and measure.
  • Zero-shot needs checking. The base checkpoints were not fine-tuned on your aspects. Evaluate on a labelled set before automating, and fine-tune if accuracy is not good enough.
  • Context length. The English checkpoint reads about 320 tokens of state; long reviews or survey answers are truncated. The multilingual checkpoint reads about 768.
  • Language. The English checkpoint can be confidently wrong on non-Latin scripts; the model card shows 0.000 accuracy at 0.952 confidence on Khmer. Let the router pick the checkpoint rather than forcing english.

Frequently asked questions

What is the difference between sentiment analysis and aspect-based sentiment analysis?
Plain sentiment analysis gives a whole text one polarity or rating. Aspect-based sentiment gives a separate verdict per topic, so a review that praises the product and complains about billing shows up in both places.
Why use choice questions with keys like A and B for positive or negative?
The model card documents that noul answers on the English checkpoint can follow their true/false labels instead of the text (issue #156). A two-option choice with neutral keys and descriptive text avoids that bias.
How accurate is Laya on emotion detection?
The model card reports 0.595 on the six-label DAIR Emotion dataset for routed Laya, against a published 0.480 for TypeSafe Jev. Measure on your own data before relying on it.
Can I get a 1 to 5 sentiment score?
You can, with a five-level score question, but it is the weakest primitive (0.372 on SST-5 per the model card). Three well-separated levels or a choice question are more reliable.
How should I aggregate sentiment across thousands of reviews?
Sum calibrated probabilities instead of counting top labels. Fit temperatures on a labelled sample first so the probabilities mean what they say.
Does it work for reviews in other languages?
Yes. Leave the model field unset and the router sends non-English reviews to the multilingual checkpoint, which covers 100+ languages.

Sources

Last updated . Laya Studio is an independent hosted service for the open-source Laya model (Apache-2.0, © Convai Innovations) and is not affiliated with Convai Innovations or TypeSafe.