Jacob Jaroya
post update
74c9228
raw
history blame contribute delete
No virus
6.41 kB
from fastapi import FastAPI # Import the FastAPI framework for building APIs
from typing import List, Literal # Import typing hints for function annotations
from pydantic import BaseModel # Import BaseModel for creating data models
import uvicorn # Import uvicorn for running the FastAPI app
import pandas as pd # Import pandas library for data manipulation
import pickle, os # Import pickle and os modules for handling files and data serialization
# Define a function to load machine learning components
def load_ml_components(fp):
'''Load machine learning to re-use in app '''
with open(fp, 'rb') as f:
object = pickle.load(f) # Load a pickled object (machine learning model)
return object # Return the loaded object
# Define a Pydantic model for the input data
class Sepsis(BaseModel):
"""
Represents the input data for the model prediction.
Attributes:
PlasmaGlucose (int): The plasma glucose level of the individual.
BloodWorkResult_1 (int): The result of blood work test 1.
BloodPressure (int): The blood pressure reading of the individual.
BloodWorkResult_2 (int): The result of blood work test 2.
BloodWorkResult_3 (int): The result of blood work test 3.
BodyMassIndex (float): The body mass index of the individual.
BloodWorkResult_4 (float): The result of blood work test 4.
Age (int): The age of the individual.
'sepsis' is the target feature which holds 0 = Negative and 1 = Positive.
"""
# Define the input features as class attributes
PlasmaGlucose : int
BloodWorkResult_1 : int
BloodPressure : int
BloodWorkResult_2 : int
BloodWorkResult_3 : int
BodyMassIndex : float
BloodWorkResult_4 : float
Age : int
# Setup
"""
Get the absolute path of the current model file.
then extracts the directory path from the absolute path of the model file.
This is useful when we need to locate the file
relative to our script's location.
"""
# Get the absolute path of the current directory
DIRPATH = os.path.dirname(os.path.realpath(__file__))
# Join the directory path with the model file name
ml_core_fp = os.path.join(DIRPATH, 'gradient_boosting_model.pkl')
# Define the labels manually
labels = ['Negative', 'Positive']
# Load the machine learning components
end2end_pipeline = load_ml_components(fp=ml_core_fp) # Load the machine learning model from the file
# Access the model step of the pipeline
model = end2end_pipeline.named_steps['model'] # Access the model component from the pipeline
# Create a dictionary to map index to labels
idx_to_labels = {i: l for (i, l) in enumerate(labels)}
# Print predictable labels and index-to-label mapping
print(f'\n[Info]Predictable labels: {labels}')
print(f'\n[Info]Indices to labels: {idx_to_labels}')
# Print information about the loaded model
print(f'\n[Info]ML components loaded - Model: {model}')
# Create the FastAPI application instance
app = FastAPI(title='Sepsis Prediction API') # Create a FastAPI instance with a title
# Define a route to handle the root endpoint
@app.get('/')
def root():
return{
"info" : "Sepsis Prediction API: This interface is about the prediction of sepsis disease of patients in ICU."
}
# Define a route to handle the prediction
@app.post('/spaces/UholoDala/sepsis_classic/classify')
def sepsis_classification(PlasmaGlucose : int,
BloodWorkResult_1 : int,
BloodPressure : int,
BloodWorkResult_2 : int,
BloodWorkResult_3 : int,
BodyMassIndex : float,
BloodWorkResult_4 : float,
Age : int):
# Define checkmarks for printing symbols
red_x = u"\u274C"
green_checkmark = "\033[32m" + u"\u2713" + "\033[0m" #u"\u2713"
try:
# # Create a dataframe from the input data, to solve the indexing issue, wrapp dict in a list
df = pd.DataFrame(
[ {
'PlasmaGlucose': PlasmaGlucose,
'BloodWorkResult_1(U/ml)': BloodWorkResult_1,
'BloodPressure(mm Hg)': BloodPressure,
'BloodWorkResult_2(mm)': BloodWorkResult_2,
'BloodWorkResult_3(U/ml)': BloodWorkResult_3,
'BodyMassIndex(kg/m)^2': BodyMassIndex,
'BloodWorkResult_4(U/ml)':BloodWorkResult_4,
'Age (years)':Age} ]
)
# Print input data as a dataframe
print(f'[Info]Input data as dataframe:\n{df.to_markdown()}')
# Predict using the loaded model
output = model.predict(df)
confidence_scores = model.predict_proba(df) # Predict the probabilities for each class
print(f'Considering the best confidence score, the output is: {output}')
print(f'Confidence scores: {confidence_scores}')
# Get index of predicted class
predicted_idx = output
# Store index then replace by the matching label
df['Predicted label'] = predicted_idx
predicted_label = df['Predicted label'].replace(idx_to_labels)
df['Predicted label'] = predicted_label
# Map predicted indices to labels
predicted_labels = [idx_to_labels[idx] for idx in output]
# Store the predicted probabilities for each class in the dataframe
for i, label in enumerate(labels):
df[f'Confidence_{label}'] = confidence_scores[:, i] * 100 # Convert to percentage
# Print the result with confidence scores as percentages
if predicted_labels:
i = 0
label = predicted_labels[0] # Get the first predicted label
confidence_score_percentage = max(confidence_scores[i]) * 100
print(f"{green_checkmark} This patient in ICU has been classified as Sepsis {label} with confidence of: {confidence_score_percentage:.1f}%")
msg = "Execution went fine"
code = 1
pred = df.to_dict("records")
except Exception as e:
print(f"\033[91m{red_x} An exception occurred: {str(e)}")
msg = "Execution did not go well"
code = 0
pred = None
# Create the API response
result = {"Execution_msg": msg, "execution_code": code, "prediction": pred}
return result
# Run the FastAPI application using uvicorn
if __name__ == "__main__":
uvicorn.run("main:app", host = "0.0.0.0", port = 8000, reload = True)