Building Classifiers with Generative Models

Creación de clasificadores con modelos generativos

Desarrollo y Evaluación de Modelos Propios

Especialización en IA Generativa y Desarrollo de Negocios

Today

Agenda · 3 hours

  1. Warm-up: chatbots and agents in three questions 10'
  2. Theory: generative vs discriminative, LLMs as classifiers, synthetic data, calibration, cost 60'
  3. Break 10'
  4. Guided lab (PyTorch): NB vs LR, an MLP, zero-shot scoring, augmentation 60'
  5. Session challenge (graded, individual) 40'

Warm-up

Three questions on last session: intents and slots, agents, and how we measured our bots.

Warm-up · 10'
Warm-up · Q1

An intent-based bot (Rasa, Dialogflow CX) receives: “Please block my card ending in 4521.” What is “4521”?

The intent (block card) comes from a text classifier; entities such as the last four digits fill slots. In our S07 lab that classifier was TF-IDF + logistic regression. Today we open that box.
Warm-up · Q2

What makes an agent different from a chatbot that only answers from its prompt?

Agents interleave reasoning and actions (the ReAct pattern of Yao et al., 2023): think, call a tool, read the observation, decide the next step. Size and memory are separate choices.
Warm-up · Q3

After a change, a bot's containment rate rose from 60% to 85%, but complaints went up. Most likely reason?

A single metric can be gamed. Containment rises if the bot simply refuses to escalate. Today we meet the same trap in classification: a model that always says “neutral” scores high accuracy.

Learning objectives

By the end of this session you can…

  1. Contrast generative and discriminative classifiers with Bayes' rule, and predict when each wins RAE 1
  2. Train Naive Bayes, logistic regression and a PyTorch MLP, and read a learning curve RAE 1
  3. Turn an LLM into a zero-shot classifier by scoring the log-likelihood of each label RAE 3
  4. Run a synthetic-data experiment without leaking into the test set, and check calibration RAE 2
  5. Recommend a classifier under cost, latency and privacy constraints RAE 3

RAE numbers refer to the learning outcomes in the course syllabus (guía de asignatura).

Part 1

Generative vs discriminative classifiers

Two ways to answer “which class?”: model how the data is produced, or only draw the boundary.

Two strategies, one decision

Model the data, or model the boundary

🎨

Generative

Learn how each class produces data, \(p(x \mid y)\), and how common it is, \(p(y)\). Classify with Bayes' rule:

$$ \hat{y} = \arg\max_y \; p(x \mid y)\, p(y) $$

Naive Bayes, Gaussian discriminant analysis, class-conditional language models, an LLM scoring labels.

✂️

Discriminative

Learn the answer directly, \(p(y \mid x)\), without modelling \(x\) at all:

$$ \hat{y} = \arg\max_y \; p_\theta(y \mid x) $$

Logistic regression, an MLP on embeddings, a fine-tuned BERT classifier (S04).

Both end in the same place, \(p(y \mid x) = \dfrac{p(x \mid y)\,p(y)}{p(x)}\); they differ in what they spend data on.

The classic generative classifier

Naive Bayes: independence makes it cheap

Assume the words of a text are independent given the class:

$$ p(x \mid y) = \prod_{j=1}^{n} p(w_j \mid y) $$

Multinomial NB estimates each word probability by counting, with Laplace smoothing \(\alpha\):

$$ \hat p(w \mid y) = \frac{\text{count}(w, y) + \alpha}{\sum_{w'} \text{count}(w', y) + \alpha\,|V|} $$

In practice we add logs: \(\log p(y) + \sum_j \log p(w_j \mid y)\).

Why it learns fast: each class needs only word counts, estimated separately. No optimisation, no iterations.

Why it is “naive”: “price” and “target” are not independent in “price target cut”, so evidence is double-counted and probabilities become extreme.

Worked example · toy numbers

Is “Analyst cuts price target” bearish?

ClassPrior \(p(y)\)\(p(\text{cuts} \mid y)\)\(p(\text{target} \mid y)\)ProductPosterior
Bearish0.150.0100.0081.2 × 10⁻⁵83%
Bullish0.200.0010.0091.8 × 10⁻⁶12%
Neutral0.650.00050.0026.5 × 10⁻⁷5%
Priors ≈ class shares in the training split of the tweets dataset we use in the lab (15% · 20% · 65%). Word likelihoods are illustrative.

