趋近智
机器学习模型处理输入数据并生成预测后,请求-响应周期的最后一步是将这些结果发送回客户端。您如何构建此响应对于易用性以及与后续应用的集成很重要。仅仅返回原始数字或字符串通常是不够的。客户端通常会从一个定义良好的JSON对象中受益,该对象包含预测结果以及其他可能的相关信息,如置信度分数或概率。
FastAPI 结合 Pydantic,使得使用响应模型来定义和执行这些响应结构变得直接简单。
让我们从一个基本情况开始:一个预测单个类别标签的分类模型。虽然您可以只返回标签作为字符串,但更好的做法是将其封装在一个 JSON 对象中。这能提供上下文,并使 API 响应更具自我描述性。
我们可以定义一个 Pydantic 模型来表示这种结构:
from pydantic import BaseModel, Field
class PredictionResponse(BaseModel):
predicted_class: str = Field(..., description="预测的类别标签。")
# 之后您可能还会添加其他字段,例如请求 ID 或模型版本
在您的端点中,您将在路径操作装饰器的 response_model 参数中使用此模型。FastAPI 会自动处理将返回值(例如字典或另一个 Pydantic 模型实例)序列化为符合 PredictionResponse 格式的 JSON。
# 假设 'model' 是您已加载的机器学习模型对象
# 假设 'InputFeatures' 是您的 Pydantic 输入模型
@app.post("/predict", response_model=PredictionResponse)
async def make_prediction(features: InputFeatures):
# 1. 如有必要,对特征进行预处理
processed_data = preprocess(features.dict()) # 预处理示例
# 2. 从模型获取预测结果
# 假设 model.predict() 直接返回类别标签
prediction_label = model.predict(processed_data)
# 3. 返回符合响应模型的结果
return PredictionResponse(predicted_class=prediction_label)
这种方式确保响应格式一致,并自动将其包含在 FastAPI 生成的 API 文档中。
对于许多分类任务,了解模型对其预测结果的置信度与预测结果本身同样重要。大多数分类模型可以输出每个可能类别的概率。例如,scikit-learn 分类器通常有一个 predict_proba() 方法,该方法返回一个包含每个类别概率的数组。
返回这些概率能为客户端提供有用的背景信息。他们可以使用此信息来设置决策阈值,或识别需要人工审查的不确定预测。
为了包含概率,我们扩展了 Pydantic 响应模型:
from pydantic import BaseModel, Field
from typing import List, Dict
class ProbabilityResponse(BaseModel):
predicted_class: str = Field(..., description="预测的类别标签。")
probabilities: Dict[str, float] = Field(..., description="一个字典,将类别标签映射到其预测概率。")
# 示例: {"cat": 0.95, "dog": 0.04, "other": 0.01}
@app.post("/predict_proba", response_model=ProbabilityResponse)
async def make_prediction_with_proba(features: InputFeatures):
processed_data = preprocess(features.dict())
# 假设 model.predict() 提供标签
prediction_label = model.predict(processed_data)
# 假设 model.predict_proba() 提供每个类别的概率
# 并且 model.classes_ 提供类别的顺序
proba_values = model.predict_proba(processed_data)[0] # 获取第一个(也是唯一一个)输入样本的概率
class_labels = model.classes_
probabilities_dict = {label: proba for label, proba in zip(class_labels, proba_values)}
# 排序概率以便于阅读(可选)
sorted_probabilities = dict(sorted(probabilities_dict.items(), key=lambda item: item[1], reverse=True))
return ProbabilityResponse(
predicted_class=prediction_label,
probabilities=sorted_probabilities
)
在此示例中,ProbabilityResponse 定义了一个结构,其中包含最可能的类别(predicted_class)以及一个字典(probabilities),该字典包含与每个可能类别相关的概率。端点从模型中获取预测结果和概率,并根据此结构进行打包。
这些概率的可视化表示有时有助于理解模型的置信度分布。
单个输入实例在不同类别上的预测概率分布示例。类别 A 具有最高概率。
您的响应模型结构应自然地反映您的特定机器学习模型的输出:
predicted_value(浮点数)而不是 predicted_class 和 probabilities,并且可能包含一个 confidence_interval(例如,一个包含 lower_bound 和 upper_bound 的字典)。核心思路保持不变:定义一个 Pydantic 模型,精确描述预期的输出格式,并在端点装饰器的 response_model 参数中使用它。这为您的 API 使用者提供了清晰的约定,并使用了 FastAPI 的验证和文档功能。
请记住,在返回浮点数(如概率)时,要考虑数值精度。您可能希望在返回响应之前,在端点逻辑中将它们四舍五入到合理的 H 位小数。此外,确保您的端点在预测过程中优雅地处理潜在错误,或许返回特定的 HTTP 错误代码和消息,而不是标准的预测响应。
这部分内容有帮助吗?
response_model 参数,以利用 Pydantic 模型定义和验证 API 响应结构。BaseModel 定义数据模型、字段和验证逻辑的全面指南,这是构建 FastAPI 响应的核心。predict 和 predict_proba,用于从机器学习模型获取类别标签和概率估计。© 2026 ApX Machine Learning用心打造