[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?
维护者通常 2 天内回复
评估
- 难度
- 1/5
- 预计耗时
- 1 小时以内
- 新手友好度
- 72/100
- Issue 类型
- 文档
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- python, scikit-learn
调研方向
阅读 machine-learning-zoomcamp 作业解答中的 FAQ 答案以及链接的 predict.py 上下文。Issue 已经解释了验证行为,并展示了一个单独的请求模型示例。检查说明和示例是否与链接的可运行版本一致。完成标准是 FAQ 清楚地区分已评分作业的行为与实验,并说明哪些无效输入会返回 422。
由索引模型根据 Issue 内容生成。
描述
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:
DictVectorizerone-hot encodes only thefeature=valuepairs it saw duringfit."Paid_Ads"and"tiktok"match no column, so the wholelead_sourceblock becomes zeros, and both get the same score.- Pydantic checks that
annual_incomeis a float and thatinteraction_countis an int. WithoutFieldconstraints, any float or int passes. Only2.5fails, 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
- 主要语言
- Python
- 星标
- 8
- 派生
- 20
- 平均合并
- 7 天 9 小时
- 30 天内合并 PR
- 8
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
DataTalksClub/faq 的其他 Issue
-
Fixing ValueError: feature_names must not contain [, ], or < in XGBoost可能已有人在做 @github-actions 于 1 天前认领。 未关闭faq-proposal
难度 2/5 1-3 小时 新手友好度 68/100
DataTalksClub/faq#536 · 1 条评论 ·
维护者通常 2 天内回复
-
How to fix uv warning: VIRTUAL_ENV does not match the project environment path可能已有人在做 @github-actions 于 1 天前认领。 未关闭faq-proposal
难度 1/5 1 小时以内 新手友好度 82/100
DataTalksClub/faq#534 · 1 条评论 ·
维护者通常 2 天内回复
-
Fixing ValueError: This solver needs samples of at least 2 classes in Logistic Regression可能已有人在做 @github-actions 于 1 天前认领。 未关闭faq-proposal
难度 2/5 1-3 小时 新手友好度 62/100
DataTalksClub/faq#532 · 1 条评论 ·
维护者通常 2 天内回复
-
难度 2/5 1-3 小时 新手友好度 60/100
DataTalksClub/faq#531 ·
维护者通常 2 天内回复
-
[FAQ]可能已有人在做 @github-actions 于 4 天前认领。 未关闭faq-proposal
难度 1/5 1 小时以内 新手友好度 85/100
DataTalksClub/faq#521 · 1 条评论 ·
维护者通常 2 天内回复
查看 DataTalksClub/faq 的全部 Issue
相似的 Issue
-
PluginProvider.storeInstance races and clobbers the dedup cache for concurrent loads可能已有人在做 @Wilson0511 今天认领。 未关闭needs-triage
难度 2/5 1-3 小时 新手友好度 62/100
维护者通常 2 天内回复
-
community documentation good first issue
难度 2/5 1-3 小时 新手友好度 75/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
-
bug(sdk): add_toleration_json silently drops camelCase tolerationSeconds for static dict/list input可能已有人在做 @ravikumar266 今天认领。 未关闭area/sdk kind/bug
难度 2/5 1-3 小时 新手友好度 75/100
kubeflow/pipelines#15347 · 3 条评论 ·
维护者通常 1 天内回复
-
predict_file with crop_model duplicates predictions once per image可能已有人在做 关联的 PR 仍在进行中或已合并。 未关闭
难度 2/5 1-3 小时 新手友好度 62/100
weecology/DeepForest#1445 ·