import gradio as gr import numpy as np from PIL import Image import requests import pandas as pd import matplotlib.pyplot as plt import numpy as np import hopsworks import joblib # Convert the input to the format the model expects def prepare_for_write(df): # Convert the categorical features to numerical def sexToInt(x): if x == "male": return 0 elif x == "female": return 1 else: raise Exception("Unsupported sex value: " + x) def embarkedToInt(x): if x == "S": return 0 elif x == "C": return 1 elif x == "Q": return 2 else: raise Exception("Unsupported embarked value: " + x) df["Sex"] = df["Sex"].apply(sexToInt) df["Embarked"] = df["Embarked"].apply(embarkedToInt) # le = preprocessing.LabelEncoder() # df = df.apply(le.fit_transform) df.columns = df.columns.str.lower() return df # Login to hopsworks and get the feature store project = hopsworks.login() fs = project.get_feature_store() # Get the model from Hopsworks mr = project.get_model_registry() model = mr.get_model("titanic_modal", version=10) model_dir = model.download() model = joblib.load(model_dir + "/titanic_model.pkl") # For generating the input form catToInput = { "Sex": ["male", "female"], "Embarked": ["Southampton", "Cherbourg", "Queenstown"], "Pclass": ["First", "Second", "Third"] } cityToInput = { "Southampton": "S", "Cherbourg": "C", "Queenstown": "Q" } classToInput = { "First": 1, "Second": 2, "Third": 3 } inputs = [] numericalInputs = ["Age", "SibSp", "Parch", "Fare"] # Maybe move cabin to categorical (or just remove it) worthlessInputs = ["Name", "Ticket", "Cabin", "Title"] categoricalInputs = ["Sex", "Embarked", "Pclass"] columnHeaders = ["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked"] def titanic(Pclass, Sex, Age, SibSp, Parch, Fare, Embarked): # Parse the unput and save it so we can run it through the model Embarked = cityToInput[Embarked] Pclass = classToInput[Pclass] # Create a dataframe from the input values input_variables = pd.DataFrame( [[Pclass, Sex, Age, SibSp, Parch, Fare, Embarked]], columns=columnHeaders) df = prepare_for_write(input_variables) # Save first row as a numpy array input_list = df.iloc[0].to_numpy() # 'res' is a list of predictions returned as the label. res = model.predict(np.asarray(input_list).reshape(1, -1)) # We add '[0]' to the result of the transformed 'res', because 'res' is a list, and we only want # the first element. intLabelToText = {0: "Died", 1: "Survived"} # Debug survived = res[0] # The API we are using only supports this age range if Age < 9: Age = 9 if Age > 75: Age = 75 # Generate a face of the inputted person generate_survivor_url = f'https://fakeface.rest/face/json?maximum_age={int(Age)}&gender={Sex}&minimum_age={int(Age)}' randomized_face_url = requests.get( generate_survivor_url).json()["image_url"] survivor_url = randomized_face_url img = Image.open(requests.get(survivor_url, stream=True).raw) # Show a green check mark if the person is predicted to survive, otherwise show a red x red_cross_url = "https://www.iconsdb.com/icons/preview/red/x-mark-xxl.png" green_check_mark_url = "https://www.iconsdb.com/icons/preview/green/checkmark-xxl.png" label_to_url = { 0: red_cross_url, 1: green_check_mark_url } url = label_to_url.get(survived) # Save the image of the person img2 = Image.open(requests.get(url, stream=True).raw) return img, img2 # All features present in the titanic dataset featureLabels = ["Pclass", "Name", "Sex", "Age", "SibSp", "Parch", "Ticket", "Fare", "Cabin", "Embarked"] # Generate the input form for feature in featureLabels: if feature in numericalInputs: if feature == 'Age': inputs.append(gr.inputs.Slider(9, 75, 1, label='Age (years)')) elif feature == 'SibSp': inputs.append(gr.inputs.Slider( 0, 10, 1, label='Number of siblings/spouses aboard')) elif feature == 'Parch': inputs.append(gr.inputs.Slider( 0, 10, 1, label='Number of parents/children aboard')) elif feature == 'Fare': inputs.append(gr.inputs.Slider(0, 1000, 1, label='Ticket fare')) else: raise Exception(f'Feature: "{feature}" not found') elif feature in worthlessInputs: pass # inputs.append(gr.Inputs.Textbox(default='text', label=feature)) elif feature in categoricalInputs: if feature == "Sex": inputs.append(gr.inputs.Dropdown( choices=catToInput.get(feature), default="male", label=feature)) elif feature == "Embarked": inputs.append(gr.inputs.Dropdown( choices=catToInput.get(feature), default="Southampton", label='City of embarkation')) elif feature == "Pclass": inputs.append(gr.inputs.Dropdown( choices=catToInput.get(feature), default=3, label='Ticket class')) else: raise Exception(f'Feature: "{feature}" not found') # Create the interface demo = gr.Interface( fn=titanic, title="Titanic Survivor Predictive Analytics", description="Experiment with person features to predict which survivor it is.", allow_flagging="never", inputs=inputs, outputs=[gr.Image(type="pil").style( height='100', rounded=False), gr.Image(type="pil").style( height='100', rounded=False)]) demo.launch()