Posterior = product ÷ sum of products. “Neutral” starts as the favourite (prior 0.65) and loses because “cuts” is 20 times more likely under “bearish”.

Your turn in the chat

Which word would you add to push the answer towards “bullish”?

The classic discriminative classifier

Logistic regression: learn only the boundary

Score each class with a weighted sum of features, turn scores into probabilities with softmax:

$$ p(y = k \mid x) = \frac{\exp(w_k^\top x + b_k)}{\sum_{j} \exp(w_j^\top x + b_j)} $$

Fit \(w\) by minimising the cross-entropy (the negative conditional log-likelihood) with gradient descent:

$$ \mathcal{L}(w) = -\frac{1}{N} \sum_{i=1}^{N} \log p(y_i \mid x_i) + \lambda \lVert w \rVert^2 $$

What changes vs NB

  • Weights are fitted jointly: correlated words share the credit instead of double-counting it.
  • Needs an optimiser, iterations and regularisation \(\lambda\).
  • Probabilities are usually better calibrated than NB's.
  • A one-layer neural network: add hidden layers and you get the MLP of the lab.

Simulator · decision boundaries

Gaussian NB vs logistic regression, fitted live

Bayes-optimal accuracy: –

Accuracy on a fixed test sample of 1,000 points. Synthetic 2-D data generated in your browser (seeded).

Gaussian NB · generative

Test accuracy: –

Logistic regression · discriminative

Test accuracy: –

Class AClass BBayes-optimal boundaryShading = predicted class

Ng & Jordan (2002), on our own data

Generative learns faster; discriminative ends higher

Theory: NB approaches its (higher) asymptotic error with about \(O(\log d)\) examples; logistic regression needs about \(O(d)\), where \(d\) is the number of features. Often two regimes: NB first, LR later.

Here: TF-IDF features, financial tweets, test = the dataset's validation split (2,388 tweets); mean of 3 random training samples per size.

Switch to accuracy: at small sizes both hover near 66%, the score of always answering “neutral”.

Check · Part 1

Andes Bank has 60 labelled complaint emails today and will have 20,000 in a year. Best plan?

Two regimes: with little data the generative model (or an LLM prior) often wins; with plenty, discriminative models usually reach a lower error. Re-check the learning curve as data grows.

Metrics that match the business

A model that never catches a sell-off

65.6%

accuracy of a “classifier” that always answers “neutral” on the validation split of the financial-tweets dataset (1,566 of 2,388 tweets). Its recall for “bearish” is 0%.

Andes Bank (fictional) wants alerts on bearish news about its clients' holdings. The rare class is the valuable one.

  • Report macro-F1 and per-class recall, not only accuracy.
  • Start with a cheap NB/LR baseline: minutes to train, runs on a laptop, top words explain it.
  • Every later model must beat that baseline on the same test set.

Part 2

Neural generative classifiers and LLMs

Any model of \(p(x \mid y)\) can classify, including a large language model.

From counts to neural networks

Plug any density model into Bayes' rule

Model of \(p(x \mid y)\)CapturesTypical use
Naive BayesWord counts per class, independent wordsText baselines, spam filters
Gaussian discriminant analysisA Gaussian per class (shared or own covariance)Numeric features, the simulator you just used
Class-conditional LSTM / LMWord order: one language model per classSmall data, adding new classes later
VAE (S02)A latent code \(z\) that explains \(x\)Semi-supervised learning, latent features
Instruction-tuned LLMText given a prompt that describes the taskZero- and few-shot classification

Yogatama et al. (2017) found the same two regimes with neural models: generative LSTM classifiers did better with little data and when new classes arrived, discriminative LSTMs reached lower error with more data.

Back to Session 02

VAEs as classifiers: learn from unlabelled data

M1 · latent features

Train a VAE on all your data, labelled or not. Encode each example into its latent mean \(\mu(x)\) and train a small classifier on those features with the few labels you have.

Same idea as our lab's MLP on sentence embeddings: a pretrained representation plus a light head.

M2 · label as a latent variable

