Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

[FAQ] omework 5 (2026): Why does `/predict` return 200 OK for `"Paid_Ads"`, `"tiktok"` or a negative count, and how do I reject bad input?

Aperta Adatta ai principianti
#524 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 2 giorni

@github-actions ci sta già lavorando.

Dal 29/10/2026.

  • #525 di @github-actions — aperta

Valutazione

Difficoltà
1/5
Tempo stimato
Meno di un'ora
Idoneità per principianti
72/100
Tipo di issue
Documentazione
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
python, scikit-learn

Direzione di ricerca

Leggi la risposta nelle FAQ e il contesto collegato di predict.py nella soluzione dei compiti di machine-learning-zoomcamp. L’issue spiega già il comportamento della validazione e mostra un esempio separato di modello di richiesta. Controlla che la spiegazione e gli esempi corrispondano alla versione funzionante collegata. Il lavoro è terminato quando le FAQ distinguono chiaramente il comportamento dei compiti valutati dagli esperimenti e spiegano quali input non validi restituiscono 422.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

faq-proposal
Course

machine-learning-zoomcamp

Question

Homework 5 (2026): I sent "lead_source": "Paid_Ads" (capital letters) to the API and got HTTP 200 with a different probability than for "paid_ads". "tiktok", "interaction_count": -3 and an income typo of 7927600 also return 200. Shouldn't the API reject these?

Answer

The course API validates types, not values, and DictVectorizer silently ignores categories it didn't see in training. Your graded answers are unaffected: the homework leads are all valid. In a real service, though, these mistakes go unnoticed.

What happens with the Q3 lead (/predict from the provided predict.py):

change status probability
none 200 0.533
lead_source: "Paid_Ads" 200 0.553
lead_source: "tiktok" 200 0.553
annual_income: 7927600 (×100 typo) 200 0.000
interaction_count: -3 200 0.167
number_of_courses_viewed: 2.5 422 —

Why:

  • DictVectorizer one-hot encodes only the feature=value pairs it saw during fit. "Paid_Ads" and "tiktok" match no column, so the whole lead_source block becomes zeros, and both get the same score.
  • Pydantic checks that annual_income is a float and that interaction_count is an int. Without Field constraints, any float or int passes. Only 2.5 fails, because it isn't a valid int.
  • Income isn't scaled, so a ×100 typo multiplies a −1.2e-5 weight by about 8 million and pushes the probability to 0.

**Fix: validate values in the request model. Read the allowed categories from the model itself so they can't drift:

from typing import Literal, Optional
from pydantic import BaseModel, Field, create_model, field_validator

def vocabulary(feature):
    names = pipeline.steps[0][1].get_feature_names_out()
    return tuple(n.split("=", 1)[1] for n in names
                 if n.startswith(f"{feature}=") and not n.endswith("=NA"))

class Numbers(BaseModel):
    number_of_courses_viewed: Optional[int] = Field(None, ge=0)
    annual_income: Optional[float] = Field(None, ge=0, lt=1_000_000)
    interaction_count: Optional[int] = Field(None, ge=0)
    lead_score: Optional[float] = Field(None, ge=0, le=1)

    @field_validator("lead_source", "industry", "employment_status", "location",
                     mode="before", check_fields=False)
    @classmethod
    def clean(cls, v):  # "Paid_Ads" -> "paid_ads", "North America" -> "north_america"
        if isinstance(v, str):
            return v.strip().lower().replace(" ", "_") or None
        return v

Lead = create_model("Lead", __base__=Numbers, {
    f: (Optional[Literal[vocabulary(f)]], None)
    for f in ["lead_source", "industry", "employment_status", "location"]})

Now "Paid_Ads" scores the same as "paid_ads" (0.533). "tiktok", negative counts, the income typo and lead_score: 4.1 return 422 with a clear message, and missing fields still fall back to the training medians. Add model_config = ConfigDict(extra="forbid") to reject misspelled field names such as leadscore too.

Don't change the provided predict.py for the graded Q4/Q6 runs. Use a separate app for experiments.

Full working version with 23 tests: https://github.com/devotuoma/machine-learning-zoomcamp/tree/hw05-deployment/cohorts/2026/homework/05-deployment/solution

Checklist
  • I have searched existing FAQs and this question is not already answered
  • The answer provides accurate, helpful information
  • I have included any relevant code examples or links
Lingua principale
Python
Stelle
7
Fork
20
Merge medio
7g 9h
PR unite (30g)
8

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di DataTalksClub/faq

Tutte le issue di DataTalksClub/faq

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.