A first approach to MLOps using Titan

Titan Tutorial #9: Integrating and consuming services in a healthcare use case

Introduction

The model

SVM Visualization
id: ID numberdiagnosis: The diagnosis of breast tissues (M = malignant, B = benign)radius_mean: mean of distances from center to points on the perimetertexture_mean: standard deviation of gray-scale valuesperimeter_mean: mean size of the core tumorarea_meansmoothness_mean: mean of local variation in radius lengthscompactness_mean: mean of perimeter^2 / area - 1.0concavity_mean: mean of severity of concave portions of the contourconcave points_mean: mean for number of concave portions of the contoursymmetry_meanfractal_dimension_mean: mean for "coastline approximation" - 1radius_se: standard error for the mean of distances from center to points on the perimetertexture_se: standard error for standard deviation of gray-scale valuesperimeter_searea_sesmoothness_se: standard error for local variation in radius lengthscompactness_se: standard error for perimeter^2 / area - 1.0concavity_se: standard error for severity of concave portions of the contourconcave points_se: standard error for number of concave portions of the contoursymmetry_sefractal_dimension_se: standard error for "coastline approximation" - 1radius_worst: "worst" or largest mean value for mean of distances from center to points on the perimetertexture_worst: "worst" or largest mean value for standard deviation of gray-scale valuesperimeter_worstarea_worstsmoothness_worst: "worst" or largest mean value for local variation in radius lengthscompactness_worst: "worst" or largest mean value for perimeter^2 / area - 1.0concavity_worst: "worst" or largest mean value for severity of concave portions of the contourconcave points_worst: "worst" or largest mean value for number of concave portions of the contoursymmetry_worstfractal_dimension_worst: "worst" or largest mean value for "coastline approximation" - 1

Defining the services

The different endpoints which will be defined
def update_data():
# Read and prepare data
df_cancer = pd.read_csv("https://storage.googleapis.com/tutorial-datasets/data.csv")
df_cancer = df_cancer.drop(['id'], axis = 1)
df_cancer.drop("Unnamed: 32",axis=1,inplace=True)
# Define X and y
X = df_cancer.drop(['diagnosis'], axis = 1)
pd.set_option('display.max_columns', None)
df_cancer['diagnosis'] = df_cancer['diagnosis'].replace({'M': 0.0, 'B': 1.0})
y = df_cancer['diagnosis']
# Split dataset
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 20)
# Scale data
X_train_min = X_train.min()
X_train_max = X_train.max()
X_train_range = (X_train_max- X_train_min)
X_train_scaled = (X_train - X_train_min)/(X_train_range)
X_test_min = X_test.min()
X_test_range = (X_test - X_test_min).max()
X_test_scaled = (X_test - X_test_min)/X_test_range
return ("Dataset successfully updated")
@endpoint
def train_svm(args, body):
type = args.get('param', args.get('basic', None))

if type[0] == "basic":
svc_model.fit(X_train, y_train)
y_predict = svc_model.predict(X_test)

if type[0] == "normalized":
svc_model.fit(X_train_scaled, y_train)
y_predict = svc_model.predict(X_test_scaled)

if type[0] == "gridsearch":
param_grid = {'C': [0.1, 1, 10, 100], 'gamma': [1, 0.1, 0.01, 0.001], 'kernel': ['rbf']}
grid = GridSearchCV(SVC(),param_grid,refit=True,verbose=4)
grid.fit(X_train_scaled,y_train)
y_predict = grid.predict(X_test_scaled)

return y_predict, svc_model
@endpoint
def prediction(args, body):
if (svc_model.predict(body.get('data', []))[0] == 1.0):
return "Benign"
elif (svc_model.predict(body.get('data', []))[0] == 0.0):
return "Malign"
              precision    recall  f1-score   support

0.0 1.00 0.98 0.99 48
1.0 0.99 1.00 0.99 66

micro avg 0.99 0.99 0.99 114
macro avg 0.99 0.99 0.99 114
weighted avg 0.99 0.99 0.99 114
def show_performance():
if y_predict is not None:
return classification_report(y_test, y_predict)
else:
return "Model not trained yet, make a call to /train_svm to train it"
Confusion Matrix
Precision and Recall
$titan deploy

The system

#!bin/bash
# Simple script to programmatically update the model dataset
curl https://services.demo.akoios.com/bcc/update_data
0 8 * * * sh /route/to/script/update_data.sh
#!bin/bash# Simple script to programmatically retrain the model curl -X POST "https://services.demo.akoios.com/bcc/train_svm?param=$1" -H "accept: text/plain" -H "Content-Type: text/plain" -d "{}"
5 8 * * * sh /route/to/script/train.sh normalized
#!bin/bash# Simple script to track the recall and send alertsrecall=$(curl -X GET "https://services.demo.akoios.com/bcc/get_recall" -H "accept: application/json")threshold=0.9if (( $(echo "$recall < $threshold" |bc -l) )); then
curl --url 'smtps://smtp.gmail.com:465' --ssl-reqd --mail-from 'mail@mail.com' --mail-rcpt 'mail@mail.com' --user 'mail@mail.com:Password' -T "mailcontent.txt"
fi
6 8 * * * sh /route/to/script/recall_tracking.sh
Our system architecture

Wrap-up

Foreword

Akoios: Frictionless solutions for modern data science.

Akoios