Make the class part of the generative model: \(p(x \mid y, z)\,p(y)\,p(z)\). For unlabelled examples, \(y\) is inferred like \(z\); a classifier \(q(y \mid x)\) is trained along the way.

Kingma, Rezende, Mohamed & Welling (2014) combined M1 + M2 for strong results with very few labels.

Unlabelled data is cheap (every past email, call transcript, headline); labels are expensive. Semi-supervised generative models turn the cheap part into accuracy.

Zero-shot by label log-likelihood

Ask the LLM how likely each label is

A verbalizer \(v(y)\) maps each class to a word: bearish, bullish, neutral. Score each label as a continuation of the prompt:

$$ s(y) = \sum_{t=1}^{|v(y)|} \log p_\theta\big(v(y)_t \mid \text{prompt}(x),\, v(y)_{<t}\big) $$

Predict \(\hat y = \arg\max_y s(y)\); a softmax over the three scores gives a confidence.

Why score instead of generate?

  • Always returns a valid label: no parsing of “Bullish!” or “It depends…”.
  • One forward pass per label (batched), no sampling, deterministic.
  • Gives a score for every class, so you can rank, set thresholds and calibrate.
  • Works with any open model where you can read the logits.

Prompt = system message + “Tweet: … Is this tweet bearish, bullish or neutral?” rendered with the model's chat template.

Simulator · multi-token labels

Sum or mean? The tokenizer gets a vote

LabelTokenslog p per token
bearishbear ish−1.90 · −0.02
bullishbull ish−2.60 · −0.02
neutralneutral−1.20

Illustrative log-probabilities. The token splits are real for the Qwen2.5 tokenizer.

Prediction: –

What can go wrong

Four traps of LLM classifiers, and their fixes

1 · Surface-form competition

“bearish”, “Bearish”, “negative” share probability mass, so the right answer can lose (Holtzman et al., 2021). Fix: fix the format in the prompt, several verbalizers per class, or PMI-style scoring.

2 · Label prior bias

Models favour some labels regardless of the input (Zhao et al., 2021). Fix: contextual calibration: subtract the scores for a content-free input such as “N/A”.

3 · Prompt sensitivity

Wording, label order and few-shot examples change results. Fix: freeze the prompt like code, version it, compare variants on a dev set.

4 · Generate-and-parse fragility

Free text needs parsing and can drift. Fix: score labels, or constrain decoding to the allowed labels or a JSON schema (many APIs offer structured outputs).

Lab preview · PyTorch

Scoring labels in a dozen lines


@torch.no_grad()
def label_scores(tweet):
    prompt = prompt_ids(tweet)                   # chat template -> token ids
    scores = []
    for label_ids in LABEL_TOKEN_IDS:            # [bear, ish], [bull, ish], [neutral]
        ids = torch.cat([prompt, torch.tensor(label_ids)])
        logp = model(input_ids=ids[None]).logits.log_softmax(-1)[0]
        # the token at position t is predicted by the logits at t - 1
        pos = torch.arange(len(prompt) - 1, len(ids) - 1)
        token_logp = logp[pos, torch.tensor(label_ids)]
        scores.append(token_logp.sum().item())   # or .mean(): length-normalised
    return scores                                # argmax -> predicted label
    

The lab batches the three labels of a tweet into one forward pass with padding.

Prompts as classifiers

Zero-shot, few-shot and verbalizers

Zero-shot

Only an instruction and the label names. Needs no labels to start; quality depends on how well the label names describe the classes.

Few-shot (in-context)

Add \(k\) labelled examples to the prompt (Brown et al., 2020). No training, longer prompts, sensitive to which examples and in what order.

Patterns + verbalizers

PET (Schick & Schütze, 2021) rewrites inputs as cloze questions, maps labels to words, then fine-tunes on few labels plus unlabelled data.

Design the verbalizer: single, common words that the model would naturally use; avoid synonyms across classes; keep them consistent between prompt and scoring.

Check · Part 2

Your zero-shot LLM labels 70% of tweets “bullish”, but only 20% are. First thing to try?

Scoring is deterministic, so temperature does nothing. A skewed label distribution is the classic symptom of prior bias; contextual calibration or a better verbalizer are cheap fixes. Tuning on the test set is leakage.

