Welcome to ML on FHIR’s documentation!

Installation

TODO

Getting Started

Connecting to a FHIR Server

To connect to a FHIR server, create a FHIRClient object and provide its BaseURL:

1
2
from fhir_client import FHIRClient
client = FHIRClient(service_base_url='https://r3.smarthealthit.org')

The server’s compatibility statement is queried to determine whether the connection was sucessful established.

Get an Overview of your Data

Before querying patients that belong to a specific cohort, we can get an overview of available procedures and via:

1
2
3
import pandas as pd
procedures = client.get_all_procedures()
pd.DataFrame([prod.code['coding'][0] for prod in procedures]).drop_duplicates().sort_values(by=['display']).head()

This might take a while but will give you an overview of available procedures. E.g.

ID code display system
893 183450002 Admission to burn unit http://snomed.info/sct
83 305428000 Admission to orthopedic department http://snomed.info/sct
13687 35637008 Alcohol rehabilitation http://snomed.info/sct

Similarily, we can receive a list of available conditions via:

1
2
conditions = client.get_all_conditions()
pd.DataFrame([cond.code['coding'][0] for cond in conditions]).drop_duplicates(subset=['display']).sort_values(by='display', ascending=True).head()
ID code display system
488 30473006 Abdominal pain http://snomed.info/sct
140 102594003 Abnormal ECG http://snomed.info/sct
6801 26079004 Abnormal involuntary movement http://snomed.info/sct

Query Patients

With a list of available conditions we can query patients for which a certain condition was diagnosed. To do so we can either use the code of a coding nomenclature (e.g. SNOMED) or its readable name:

1
2
patients_by_condition_text = client.get_patients_by_condition_text("Abdominal pain")
patients_by_procedure_code = client.get_patients_by_procedure_code("http://snomed.info/sct","73761001")

Machine Learning

TODO

Server Interoperability

ObservationProcessors

To use patient features in a machine learning task, we will extract them from the FHIR Observation Resource. Depending on how your server is set up, the way we can extract desired observation values might differ. In the following example we will use LOINC codes to extract the latest BMI measurement of a patient.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from ml_on_fhir.preprocessing import AbstractObservationProcessor, get_coding_condition

class ObservationLatestBmiProcessor(AbstractObservationProcessor):
        """
        Class to transform the FHIR observation resource with loinc code 39156-5 (BMI)
        to be usable as patient feature.
        """
        def __init__(self):
                super().__init__('bmiLatest')

        def transform(self, X, **transform_params):
                conditions = get_coding_condition([{'system': 'http://loinc.org',
                                                    'code': '39156-5'}])
                bmis = list(filter(conditions, X))
                bmis = sorted(bmis, reverse=True)
                if len(bmis) >= 1:
                        return self.patient_attribute_name, float(bmis[0].valueQuantity['value'])
                else:
                        return self.patient_attribute_name, 0.0

In line 9, we define the name of the feature, so we can use it as if it was a patient attribute. In line 12, we define the conditions that an observation needs to fulfill to be considered. An observation has to fulfill all conditions (e.g. coding system has to be http://loinc.org and its code must be 39156-5). In line 13, we apply the conditions on all observations of a given patient (X). Now, we reversely sort the Observation objects that are left. Observation objects are always sorted by FHIR’s effectiveDateTime attribute. Finally, we use the FHIR quantity datatype to return the patient’s latest BMI measurement.

We can now use the new bmiLatest feature in a MLOnFHIRClassifier after registering in with the FHIRClient.

1
2
3
4
5
6
from ml_on_fhir.fhir_client import FHIRClient

client = FHIRClient(service_base_url='https://r3.smarthealthit.org')
client.preprocessor.register_preprocessor(ObservationLatestBmiProcessor)
ml_fhir = MLOnFHIRClassifier(Patient, feature_attrs=['bmiLatest'],
                             label_attrs=['gender'], preprocessor=client.preprocessor)

Note that some patient attributes like gender are already provided through a similar mechanism with PatientProcessors. Read more about them here.

PatientProcessors