Spaces:
Sleeping
Sleeping
Sylvester107
commited on
Commit
·
2bb6eb6
1
Parent(s):
7e3908b
init
Browse files- Dockerfile +18 -0
- requirements.txt +0 -0
- src/__pycache__/API.cpython-39.pyc +0 -0
- src/__pycache__/Sepsis_API.cpython-39.pyc +0 -0
- src/__pycache__/app.cpython-39.pyc +0 -0
- src/__pycache__/main.cpython-39.pyc +0 -0
- src/gradient_boosting_model.pkl +3 -0
- src/main.py +161 -0
Dockerfile
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#
|
2 |
+
FROM python:3.9
|
3 |
+
|
4 |
+
#
|
5 |
+
WORKDIR /code
|
6 |
+
|
7 |
+
#
|
8 |
+
COPY ./requirements.txt /code/requirements.txt
|
9 |
+
|
10 |
+
#
|
11 |
+
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
|
12 |
+
|
13 |
+
#
|
14 |
+
COPY ./src /code/src
|
15 |
+
|
16 |
+
|
17 |
+
#
|
18 |
+
CMD ["python", "src/main.py","--host", "0.0.0.0", "--port", "7860"]
|
requirements.txt
ADDED
Binary file (1.64 kB). View file
|
|
src/__pycache__/API.cpython-39.pyc
ADDED
Binary file (524 Bytes). View file
|
|
src/__pycache__/Sepsis_API.cpython-39.pyc
ADDED
Binary file (1.45 kB). View file
|
|
src/__pycache__/app.cpython-39.pyc
ADDED
Binary file (635 Bytes). View file
|
|
src/__pycache__/main.cpython-39.pyc
ADDED
Binary file (4.39 kB). View file
|
|
src/gradient_boosting_model.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:11bc712d26e3044165144ece900b92eed6eb41f80396f3ce7d53704133400684
|
3 |
+
size 1089788
|
src/main.py
ADDED
@@ -0,0 +1,161 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import FastAPI # Import the FastAPI framework for building APIs
|
2 |
+
from typing import List, Literal # Import typing hints for function annotations
|
3 |
+
from pydantic import BaseModel # Import BaseModel for creating data models
|
4 |
+
import uvicorn # Import uvicorn for running the FastAPI app
|
5 |
+
import pandas as pd # Import pandas library for data manipulation
|
6 |
+
import pickle, os # Import pickle and os modules for handling files and data serialization
|
7 |
+
|
8 |
+
# Define a function to load machine learning components
|
9 |
+
def load_ml_components(fp):
|
10 |
+
'''Load machine learning to re-use in app '''
|
11 |
+
with open(fp, 'rb') as f:
|
12 |
+
object = pickle.load(f) # Load a pickled object (machine learning model)
|
13 |
+
return object # Return the loaded object
|
14 |
+
|
15 |
+
# Define a Pydantic model for the input data
|
16 |
+
class Sepsis(BaseModel):
|
17 |
+
"""
|
18 |
+
Represents the input data for the model prediction.
|
19 |
+
|
20 |
+
Attributes:
|
21 |
+
PlasmaGlucose (int): The plasma glucose level of the individual.
|
22 |
+
BloodWorkResult_1 (int): The result of blood work test 1.
|
23 |
+
BloodPressure (int): The blood pressure reading of the individual.
|
24 |
+
BloodWorkResult_2 (int): The result of blood work test 2.
|
25 |
+
BloodWorkResult_3 (int): The result of blood work test 3.
|
26 |
+
BodyMassIndex (float): The body mass index of the individual.
|
27 |
+
BloodWorkResult_4 (float): The result of blood work test 4.
|
28 |
+
Age (int): The age of the individual.
|
29 |
+
|
30 |
+
'sepsis' is the target feature which holds 0 = Negative and 1 = Positive.
|
31 |
+
"""
|
32 |
+
# Define the input features as class attributes
|
33 |
+
|
34 |
+
PlasmaGlucose : int
|
35 |
+
BloodWorkResult_1 : int
|
36 |
+
BloodPressure : int
|
37 |
+
BloodWorkResult_2 : int
|
38 |
+
BloodWorkResult_3 : int
|
39 |
+
BodyMassIndex : float
|
40 |
+
BloodWorkResult_4 : float
|
41 |
+
Age : int
|
42 |
+
|
43 |
+
# Setup
|
44 |
+
"""
|
45 |
+
Get the absolute path of the current model file.
|
46 |
+
then extracts the directory path from the absolute path of the model file.
|
47 |
+
This is useful when we need to locate the file
|
48 |
+
relative to our script's location.
|
49 |
+
"""
|
50 |
+
# Get the absolute path of the current directory
|
51 |
+
DIRPATH = os.path.dirname(os.path.realpath(__file__))
|
52 |
+
|
53 |
+
# Join the directory path with the model file name
|
54 |
+
ml_core_fp = os.path.join(DIRPATH, 'gradient_boosting_model.pkl')
|
55 |
+
|
56 |
+
# Define the labels manually
|
57 |
+
labels = ['Negative', 'Positive']
|
58 |
+
|
59 |
+
# Load the machine learning components
|
60 |
+
end2end_pipeline = load_ml_components(fp=ml_core_fp) # Load the machine learning model from the file
|
61 |
+
|
62 |
+
# Access the model step of the pipeline
|
63 |
+
model = end2end_pipeline.named_steps['model'] # Access the model component from the pipeline
|
64 |
+
|
65 |
+
# Create a dictionary to map index to labels
|
66 |
+
idx_to_labels = {i: l for (i, l) in enumerate(labels)}
|
67 |
+
|
68 |
+
# Print predictable labels and index-to-label mapping
|
69 |
+
print(f'\n[Info]Predictable labels: {labels}')
|
70 |
+
print(f'\n[Info]Indices to labels: {idx_to_labels}')
|
71 |
+
|
72 |
+
# Print information about the loaded model
|
73 |
+
print(f'\n[Info]ML components loaded - Model: {model}')
|
74 |
+
|
75 |
+
# Create the FastAPI application instance
|
76 |
+
app = FastAPI(title='Sepsis Prediction API') # Create a FastAPI instance with a title
|
77 |
+
|
78 |
+
# Define a route to handle the root endpoint
|
79 |
+
@app.get('/')
|
80 |
+
def root():
|
81 |
+
return{
|
82 |
+
"info" : "Sepsis Prediction API: This interface is about the prediction of sepsis disease of patients in ICU."
|
83 |
+
}
|
84 |
+
|
85 |
+
|
86 |
+
# Define a route to handle the prediction
|
87 |
+
@app.post('/classify')
|
88 |
+
def sepsis_classification(PlasmaGlucose : int,
|
89 |
+
BloodWorkResult_1 : int,
|
90 |
+
BloodPressure : int,
|
91 |
+
BloodWorkResult_2 : int,
|
92 |
+
BloodWorkResult_3 : int,
|
93 |
+
BodyMassIndex : float,
|
94 |
+
BloodWorkResult_4 : float,
|
95 |
+
Age : int):
|
96 |
+
# Define checkmarks for printing symbols
|
97 |
+
red_x = u"\u274C"
|
98 |
+
green_checkmark = "\033[32m" + u"\u2713" + "\033[0m" #u"\u2713"
|
99 |
+
|
100 |
+
try:
|
101 |
+
# # Create a dataframe from the input data, to solve the indexing issue, wrapp dict in a list
|
102 |
+
df = pd.DataFrame(
|
103 |
+
[ {
|
104 |
+
'PlasmaGlucose': PlasmaGlucose,
|
105 |
+
'BloodWorkResult_1(U/ml)': BloodWorkResult_1,
|
106 |
+
'BloodPressure(mm Hg)': BloodPressure,
|
107 |
+
'BloodWorkResult_2(mm)': BloodWorkResult_2,
|
108 |
+
'BloodWorkResult_3(U/ml)': BloodWorkResult_3,
|
109 |
+
'BodyMassIndex(kg/m)^2': BodyMassIndex,
|
110 |
+
'BloodWorkResult_4(U/ml)':BloodWorkResult_4,
|
111 |
+
'Age (years)':Age} ]
|
112 |
+
)
|
113 |
+
# Print input data as a dataframe
|
114 |
+
print(f'[Info]Input data as dataframe:\n{df.to_markdown()}')
|
115 |
+
|
116 |
+
# Predict using the loaded model
|
117 |
+
output = model.predict(df)
|
118 |
+
confidence_scores = model.predict_proba(df) # Predict the probabilities for each class
|
119 |
+
print(f'Considering the best confidence score, the output is: {output}')
|
120 |
+
print(f'Confidence scores: {confidence_scores}')
|
121 |
+
|
122 |
+
# Get index of predicted class
|
123 |
+
predicted_idx = output
|
124 |
+
|
125 |
+
# Store index then replace by the matching label
|
126 |
+
df['Predicted label'] = predicted_idx
|
127 |
+
predicted_label = df['Predicted label'].replace(idx_to_labels)
|
128 |
+
df['Predicted label'] = predicted_label
|
129 |
+
|
130 |
+
# Map predicted indices to labels
|
131 |
+
predicted_labels = [idx_to_labels[idx] for idx in output]
|
132 |
+
|
133 |
+
# Store the predicted probabilities for each class in the dataframe
|
134 |
+
for i, label in enumerate(labels):
|
135 |
+
df[f'Confidence_{label}'] = confidence_scores[:, i] * 100 # Convert to percentage
|
136 |
+
|
137 |
+
# Print the result with confidence scores as percentages
|
138 |
+
if predicted_labels:
|
139 |
+
i = 0
|
140 |
+
label = predicted_labels[0] # Get the first predicted label
|
141 |
+
confidence_score_percentage = max(confidence_scores[i]) * 100
|
142 |
+
print(f"{green_checkmark} This patient in ICU has been classified as Sepsis {label} with confidence of: {confidence_score_percentage:.1f}%")
|
143 |
+
|
144 |
+
msg = "Execution went fine"
|
145 |
+
code = 1
|
146 |
+
pred = df.to_dict("records")
|
147 |
+
|
148 |
+
|
149 |
+
except Exception as e:
|
150 |
+
print(f"\033[91m{red_x} An exception occurred: {str(e)}")
|
151 |
+
msg = "Execution did not go well"
|
152 |
+
code = 0
|
153 |
+
pred = None
|
154 |
+
|
155 |
+
# Create the API response
|
156 |
+
result = {"Execution_msg": msg, "execution_code": code, "prediction": pred}
|
157 |
+
return result
|
158 |
+
|
159 |
+
# Run the FastAPI application using uvicorn
|
160 |
+
if __name__ == "__main__":
|
161 |
+
uvicorn.run("main:app", reload = True)
|