backend/sweettweet/services/lstm_model.py
def forecast(self, past_data, user_info, new_bg):
        '''
        Return predicted glucose data along with past data and hypoglycemic
        alarm state based on input past data, user info and new glucose measurement.
        '''

        # read in past glucose data
        data = pd.read_json(json.dumps(past_data))

        # format columns to timestamp
        data.actualTime = [pd.Timestamp(d, unit='ms') for d in data.actualTime]
        data.forecastTime = [pd.Timestamp(d, unit='ms') for d in data.forecastTime]
        data.sort_values(['actualTime', 'forecastTime'], inplace = True)

        # new measurement timestamp
        new_timestamp = pd.date_range(start = max(data.actualTime), periods = 2, freq = '5min')[1]

        # add new measurement to past data
        X_new = pd.DataFrame({'actualTime' : [new_timestamp], 'glucose' : [float(new_bg)]})
        X_new = pd.concat([data[data.actualTime == data.forecastTime
                                ].sort_values(['actualTime', 'forecastTime']
                                ).iloc[-144:, [0,2]],
                               X_new], axis = 0, ignore_index= True)

        # calculate model features
        X_new['Time'] = [float(str(d).split(':')[0]) + float(str(d).split(':')[1])/60 for d in X_new.actualTime.dt.time]
        X_new['Time_norm'] = X_new.Time / 24
        X_new['Night'] = [1 if (d < 7 or d > 21) else 0 for d in X_new.Time] 
        X_new['Glucose_norm'] = 2 * (np.log(X_new.glucose) - np.log(30)) / (np.log(400) - np.log(30)) - 1

        gender = int(user_info['gender'] == 'M') # from userInfo
        insulin = int(user_info['insulinDelivery'] == 'pump') # from userInfo
        bmi = float(user_info['bmi']) # from userInfo
        bmi_norm =2 * (bmi - 12) / (45 - 12) - 1 
        age = float(user_info['age']) # from uerInfo
        age_norm = 2 * (age) / 100 - 1

        glucose_input = X_new.Glucose_norm
        night_input = X_new.Night
        time_input = X_new.Time_norm
        timestamp_input = X_new.actualTime
        gender_input = np.ones_like(time_input) * gender
        insulin_input = np.ones_like(time_input) * insulin
        bmi_input = np.ones_like(time_input) * bmi_norm
        age_input = np.ones_like(time_input) * age_norm
        
        # stack all features for the lstm model
        X = np.dstack((night_input, time_input, glucose_input, 
                   gender_input, insulin_input, bmi_input, age_input))

        # forecast
        with self.graph.as_default():
            Y_pred = self.model.predict(X)

        # inverse glucose normalization
        Y_pred = inv_norm(Y_pred)

        # alarm
        alarm = int(Y_pred[0, -1] < 70)

        # format prediction to send back to client
        actual_time = [new_timestamp] * 7
        forecast_time = pd.date_range(start = new_timestamp, periods = 7, freq = '5min')
        glucose = [inv_norm(X[:, -1, 2][0])] + Y_pred[0,:].tolist()
        glucose_data_tmp = pd.DataFrame({'actualTime' : actual_time, 
                                         'forecastTime' : forecast_time, 
                                         'glucose': glucose})
        
        data = pd.concat([data, glucose_data_tmp], axis = 0, ignore_index=True)
        
        # removing first timepoint to only keep the past 12h
        data = data[data.actualTime > min(data.actualTime)]

        # export data to json
        data_json = data.to_json(path_or_buf = None, orient = 'records')

        return (data_json, alarm)

        Return predicted glucose data along with past data and hypoglycemic
        alarm state based on input past data, user info and new glucose measurement.
        
Return predicted glucose data along with past data and hypoglycemic
alarm state based on input past data, user info and new glucose measurement.
Return predicted glucose data along with past data and hypoglycemic alarm state based on input past data user info and new glucose measurement .
def forecast(self, past_data, user_info, new_bg):
        data = pd.read_json(json.dumps(past_data))
        data.actualTime = [pd.Timestamp(d, unit='ms') for d in data.actualTime]
        data.forecastTime = [pd.Timestamp(d, unit='ms') for d in data.forecastTime]
        data.sort_values(['actualTime', 'forecastTime'], inplace = True)
        new_timestamp = pd.date_range(start = max(data.actualTime), periods = 2, freq = '5min')[1]
        X_new = pd.DataFrame({'actualTime' : [new_timestamp], 'glucose' : [float(new_bg)]})
        X_new = pd.concat([data[data.actualTime == data.forecastTime
                                ].sort_values(['actualTime', 'forecastTime']
                                ).iloc[-144:, [0,2]],
                               X_new], axis = 0, ignore_index= True)
        X_new['Time'] = [float(str(d).split(':')[0]) + float(str(d).split(':')[1])/60 for d in X_new.actualTime.dt.time]
        X_new['Time_norm'] = X_new.Time / 24
        X_new['Night'] = [1 if (d < 7 or d > 21) else 0 for d in X_new.Time] 
        X_new['Glucose_norm'] = 2 * (np.log(X_new.glucose) - np.log(30)) / (np.log(400) - np.log(30)) - 1
        gender = int(user_info['gender'] == 'M') 
        insulin = int(user_info['insulinDelivery'] == 'pump') 
        bmi = float(user_info['bmi']) 
        bmi_norm =2 * (bmi - 12) / (45 - 12) - 1 
        age = float(user_info['age']) 
        age_norm = 2 * (age) / 100 - 1
        glucose_input = X_new.Glucose_norm
        night_input = X_new.Night
        time_input = X_new.Time_norm
        timestamp_input = X_new.actualTime
        gender_input = np.ones_like(time_input) * gender
        insulin_input = np.ones_like(time_input) * insulin
        bmi_input = np.ones_like(time_input) * bmi_norm
        age_input = np.ones_like(time_input) * age_norm
        X = np.dstack((night_input, time_input, glucose_input, 
                   gender_input, insulin_input, bmi_input, age_input))
        with self.graph.as_default():
            Y_pred = self.model.predict(X)
        Y_pred = inv_norm(Y_pred)
        alarm = int(Y_pred[0, -1] < 70)
        actual_time = [new_timestamp] * 7
        forecast_time = pd.date_range(start = new_timestamp, periods = 7, freq = '5min')
        glucose = [inv_norm(X[:, -1, 2][0])] + Y_pred[0,:].tolist()
        glucose_data_tmp = pd.DataFrame({'actualTime' : actual_time, 
                                         'forecastTime' : forecast_time, 
                                         'glucose': glucose})
        data = pd.concat([data, glucose_data_tmp], axis = 0, ignore_index=True)
        data = data[data.actualTime > min(data.actualTime)]
        data_json = data.to_json(path_or_buf = None, orient = 'records')
        return (data_json, alarm)
