1

I am currently building an API using FastAPI to deploy my logistic regression model. For some reason, I am getting the above error in the server docs when I test the model.

My code below:

app = FastAPI()

class PatientAttendance(BaseModel):
    apptslotduration: int
    patientage: int
    log_distance: float
    pct_appts_missed: float
    doc_no_show_rate: float
    zip_no_show_rate: float
    note_no_show_rate: float
    type_no_show_rate: float
    spec_type_no_show_rate: float
    monthly_no_show_rate: float
    seasonal_no_show_rate: float
    dow_no_show_rate: float
    clinic_no_show_rate: float
    lead_time_in_days: int
    groupedstarttime: int
    priminsurance_no_show_rate: float
    secondinsurance_no_show_rate: float

@app.post('/predict/')
def predict(features: PatientAttendance):
    data = features
    prediction = model.predict([[data]])
    if prediction[0] == 0:
        result = "Patient Show"
    else:
        result = "No-Show"
    probability = model.predict_proba([[data]])

    return {
        'prediction': prediction,
        'probability': probability
    }

if __name__ == '__main__':
    uvicorn.run(app, host="127.0.0.1", port=8000)

The error:

TypeError: float() argument must be a string or a number, not 'PatientAttendance'

I am using a Pydantic BaseModel and I have no idea why I am receiving this error. I believe I have the app pointing in the right direction with respect to the server. I've tried utilizing GET & POST. features is the array of features in my dataset that I standardized and turned into a dictionary. All the features have been vectorized. I always seem to get some type of error whenever I test my API in the server docs.

Chris
  • 18,724
  • 6
  • 46
  • 80
Leo Luna
  • 11
  • 1
  • You're sending the pydantic basemodel directly into your `predict` function - does that even accept pydantic models directly? – MatsLindh Mar 24 '22 at 21:08
  • Yes I believe so. I don't think the problem is with `PatientAttendance`; I'm pretty sure the issue has to do with the `def predict(features:` portion. – Leo Luna Mar 24 '22 at 21:20
  • The error should have a line number attached, so you can tell exactly where the problem occurs - include that in your question. What is your `model` variable initialized as? If it's a sklearn model, there doesn't seem to be any method (`predict` or `predict_proba`) that expects a pydantic model nested inside two lists. – MatsLindh Mar 24 '22 at 23:04

1 Answers1

0

Option 1

# Getting prediction
prediction = model.predict([[data.apptslotduration, data.patientage, data.pct_appts_missed, data.doc_no_show_rate, ...]])[0]

# Getting probability
probability = model.predict_proba([[data.apptslotduration, data.patientage, data.pct_appts_missed, data.doc_no_show_rate, ...]])

Option 2

Use the __dict__ method to get the values of all attributes in the model:

# Getting prediction
prediction = model.predict([list(data.__dict__.values())])[0]

# Getting probability
probability = model.predict_proba([list(data.__dict__.values())])

or (better) use the Pydantic's .dict() method:

# Getting prediction
prediction = model.predict([list(data.dict().values())])[0]

# Getting probability
probability = model.predict_proba([list(data.dict().values())])

Option 3

Convert the input data (from the Pydantic model) into a dictionray using the dict() method, and then into a Pandas dataframe:

import pandas as pd

# Converting input data into Pandas DataFrame
df = pd.DataFrame([features.dict()])

# Getting prediction
prediction = model.predict(df)[0]

# Getting probability
probability = model.predict_proba(df)

More Options

In case you have a list of inputs, have a look at this answer (Option 3).

Chris
  • 18,724
  • 6
  • 46
  • 80