Mots-clés: IRIS, IntegratedML, apprentissage automatique, Covid-19, Kaggle
Continuation de la précédente Partie I ... Dans la partie I, nous avons parcouru les approches ML traditionnelles sur ce jeu de données Covid-19 sur Kaggle.
Dans cette partie II, nous allons exécuter les mêmes données et la même tâche, dans sa forme la plus simple possible, à travers IRIS integratedML qui est une interface SQL agréable et élégante pour les options AutoML du backend. Cette interface utilise le même environnement.
Approche IntegratedML ?
Comment charger des données dans IRIS
integredML-demo-template a défini plusieurs façons de charger des données dans IRIS. Par exemple, je peux définir une classe IRIS personnalisée spécifique à ce fichier xls au format CSV, puis le charger dans un tableau IRIS. Cela permet un meilleur contrôle pour les volumes de données importants.
Cependant, dans cet article, j'opte pour une méthode simplifiée et légère, en me contentant de charger le jeux des données dans un tableau IRIS via une fonction Python personnalisée que j'ai créée. Cela nous permet de sauvegarder à tout moment les différentes étapes des dataframes brutes ou traitées dans IRIS, pour des comparaisons similaires avec l'approche ML précédente.
def to_sql_iris(cursor, dataFrame, tableName, schemaName='SQLUser', drop_table=False ):
""""
Insertion dynamique d'un dataframe dans un tableau IRIS via SQL par "excutemany"
Inputs:
cursor: Curseur Python JDBC ou PyODBC à partir d'une connexion DB valide et établie
dataFrame: Pandas dataframe
tablename: Tableau SQL IRIS à créer, à insérer ou à modifier
schemaName: IRIS schemaName, par défaut pour "SQLUser"
drop_table: Si le tableau existe déjà, le supprimer et le recréer si True ; sinon, le sauvegarder et l'appliquer
Output:
True en cas de succès ; False en cas d'exception.
"""
if drop_table:
try:
curs.execute("DROP TABLE %s.%s" %(schemaName, tableName))
except Exception:
pass
try:
dataFrame.columns = dataFrame.columns.str.replace("[() -]", "_")
curs.execute(pd.io.sql.get_schema(dataFrame, tableName))
except Exception:
pass
curs.fast_executemany = True
cols = ", ".join([str(i) for i in dataFrame.columns.tolist()])
wildc =''.join('?, ' * len(dataFrame.columns))
wildc = '(' + wildc[:-2] + ')'
sql = "INSERT INTO " + tableName + " ( " + cols.replace('-', '_') + " ) VALUES" + wildc
#print(sql)
curs.executemany(sql, list(dataFrame.itertuples(index=False, name=None)) )
return True
Configuration de la connexion Python JDBC
import numpy as np
import pandas as pd
from sklearn.impute import SimpleImputer
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, roc_auc_score, roc_curve
import seaborn as sns
sns.set(style="whitegrid")
import jaydebeapi
url = "jdbc:IRIS://irisimlsvr:51773/USER"
driver = 'com.intersystems.jdbc.IRISDriver'
user = "SUPERUSER"
password = "SYS"
jarfile = "./intersystems-jdbc-3.1.0.jar"
conn = jaydebeapi.connect(driver, url, [user, password], jarfile)
curs = conn.cursor()
Définition du point de départ des données
Pour les comparaisons à l'identique, j'ai commencé par le dataframe après les sélections de caractéristiques dans le post précédent (dans la section "Sélection de caractéristiques - Sélection finale"), où "DataS" est le dataframe exact que nous commençons ici.
data = dataS
data = pd.get_dummies(data)
data.ÂGE_AU-DESSUS65 = data.ÂGE_AU-DESSUS65.astype(int)
data.ICU = data.ICU.astype(int)
data_new = data
data_new
ÂGE_AU-DESSUS65 | GENRE | HTN | AUTRES | CALCIUM_MÉDIAN | CALCIUM_MIN | CALCIUM_MAX | CRÉATININE_MÉDIANE | CRÉATININE_MOYENNE | CRÉATININE_MIN | ... | DIFFÉRENCE_DU_RYTHME_CARDIAQUE_REL | DIFFÉRENCE_DE_TAUX_RESPIRATOIRE_REL | DIFFÉRENCE_DE_TEMPÉRATURE_REL | DIFFÉRENCE_DE_SATURATION_D'OXYGÈNE_REL | USI | FENÊTRE_0-2 | FENÊTRE_2-4 | FENÊTRE_4-6 | FENÊTRE_6-12 | FENÊTRE_AU-DESSUS_12 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 0.0 | 0.0 | 1.0 | 0.330359 | 0.330359 | 0.330359 | -0.891078 | -0.891078 | -0.891078 | ... | -1.000000 | -1.000000 | -1.000000 | -1.000000 | 1 | ||||||
1 | 1 | 0.0 | 0.0 | 1.0 | 0.330359 | 0.330359 | 0.330359 | -0.891078 | -0.891078 | -0.891078 | ... | -1.000000 | -1.000000 | -1.000000 | -1.000000 | 1 | |||||
2 | 1 | 0.0 | 0.0 | 1.0 | 0.183673 | 0.183673 | 0.183673 | -0.868365 | -0.868365 | -0.868365 | ... | -0.817800 | -0.719147 | -0.771327 | -0.886982 | 1 | |||||
3 | 1 | 0.0 | 0.0 | 1.0 | 0.330359 | 0.330359 | 0.330359 | -0.891078 | -0.891078 | -0.891078 | ... | -0.817800 | -0.719147 | -1.000000 | -1.000000 | 1 | |||||
4 | 1 | 0.0 | 0.0 | 1.0 | 0.326531 | 0.326531 | 0.326531 | -0.926398 | -0.926398 | -0.926398 | ... | -0.230462 | 0.096774 | -0.242282 | -0.814433 | 1 | 1 | ||||
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
1920 | 1.0 | 0.0 | 1.0 | 0.330359 | 0.330359 | 0.330359 | -0.891078 | -0.891078 | -0.891078 | ... | -1.000000 | -1.000000 | -1.000000 | -1.000000 | 1 | ||||||
1921 | 1.0 | 0.0 | 1.0 | 0.244898 | 0.244898 | 0.244898 | -0.934890 | -0.934890 | -0.934890 | ... | -1.000000 | -1.000000 | -1.000000 | -1.000000 | 1 | ||||||
1922 | 1.0 | 0.0 | 1.0 | 0.330359 | 0.330359 | 0.330359 | -0.891078 | -0.891078 | -0.891078 | ... | -1.000000 | -1.000000 | -1.000000 | -1.000000 | 1 | ||||||
1923 | 1.0 | 0.0 | 1.0 | 0.330359 | 0.330359 | 0.330359 | -0.891078 | -0.891078 | -0.891078 | ... | -1.000000 | -1.000000 | -1.000000 | -1.000000 | 1 | ||||||
1924 | 1.0 | 0.0 | 1.0 | 0.306122 | 0.306122 | 0.306122 | -0.944798 | -0.944798 | -0.944798 | ... | -0.763868 | -0.612903 | -0.551337 | -0.835052 | 1 |
1925 lignes × 62 colonnes
Ce qui précède indique que nous disposons de 58 caractéristiques sélectionnées plus 4 autres caractéristiques converties à partir de la colonne non numérique précédente ("FENÊTRE").
Sauvegarder les données dans le tableau IRIS
Nous utilisons la fonction to_sql_iris ci-dessus pour sauvegarder les données dans le tableau IRIS "CovidPPP62" :
iris_schema = 'SQLUser'
iris_table = 'CovidPPP62'
to_sql_iris(curs, data_new, iris_table, iris_schema, drop_table=True)
df2 = pd.read_sql("SELECT COUNT(*) from %s.%s" %(iris_schema, iris_table),conn)
display(df2)
Sauvegarder les données dans le tableau IRIS | Aggregate_1 |
---|---|
1925 |
Définissez ensuite le nom de la vue de formation, le nom du modèle et la colonne cible de la formation, qui est ici " USI ".
dataTable = iris_table
dataTableViewTrain = dataTable + 'Train1'
dataTablePredict = dataTable + 'Predict1'
dataColumn = 'ICU'
dataColumnPredict = 'ICUPredicted'
modelName = "ICUP621" #choisir un nom - doit être unique du côté serveur
Nous pouvons ensuite diviser les données en une Vue de formation (1700 lignes) et une Vue de test (225 lignes). Nous ne sommes pas obligés de faire cela dans Integrated ML ; c'est juste à des fins de comparaison avec l'article précédent.
curs.execute("CREATE VIEW %s AS SELECT * FROM %s WHERE ID<=1700" % (dataTableViewTrain, dataTable))
df62 = pd.read_sql("SELECT * from %s" % dataTableViewTrain, conn)
display(df62)
print(dataTableViewTrain, modelName, dataColumn)
CovidPPP62Train1 ICUP621 ICU
Formation du modèle à l'aide de l'AutoML par défaut d'IntegratedML
curs.execute("CREATE MODEL %s PREDICTING (%s) FROM %s" % (modelName, dataColumn, dataTableViewTrain))
curs.execute("TRAIN MODEL %s FROM %s" % (modelName, dataTableViewTrain))
df3 = pd.read_sql("SELECT * FROM INFORMATION_SCHEMA.ML_TRAINED_MODELS", conn)
display(df3)
NOM_DU_MODÈLE | NOM_DU_MODÈLE_FORMÉ | FOURNISSEUR | HORODATAGE_FORMÉ | TYPE_DU_MODÈLE | MODÈLE_INFO | |
---|---|---|---|---|---|---|
9 | USIP621 | USIP6212 | AutoML | 2020-07-22 19:28:16.174000 | classification | ModelType:Random Forest, Paquet:sklearn, Prob... |
Ainsi, nous pouvons voir que le résultat montre qu'IntegratedML a automatiquement choisi "ModelType" comme étant "Random Forest" (forêt aléatoire), et traite le problème comme une tâche de "Classification". C'est exactement ce que nous avons obtenu après les longues comparaisons de modèles et les sélections par boîte à moustaches, ainsi que le long réglage des paramètres du modèle par quadrillage, etc. dans l'article précédent, n'est-ce pas ?
Remarque: le SQL ci-dessus est le strict minimum selon la syntaxe d'IntegratedML. Je n'ai pas spécifié d'approche de formation ou de sélection de modèle, et je n'ai pas défini de plateforme de ML. Tout a été laissé à la décision de l'IML, qui a réussi à mettre en œuvre sa stratégie de formation interne, avant de se contenter d'un modèle raisonnable avec des résultats finaux corrects. Je dirais que cela a dépassé mes attentes.
Effectuons un rapide test de comparaison du modèle actuellement entraîné sur notre ensemble de test réservé.
Prédiction des résultats sur la base de données de test
Nous avons utilisé 1700 lignes pour la formation. Ci-dessous, nous créons une vue des données de test avec les 225 lignes restantes, et nous exécutons SELECT PREDICT sur ces enregistrements. Nous sauvegarderons le résultat prédit dans 'dataTablePredict
', et le chargerons dans 'df62' en tant que data frame.
dataTableViewTest = "SQLUSER.DTT621"
curs.execute("CREATE VIEW %s AS SELECT * FROM %s WHERE ID > 1700" % (dataTableViewTest, dataTable))
curs.execute("DROP TABLE %s" % dataTablePredict )
curs.execute("Create Table %s (%s VARCHAR(100), %s VARCHAR(100))" % (dataTablePredict, dataColumnPredict, dataColumn))
curs.execute("INSERT INTO %s SELECT PREDICT(%s) AS %s, %s FROM %s" % (dataTablePredict, modelName, dataColumnPredict, dataColumn, dataTableViewTest))
df62 = pd.read_sql("SELECT * from %s ORDER BY ID" % dataTablePredict, conn)
display(df62)
Nous n'avons pas besoin de calculer manuellement sa matrice de confusion. Il s'agit simplement d'une comparaison :
TP = df62[(df62['ICUPredicted'] == '1') & (df62['ICU']=='1')].count()['ICU']
TN = df62[(df62['ICUPredicted'] == '0') & (df62['ICU']=='0')].count()["ICU"]
FN = df62[(df62['ICU'] == '1') & (df62['ICUPredicted']=='0')].count()["ICU"]
FP = df62[(df62['ICUPredicted'] == '1') & (df62['ICU']=='0')].count()["ICU"]
print(TP, FN, '\n', FP, TN)
precision = (TP)/(TP+FP)
recall = (TP)/(TP+FN)
f1 = ((precision*recall)/(precision+recall))*2
accuracy = (TP+TN) / (TP+TN+FP+FN)
print("Precision: ", precision, " Recall: ", recall, " F1: ", f1, " Accuracy: ", accuracy)
34 20 8 163 Précision: 0.8095238095238095 rappel: 0.6296296296296297 F1: 0.7083333333333334 Exactitude: 0.8755555555555555
Nous pouvons également utiliser la syntaxe IntegratedML pour obtenir sa matrice de confusion intégrée :
# valider les données de test
curs.execute("VALIDATE MODEL %s FROM %s" % (modelName, dataTableViewTest) )
df5 = pd.read_sql("SELECT * FROM INFORMATION_SCHEMA.ML_VALIDATION_METRICS", conn)
df6 = df5.pivot(index='VALIDATION_RUN_NAME', columns='METRIC_NAME', values='METRIC_VALUE')
display(df6)
NOM_MÉTRIQUE | Exactitude | Mesure F | Précision | Rappel |
---|---|---|---|---|
NOM_DE_L'EXÉCUTION_DE_LA_VALIDATION | ||||
USIP62121 | 0.88 | 0.71 | 0.81 | 0.63 |
... | ... | ... | ... | ... |
Si l'on compare avec le "Résultat original" de la section " Exécuter une formation de base en LR " dans la partie I, le résultat ci-dessus présente un rappel de 63 % contre 57 %, et une exactitude de 88 % contre 85 %. Il s'agit donc d'un meilleur résultat avec IntegratedML.
Former à nouveau IntegratedML sur des données de formation rééquilibrées via SMOTE
Le test ci-dessus a été effectué sur des données déséquilibrées, dans lesquelles le rapport entre les patients admis en USI et les patients non admis est de 1:3. Donc, comme dans l'article précédent, nous allons simplement effectuer un SMOTE pour que les données soient équilibrées, puis nous allons réexécuter le pipeline IML ci-dessus.
'X_train_res' and 'y_train_res' sont des dataframes après SMOTE de la Partie I précédente dans sa section " Exécuter une formation de base en LR ".
df_x_train = pd.DataFrame(X_train_res)
df_y_train = pd.DataFrame(y_train_res)
df_y_train.columns=['ICU']
df_smote = pd.concat([df_x_train, df_y_train], 1)
display(df_smote)
iris_schema = 'SQLUser'
iris_table = 'CovidSmote'
to_sql_iris(curs, df_smote, iris_table, iris_schema, drop_table=True) # sauvegarder ceci dans un nouveau tableau IRIS portant le nom spécifié
df2 = pd.read_sql("SELECT COUNT(*) from %s.%s" %(iris_schema, iris_table),conn)
display(df2)
Aggregate_1 | |
---|---|
2490 |
Le jeu de données comporte désormais 2490 lignes au lieu de 1700, car SMOTE a enrichi davantage d'enregistrements avec USI = 1.
dataTable = iris_table
dataTableViewTrain = dataTable + 'TrainSmote'
dataTablePredict = dataTable + 'PredictSmote'
dataColumn = 'ICU'
dataColumnPredict = 'ICUPredictedSmote'
modelName = "ICUSmote1" #choisir un nom - doit être unique du côté serveur
curs.execute("CREATE VIEW %s AS SELECT * FROM %s" % (dataTableViewTrain, dataTable))
df_smote = pd.read_sql("SELECT * from %s" % dataTableViewTrain, conn)
display(df_smote)
print(dataTableViewTrain, modelName, dataColumn)
CovidSmoteTrainSmote ICUSmote1 ICU
curs.execute("CREATE MODEL %s PREDICTING (%s) FROM %s" % (modelName, dataColumn, dataTableViewTrain))
curs.execute("TRAIN MODEL %s FROM %s" % (modelName, dataTableViewTrain))
df3 = pd.read_sql("SELECT * FROM INFORMATION_SCHEMA.ML_TRAINED_MODELS", conn)
display(df3)
NOM_DU_MODÈLE | NOM_DU_MODÈLE_FORMÉ | FOURNISSEUR | HORODATAGE_FORMÉ | TYPE_DU_MODÈLE | MODEL_INFO | |
---|---|---|---|---|---|---|
9 | USIP621 | USIP6212 | AutoML | 2020-07-22 19:28:16.174000 | classification | ModelType:Random Forest, Paquet:sklearn, Prob... |
12 | USISmote1 | USISmote12 | AutoML | 2020-07-22 20:49:13.980000 | classification | ModelType:Random Forest, Paquet:sklearn, Prob... |
Ensuite, nous préparons à nouveau un ensemble réservé de 225 lignes de données de test et nous exécutons le modèle reformé de SMOTE sur ces lignes :
df_x_test = pd.DataFrame(X3_test)
df_y_test = pd.DataFrame(y3_test)
df_y_test.columns=['ICU']
df_test_smote = pd.concat([df_x_test, df_y_test], 1)
display(df_test_smote)
iris_schema = 'SQLUser'
iris_table = 'CovidTestSmote'
to_sql_iris(curs, df_test_smote, iris_table, iris_schema, drop_table=True)
dataTableViewTest = "SQLUSER.DTestSmote225"
curs.execute("CREATE VIEW %s AS SELECT * FROM %s" % (dataTableViewTest, iris_table))
curs.execute("Create Table %s (%s VARCHAR(100), %s VARCHAR(100))" % (dataTablePredict, dataColumnPredict, dataColumn))
curs.execute("INSERT INTO %s SELECT PREDICT(%s) AS %s, %s FROM %s" % (dataTablePredict, modelName, dataColumnPredict, dataColumn, dataTableViewTest))
df62 = pd.read_sql("SELECT * from %s ORDER BY ID" % dataTablePredict, conn)
display(df62)
TP = df62[(df62['ICUPredictedSmote'] == '1') & (df62['ICU']=='1')].count()['ICU']
TN = df62[(df62['ICUPredictedSmote'] == '0') & (df62['ICU']=='0')].count()["ICU"]
FN = df62[(df62['ICU'] == '1') & (df62['ICUPredictedSmote']=='0')].count()["ICU"]
FP = df62[(df62['ICUPredictedSmote'] == '1') & (df62['ICU']=='0')].count()["ICU"]
print(TP, FN, '\n', FP, TN)
precision = (TP)/(TP+FP)
recall = (TP)/(TP+FN)
f1 = ((precision*recall)/(precision+recall))*2
accuracy = (TP+TN) / (TP+TN+FP+FN)
print("Precision: ", precision, " Recall: ", recall, " F1: ", f1, " Accuracy: ", accuracy)
45 15
9 156
Précision: 0.8333333333333334 Rappel: 0.75 F1: 0.7894736842105262 Exactitude: 0.8933333333333333
# valider les données d'essai à l'aide du modèle reformé de SMOTE
curs.execute("VALIDATE MODEL %s FROM %s" % (modelName, dataTableViewTest) ) #Covid19aTest500, Covid19aTrain1000
df5 = pd.read_sql("SELECT * FROM INFORMATION_SCHEMA.ML_VALIDATION_METRICS", conn)
df6 = df5.pivot(index='VALIDATION_RUN_NAME', columns='METRIC_NAME', values='METRIC_VALUE')
display(df6)
NOM_MÉTRIQUE | Exactitude | Mesure F | Précision | Rappel |
---|---|---|---|---|
NOM_DE_L'EXÉCUTION_DE_LA_VALIDATION | ||||
USIP62121 | 0.88 | 0.71 | 0.81 | 0.63 |
USISmote122 | 0.89 | 0.79 | 0.83 | 0.75 |
Le résultat indique une amélioration significative du rappel de 75 % par rapport aux 63 % précédents, ainsi qu'une légère amélioration de l'exactitude et du score F1.
Plus notablement, ce résultat est conforme à notre "approche ML traditionnelle" dans l'article précédent, après une "sélection de modèle" intensive et un "réglage des paramètres par quadrillage", comme indiqué dans la section "Exécuter le modèle sélectionné en poursuivant "Ajustement des paramètres via la recherche par quadrillage" supplémentaire". Le résultat de l'IML n'est donc pas mauvais du tout.
Changement de fournisseur H2O d'IntegratedML
Nous pouvons modifier le fournisseur AutoML de l'IML d'une seule ligne, puis former à nouveau le modèle comme nous l'avons fait à l'étape précédente :
curs.execute("SET ML CONFIGURATION %H2O; ")
modelName = 'ICUSmoteH2O'
print(dataTableViewTrain)
curs.execute("CREATE MODEL %s PREDICTING (%s) FROM %s" % (modelName, dataColumn, dataTableViewTrain))
curs.execute("TRAIN MODEL %s FROM %s" % (modelName, dataTableViewTrain))
df3 = pd.read_sql("SELECT * FROM INFORMATION_SCHEMA.ML_TRAINED_MODELS", conn)
display(df3)
NOM_DU_MODÈLE | NOM_DU_MODÈLE_FORMÉ | FOURNISSEUR | HORODATAGE_FORMÉ | TYPE_DU_MODÈLE | MODÈLE_INFO | |
---|---|---|---|---|---|---|
12 | USISmote1 | USISmote12 | AutoML | 2020-07-22 20:49:13.980000 | classification | ModelType:Random Forest, Paquet:sklearn, Prob... |
13 | USIPPP62 | USIPPP622 | AutoML | 2020-07-22 17:48:10.964000 | classification | ModelType:Random Forest, Paquet:sklearn, Prob... |
14 | USISmoteH2O | USISmoteH2O2 | H2O | 2020-07-22 21:17:06.990000 | classification | Aucun |
# valider les données de test
curs.execute("VALIDATE MODEL %s FROM %s" % (modelName, dataTableViewTest) ) #Covid19aTest500, Covid19aTrain1000
df5 = pd.read_sql("SELECT * FROM INFORMATION_SCHEMA.ML_VALIDATION_METRICS", conn)
df6 = df5.pivot(index='VALIDATION_RUN_NAME', columns='METRIC_NAME', values='METRIC_VALUE')
display(df6)
NOM_MÉTRIQUE | Exactitude | Mesure F | Précision | Rappel |
---|---|---|---|---|
NOM_DE_L'EXÉCUTION_DE_LA_VALIDATION | ||||
USIP62121 | 0.88 | 0.71 | 0.81 | 0.63 |
USISmote122 | 0.89 | 0.79 | 0.83 | 0.75 |
USISmoteH2O21 | 0.90 | 0.79 | 0.86 | 0.73 |
Les résultats semblent montrer que H2O AutoML a une précision légèrement supérieure, le même F1, mais un rappel légèrement inférieur. Cependant, notre objectif principal dans cette tâche de Covid19 USI est de minimiser les faux négatifs si nous le pouvons. Il semble donc que le changement de fournisseur pour H2O n'ait pas encore permis d'augmenter notre performance cible.
J'aimerais certainement tester également le fournisseur DataRobot d'IntegratedML, mais je n'ai malheureusement pas encore de clé API de DataRobot, alors je vais la mettre de côté ici.
Récapitulatif:
-
Performance : Pour cette tâche spécifique de l'unité de soins intensifs de Covid-19, nos comparaisons de tests indiquent que les performances de l'IntegratedML d'IRIS sont au moins équivalentes ou similaires aux résultats de l'approche ML traditionnelle. Dans ce cas précis, IntegratedML a été capable de choisir automatiquement et correctement la stratégie d'entraînement interne, et a semblé établir le bon modèle, fournissant le résultat escompté.
-
Simplicité : IntegratedML a un processus beaucoup plus simplifié que les pipelines ML traditionnels. Comme indiqué ci-dessus, je n'ai plus besoin de me préoccuper de la sélection des modèles et l'ajustement des paramètres, etc. Je n'ai pas non plus besoin de la sélection des caractéristiques, si ce n'est à des fins de comparaison. De plus, je n'ai utilisé que la syntaxe minimale d'IntegratedML, comme indiqué dans le cahier de démonstration d'Integrated-demo-template. Bien sûr, le désavantage est que nous sacrifions les capacités de personnalisation et d'ajustement des outils courants de science des données via leurs pipelines traditionnels, mais c'est aussi plus ou moins vrai pour d'autres plateformes AutoML.
-
Le prétraitement des données reste important : Il n'y a malheureusement pas de solution miracle ; ou plutôt, cette solution miracle prendrait du temps. Spécifiquement pour cette tâche de Covid19 USI, les tests ci-dessus montrent que les données ont encore beaucoup d'importance pour l'approche actuelle d'IntegratedML : données brutes, caractéristiques sélectionnées avec données manquantes imputées, et données rééquilibrées avec suréchantillonnage SMOTE de base, elles ont toutes abouti à des performances significativement différentes. C'est vrai pour l'AutoML par défaut d'IML et son fournisseur H2O. J'imagine que DataRobot pourrait revendiquer une performance légèrement supérieure, mais cela doit être testé plus avant avec l'enveloppe SQL d'IntegratedML. En bref, la normalisation des données est toujours importante dans IntegratedML.
-
Déployabilité : Je n'ai pas encore comparé la déployabilité, la gestion de l'API, la surveillance et la facilité d'utilisation non fonctionnelle, etc.
Suivant
-
Déploiements de modèles : Jusqu'à présent, nous avons fait des démonstrations d'IA sur les radiographies pour le Covid-19 et des prédictions pour l'unité de soins intensifs pour le Covid-19 sur les signes vitaux et les observations. Pouvons-nous les déployer dans les piles de services Flask/FastAPI et IRIS, et exposer leurs capacités ML/DL de démonstration via des API REST/JSON ? Bien sûr, nous pouvons essayer de le faire dans le prochain article. Ensuite, nous pourrons ajouter d'autres capacités d'IA de démonstration au fil du temps, y compris des API NLP, etc.
-
Interopérabilité de l'API enveloppée dans FHIR : Nous disposons également d'un modèle FHIR, ainsi que d'une API native IRIS, etc. dans cette communauté de développeurs. Pourrions-nous transformer notre service d'IA de démonstration en SMART on FHIR apps, ou en services d'IA enveloppés dans FHIR selon les normes correspondantes - pourrions-nous essayer cela ? Et n'oubliez pas que dans la gamme de produits IRIS, nous avons également API Gateway, ICM avec support Kubernetes, et SAM etc. que nous pourrions également exploiter avec nos piles de démonstrations d'IA.
-
Démonstration d'intégration avec HealthShare Clinical Viewer et/ou Trak etc ? J'ai brièvement montré une démonstration d'intégration du PACS Viewer d'un fournisseur d'IA tiers (pour les CT Covid-19) avec HealthShare Clinical Viewer, et nous pourrions peut-être terminer cette randonnée avec nos propres services de démonstration d'IA, dans divers domaines de spécialité au fil du temps.