我们可以使用 FastAPI 直接在 model.predict() 内部使用 Pydantic 模型(Basemodel)吗?如果不能,为什么?
Can we use Pydantic models (Basemodel) directly inside model.predict() using FastAPI, and if not ,why?
我将 Pydantic 模型 (Basemodel
) 与 FastAPI 一起使用并将输入转换为 dictionary
,然后将其转换为 Pandas DataFrame
以进行分配将其转化为机器学习预测的model.predict()
函数,如下图:
from fastapi import FastAPI
import uvicorn
from pydantic import BaseModel
import pandas as pd
from typing import List
class Inputs(BaseModel):
f1: float,
f2: float,
f3: str
@app.post('/predict')
def predict(features: List[Inputs]):
output = []
# loop the list of input features
for data in features:
result = {}
# Convert data into dict() and then into a DataFrame
data = data.dict()
df = pd.DataFrame([data])
# get predictions
prediction = classifier.predict(df)[0]
# get probability
probability = classifier.predict_proba(df).max()
# assign to dictionary
result["prediction"] = prediction
result["probability"] = probability
# append dictionary to list (many outputs)
output.append(result)
return output
它工作正常,我只是不太确定它是否优化或正确的方法,因为我将输入转换两次以获得预测。另外,我不确定在有大量输入的情况下它是否会快速工作。有什么改进吗?如果有办法(即使不是使用 Pydantic 模型,我也可以直接工作并避免进行转换和循环。
首先,您应该为 variables/objects 使用更具描述性的名称。例如:
@app.post('/predict')
def predict(inputs: List[Inputs]):
for input in inputs:
# ...
您不能将 Pydantic 模型直接传递给 predict()
函数,因为它接受数据 array
,而不是 Pydantic 模型。下面列出了可用的选项。
选项 1
您可以使用:
prediction = model.predict([[input.f1, input.f2, input.f3]])[0]
选项 2
如果您不想使用 Pandas DataFrame,如您的问题所示,即
df = pd.DataFrame([input.dict()])
prediction = model.predict(df)[0]
然后,您可以使用 __dict__
方法获取模型中所有属性的值并将其转换为 list
:
prediction = model.predict([list(input.__dict__.values())])[0]
或者,最好使用 Pydantic 的 .dict()
方法:
prediction = model.predict([list(input.dict().values())])[0]
选项 3
您可以避免遍历单个项目并多次调用 predict()
函数,而是使用以下代码:
import pandas as pd
df = pd.DataFrame([i.dict() for i in inputs])
prediction = model.predict(df)
probability = model.predict_proba(df)
return {'prediction': prediction.tolist(), 'probability': probability.tolist()}
或(如果您不想使用 Pandas DataFrame):
inputs_list = [list(i.dict().values()) for i in inputs]
prediction = model.predict(inputs_list)
probability = model.predict_proba(inputs_list)
return {'prediction': prediction.tolist(), 'probability': probability.tolist()}
我将 Pydantic 模型 (Basemodel
) 与 FastAPI 一起使用并将输入转换为 dictionary
,然后将其转换为 Pandas DataFrame
以进行分配将其转化为机器学习预测的model.predict()
函数,如下图:
from fastapi import FastAPI
import uvicorn
from pydantic import BaseModel
import pandas as pd
from typing import List
class Inputs(BaseModel):
f1: float,
f2: float,
f3: str
@app.post('/predict')
def predict(features: List[Inputs]):
output = []
# loop the list of input features
for data in features:
result = {}
# Convert data into dict() and then into a DataFrame
data = data.dict()
df = pd.DataFrame([data])
# get predictions
prediction = classifier.predict(df)[0]
# get probability
probability = classifier.predict_proba(df).max()
# assign to dictionary
result["prediction"] = prediction
result["probability"] = probability
# append dictionary to list (many outputs)
output.append(result)
return output
它工作正常,我只是不太确定它是否优化或正确的方法,因为我将输入转换两次以获得预测。另外,我不确定在有大量输入的情况下它是否会快速工作。有什么改进吗?如果有办法(即使不是使用 Pydantic 模型,我也可以直接工作并避免进行转换和循环。
首先,您应该为 variables/objects 使用更具描述性的名称。例如:
@app.post('/predict')
def predict(inputs: List[Inputs]):
for input in inputs:
# ...
您不能将 Pydantic 模型直接传递给 predict()
函数,因为它接受数据 array
,而不是 Pydantic 模型。下面列出了可用的选项。
选项 1
您可以使用:
prediction = model.predict([[input.f1, input.f2, input.f3]])[0]
选项 2
如果您不想使用 Pandas DataFrame,如您的问题所示,即
df = pd.DataFrame([input.dict()])
prediction = model.predict(df)[0]
然后,您可以使用 __dict__
方法获取模型中所有属性的值并将其转换为 list
:
prediction = model.predict([list(input.__dict__.values())])[0]
或者,最好使用 Pydantic 的 .dict()
方法:
prediction = model.predict([list(input.dict().values())])[0]
选项 3
您可以避免遍历单个项目并多次调用 predict()
函数,而是使用以下代码:
import pandas as pd
df = pd.DataFrame([i.dict() for i in inputs])
prediction = model.predict(df)
probability = model.predict_proba(df)
return {'prediction': prediction.tolist(), 'probability': probability.tolist()}
或(如果您不想使用 Pandas DataFrame):
inputs_list = [list(i.dict().values()) for i in inputs]
prediction = model.predict(inputs_list)
probability = model.predict_proba(inputs_list)
return {'prediction': prediction.tolist(), 'probability': probability.tolist()}