def forecast ( self , past_data , user_info , new_bg ) : data = pd . read_json ( json . dumps ( past_data ) ) data . actualTime = [ pd . Timestamp ( d , unit = 'ms' ) for d in data . actualTime ] data . forecastTime = [ pd . Timestamp ( d , unit = 'ms' ) for d in data . forecastTime ] data . sort_values ( [ 'actualTime' , 'forecastTime' ] , inplace = True ) new_timestamp = pd . date_range ( start = max ( data . actualTime ) , periods = 2 , freq = '5min' ) [ 1 ] X_new = pd . DataFrame ( { 'actualTime' : [ new_timestamp ] , 'glucose' : [ float ( new_bg ) ] } ) X_new = pd . concat ( [ data [ data . actualTime == data . forecastTime ] . sort_values ( [ 'actualTime' , 'forecastTime' ] ) . iloc [ - 144 : , [ 0 , 2 ] ] , X_new ] , axis = 0 , ignore_index = True ) X_new [ 'Time' ] = [ float ( str ( d ) . split ( ':' ) [ 0 ] ) + float ( str ( d ) . split ( ':' ) [ 1 ] ) / 60 for d in X_new . actualTime . dt . time ] X_new [ 'Time_norm' ] = X_new . Time / 24 X_new [ 'Night' ] = [ 1 if ( d < 7 or d > 21 ) else 0 for d in X_new . Time ] X_new [ 'Glucose_norm' ] = 2 * ( np . log ( X_new . glucose ) - np . log ( 30 ) ) / ( np . log ( 400 ) - np . log ( 30 ) ) - 1 gender = int ( user_info [ 'gender' ] == 'M' ) insulin = int ( user_info [ 'insulinDelivery' ] == 'pump' ) bmi = float ( user_info [ 'bmi' ] ) bmi_norm = 2 * ( bmi - 12 ) / ( 45 - 12 ) - 1 age = float ( user_info [ 'age' ] ) age_norm = 2 * ( age ) / 100 - 1 glucose_input = X_new . Glucose_norm night_input = X_new . Night time_input = X_new . Time_norm timestamp_input = X_new . actualTime gender_input = np . ones_like ( time_input ) * gender insulin_input = np . ones_like ( time_input ) * insulin bmi_input = np . ones_like ( time_input ) * bmi_norm age_input = np . ones_like ( time_input ) * age_norm X = np . dstack ( ( night_input , time_input , glucose_input , gender_input , insulin_input , bmi_input , age_input ) ) with self . graph . as_default ( ) : Y_pred = self . model . predict ( X ) Y_pred = inv_norm ( Y_pred ) alarm = int ( Y_pred [ 0 , - 1 ] < 70 ) actual_time = [ new_timestamp ] * 7 forecast_time = pd . date_range ( start = new_timestamp , periods = 7 , freq = '5min' ) glucose = [ inv_norm ( X [ : , - 1 , 2 ] [ 0 ] ) ] + Y_pred [ 0 , : ] . tolist ( ) glucose_data_tmp = pd . DataFrame ( { 'actualTime' : actual_time , 'forecastTime' : forecast_time , 'glucose' : glucose } ) data = pd . concat ( [ data , glucose_data_tmp ] , axis = 0 , ignore_index = True ) data = data [ data . actualTime > min ( data . actualTime ) ] data_json = data . to_json ( path_or_buf = None , orient = 'records' ) return ( data_json , alarm )
Return predicted glucose data along with past data and hypoglycemic
alarm state based on input past data, user info and new glucose measurement.
Return predicted glucose data along with past data and hypoglycemic alarm state based on input past data user info and new glucose measurement .
'''
        Return predicted glucose data along with past data and hypoglycemic
        alarm state based on input past data, user info and new glucose measurement.
        ''' # read in past glucose data # format columns to timestamp # new measurement timestamp # add new measurement to past data # calculate model features # from userInfo # from userInfo # from userInfo # from uerInfo # stack all features for the lstm model # forecast # inverse glucose normalization # alarm # format prediction to send back to client # removing first timepoint to only keep the past 12h # export data to json
self
past_data
user_info
new_bg