Zero labels on day one

Zero-shot is a start, not a finish

NovaTel (fictional) wants to tag customer messages into 8 new categories next week, with no labelled data.

  • Zero-shot gives a working classifier today: the prompt is the specification.
  • You still need 100–200 hand-labelled messages to measure it.
  • Those labels are also the seed of a cheaper supervised model later.

Questions before production

  • Where does the text go? An API means data leaves your perimeter.
  • Latency per message at peak volume?
  • Cost per 1,000 predictions vs a small local model?
  • Who re-validates when the model version changes?

Part 3

Synthetic data and calibration

Generative models can also write training data. And any classifier's confidence must be checked.

Synthetic data augmentation

A recipe for rare classes

  1. Seed: pick a few real examples of the rare class from the training set.
  2. Generate: ask the LLM for new, different examples (temperature ≈ 0.9, many samples).
  3. Filter: remove duplicates, near-copies of the seeds, off-format and off-label outputs.
  4. Inspect: read a sample by hand; measure diversity (for example, average similarity between examples).
  5. Train on real + synthetic; evaluate on real data only, against the real-only baseline.

Evidence: across ten classification tasks, human-labelled data matched or beat LLM-augmented data, but augmentation helped rare classes in multi-class tasks (Møller et al., 2024).

Classic alternatives: back-translation, synonym replacement, paraphrasing; see the survey by Feng et al. (2021).

Synthetic data · risks

What the generator gives, and what it hides

  • Low diversity: small models repeat the same companies and templates, so the classifier learns the template.
  • Label noise: a “bearish” request can return a bullish tweet; nobody checks unless you read them.
  • Leakage: synthetic examples in the test set inflate every metric.
  • Bias amplification: the generator's stereotypes become training data.
  • Recursion: models trained repeatedly on generated data lose the tails of the distribution (Shumailov et al., 2024).
  • Terms of use: some model licences restrict using outputs to train other models.

Seen while preparing this lab

Asked for bearish tweets, the 0.5B model also wrote:

“Apple announces strong quarterly earnings despite mixed tech sector outlook”

Off-label (bullish) and a company name repeated across samples. Filtering and reading are not optional.

Self-check · three rules

Say the rule before you flip the card

Where may synthetic examples go?
Only into the training set. Validation and test stay 100% real and untouched.
What do you compare against?
The same model trained on real data only, evaluated on the same real test set.
What must you record?
Provenance: generator model, prompt, temperature, filters and how many examples you kept.

One line in the chat

Where in your organisation is one class rare but important (fraud, churn, complaints…)?

Calibration

Does 90% confident mean 90% right?

Reliability diagram, illustrative values: an overconfident model sits below the diagonal.

Group predictions into bins by confidence; compare accuracy and confidence in each bin:

$$ \text{ECE} = \sum_{b=1}^{B} \frac{|B_b|}{n}\, \big|\, \text{acc}(B_b) - \text{conf}(B_b) \big| $$
  • Modern deep networks tend to be overconfident; temperature scaling, \(\text{softmax}(z/T)\) with \(T\) fitted on validation data, is a simple fix (Guo et al., 2017).
  • Naive Bayes pushes probabilities to 0 and 1; logistic regression is usually well calibrated (Niculescu-Mizil & Caruana, 2005).
  • Calibration changes confidences, not the ranking: accuracy stays the same.
Check · Part 3

Over 1,000 alerts the model said “bearish, 90% sure”. 700 were truly bearish. What do you conclude?

Confidence 0.90 vs accuracy 0.70 is a 20-point gap: overconfident. Any rule of the form “automate if confidence ≥ τ” (Session 06) silently breaks if confidences are not calibrated.

From confidence to operations

Calibrated scores set the human workload

Banco Andino (fictional) auto-tags news when confidence ≥ τ and sends the rest to two analysts.

  • Overconfident model → fewer items reach analysts, more silent errors.
  • Underconfident model → analysts review items the model had right.
  • Recalibrate after every model or prompt change; confidences drift.

Synthetic data meets calibration

Adding synthetic minority examples changes the class balance the model sees, so its probabilities shift too. Re-check calibration and thresholds on real validation data after augmenting.

