Article
· Mars 31, 2023 22m de lecture

Prédictions de Covid-19 ICU via ML vs. IntegratedML (Partie II)

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:

  1. 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é.

  2. 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.

  3. 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.

  4. 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

  1. 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.

  2. 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.

  3. 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.

Discussion (0)2
Connectez-vous ou inscrivez-vous pour continuer