Part 4

Choosing and shipping a classifier

Quality is one column of the decision. Cost, latency and privacy are the others.

The menu

Five classifiers, five trade-offs

OptionLabels to startSpeed on CPUMain costData stays in-houseConfidence
NB / LR on TF-IDFTens to thousandsFastestAlmost noneYesLR good, NB extreme
MLP on sentence embeddingsHundreds+Fast (small encoder)Encoder computeYesCheck it
Fine-tuned encoder (S04)ThousandsMedium; GPU helpsTraining + servingYesOften overconfident
Small local LLM, zero-shotNone (+ eval set)Slow on CPUGPU/CPU hoursYesPrior bias; calibrate
LLM via APINone (+ eval set)Network + queuePer-token billNo, by defaultProvider-dependent
Qualitative guide. Measure your own numbers: the lab's summary table reports accuracy, macro-F1, ECE and latency per model.

Simulator · monthly cost

API per token vs a self-hosted small model

API: – · Self-hosted: –

Break-even: –

All prices are inputs, not quotes: set them from a current price list and write down the date.

Implementation notes

The same MLP in PyTorch and in Keras


model = nn.Sequential(nn.Linear(384, 128), nn.ReLU(),
                      nn.Dropout(0.2), nn.Linear(128, 3))
opt = torch.optim.Adam(model.parameters(), lr=1e-3)
for epoch in range(20):
    for xb, yb in loader:
        opt.zero_grad()
        loss = F.cross_entropy(model(xb), yb)
        loss.backward()
        opt.step()
        

PyTorch: explicit loop, full control; the default for most Hugging Face models and research code.


model = keras.Sequential([
    keras.Input(shape=(384,)),
    keras.layers.Dense(128, activation="relu"),
    keras.layers.Dropout(0.2),
    keras.layers.Dense(3, activation="softmax")])
model.compile(optimizer="adam",
              loss="sparse_categorical_crossentropy")
model.fit(X, y, epochs=20, batch_size=32)
        

Keras 3: compile + fit, runs on TensorFlow, JAX or PyTorch backends; TensorFlow adds TF Lite (LiteRT) for mobile.

Apply it

Recommend a classifier under three constraints

One case per room · 6 min

  1. Budget · MercaLatam: tag 500 seller reviews a day into 12 brand-new categories by next week; no labels; one analyst; almost no budget.
  2. Latency · NovaTel: route every live-chat message to 1 of 8 queues in under 50 ms at peak; 40,000 labelled chats.
  3. Privacy · Banco Andino: classify complaints into 6 regulatory categories; text cannot leave the bank; 300 labelled examples; one on-premises GPU.

Deliver: model choice · metric you would report · one risk and its mitigation. All companies are fictional.

Rooms of 3–4. One person per room reports in 30 seconds.

Break

Stretch and come back ready to code. Tip: open the lab now so the model downloads during the break.

Hands-on

Guided lab

Four classifiers for financial tweets, from word counts to an LLM, compared on quality, calibration, latency and cost.

Lab · 60'

Lab bridge

What we will build

1NB vs logistic regression on TF-IDF, learning curve from 20 tweets to the full set18'
2PyTorch MLP on MiniLM embeddings (manual loop) + the Keras version12'
3Zero-shot with Qwen2.5-0.5B-Instruct by label log-likelihood15'
430 synthetic “bearish” tweets: retrain and compare10'
5Summary: accuracy, macro-F1, ECE, latency, cost5'

Open the notebook

Kaggle checklist: Internet on · Accelerator GPU T4 x2 recommended (CPU works; Parts 3–4 are slower).

Open in Kaggle Colab

Dataset: zeroshot/twitter-financial-news-sentiment, about 12,000 English finance tweets labelled bearish, bullish or neutral.

Session challenge

Individual, graded, 40 minutes in class. Submit by 23:59 today.

Challenge de la sesión · evaluado

Challenge S08: tu clasificador, tus restricciones

  1. Ejecución: Naive Bayes vs. regresión logística vs. LLM zero-shot con tu n_train y tu porción personal de 60 tuits.
  2. Análisis: aumento sintético para tu clase minoritaria (bajista o alcista): ¿mejoró su F1? ¿a qué costo?
  3. Explica y decide: recomienda un clasificador para tu perfil (presupuesto, latencia o privacidad).
  4. Crítica a la IA: encuentra y corrige tres fugas de datos en un código generado por IA.
  • Rúbrica: ejecución 40% · análisis 40% · reflexión y registro de IA 20%.
  • IA permitida con registro; micro-sustentaciones: si no explicas tu entrega, máximo 3.0.
  • Entrega: Archivo → Descargar notebook → e-Aulas como S08_<codigo>.ipynb, 23:59.

Wrap-up

Key takeaways

  • Generative classifiers model \(p(x \mid y)\,p(y)\); discriminative ones model \(p(y \mid x)\). Little data favours the first, lots of data the second.
  • An LLM is a generative classifier: score each label's log-likelihood instead of parsing free text, and watch token counts, wording and prior bias.
  • Synthetic data can help rare classes, only in training, always measured on real data.
  • Choose with macro-F1, calibration, latency, cost per 1,000 predictions and privacy, not accuracy alone.

Exit question

For a classification problem in your organisation: which of today's classifiers would you try first, and what evidence would make you switch?

Next session: S09 starts at 10:00 today, after a short break: use cases in real contexts (health, finance, education), value × feasibility and ROI. No pre-work in between (S09's readings were due before 7:00). After today: finish the challenge by 23:59; for the project, train your first model and compare it with your baseline.

References

Sources for this session

  • Ng, A. Y., & Jordan, M. I. (2002). On discriminative vs. generative classifiers: A comparison of logistic regression and naive Bayes. NeurIPS 14.
  • Jurafsky, D., & Martin, J. H. (2023). Speech and language processing (3rd ed. draft), ch. 4 (Naive Bayes) and ch. 5 (Logistic regression).
  • Niculescu-Mizil, A., & Caruana, R. (2005). Predicting good probabilities with supervised learning. ICML.
  • Yogatama, D., Dyer, C., Ling, W., & Blunsom, P. (2017). Generative and discriminative text classification with recurrent neural networks. arXiv:1703.01898.
  • Kingma, D. P., Rezende, D. J., Mohamed, S., & Welling, M. (2014). Semi-supervised learning with deep generative models. NeurIPS.
  • Brown, T. B., et al. (2020). Language models are few-shot learners. NeurIPS.
  • Schick, T., & Schütze, H. (2021). Exploiting cloze questions for few shot text classification and natural language inference. EACL.
  • Holtzman, A., West, P., Shwartz, V., Choi, Y., & Zettlemoyer, L. (2021). Surface form competition: Why the highest probability answer isn't always right. EMNLP.
  • Zhao, Z., Wallace, E., Feng, S., Klein, D., & Singh, S. (2021). Calibrate before use: Improving few-shot performance of language models. ICML.
  • Møller, A. G., Pera, A., Dalsgaard, J., & Aiello, L. (2024). The parrot dilemma: Human-labeled vs. LLM-augmented data in classification tasks. EACL (short papers).
  • Feng, S. Y., Gangal, V., Wei, J., Chandar, S., Vosoughi, S., Mitamura, T., & Hovy, E. (2021). A survey of data augmentation approaches for NLP. Findings of ACL.
  • Shumailov, I., et al. (2024). AI models collapse when trained on recursively generated data. Nature, 631, 755–759.
  • Guo, C., Pleiss, G., Sun, Y., & Weinberger, K. Q. (2017). On calibration of modern neural networks. ICML.
  • Gebru, T., et al. (2021). Datasheets for datasets. Communications of the ACM, 64(12), 86–92.
  • Reimers, N., & Gurevych, I. (2019). Sentence-BERT: Sentence embeddings using Siamese BERT-networks. EMNLP.
  • Malo, P., Sinha, A., Korhonen, P., Wallenius, J., & Takala, P. (2014). Good debt or bad debt: Detecting semantic orientations in economic texts. JASIST, 65(4), 782–796.
  • Yao, S., et al. (2023). ReAct: Synergizing reasoning and acting in language models. ICLR.
  • Tunstall, L., von Werra, L., & Wolf, T. (2022). Natural language processing with transformers (rev. ed.), ch. 2. O'Reilly.