Authors: Ferran Torrent-Fontbona, Beatriz López and Joaquim Massana (Univeristy of Girona).
The purpose of this document is to describe the setup procedure for the PEPPER Insulin Recommender library, the insulin recommender API and the details on the implementation. The PEPPER Core library (Insulin Recommender) is a self-contained independent library designed for interaction with the PEPPER Safety System. The core of the library and the API have been developed by the University of Girona.
This chapter details the setup of the PEPPER Insulin Recommender library.
Setup of the library involves only importing the PepperCore.jar into the Android project. In this section we provide two options: First, manually edit the application’s module build.gradle; Second, using the Android Studio interface to import a JAR as a dependency. The PepperCore.jar can be downloaded from this link:
http:// pepper.eu.com/ApplicationFiles/Download/791
build.gradle
(example for the libs
directory):
compile fileTree(include: [’*.jar’], dir: ’libs’)
For example:
dependencies { compile fileTree(include: [’*.jar’], dir: ’libs’)
// other dependencies omitted
}
PepperCore.jar
to the application
module’s build.gradle
(example for the
libs
directory):
compile files(’libs/PepperCore.jar’)
For example:
dependencies { compile files(’libs/PepperCore.jar’)
// other dependencies omitted
}
build.gradle
has been sync’d,
the library should not be imported.
PepperCore.jar
in the
libs
folder of the project.
File > Project Structure
.
PepperCore.jar
and click
OK.
The architecture of the CBR System inside a CBR core.
This core holds the CBR classes within three main
packages: CBR
, IO
and
PEPPER
:
Core.CBR
Location:.\src\Core\CBR
This package contains the CBR
class, the
main class for cbr execution that calls all other classes
to perform the cycle. The package also contains the
following data and method packages needed for the
execution:
Distances
Location:.\src\Core\CBR\Distances
This package contains the classes to compute distances between Populations, its Individuals and their Attributes.
Globals
Location:.\src\Core\Distances\Globals
This package contains the classes to compute different
kinds of distance between all the Individuals of the
train Population towards the Individuals in the test
Population, considering all of their Attributes. These
classes extend the abstract class
GlobalDistance
, and are to be built through
the GlobalDistanceFactory
class.
Locals
Location:.\src\Core\Distances\Locals
This package contains the classes to compute different
kinds of distance between all the Individuals of the
train Population towards the Individuals in the test
Population, considering only one specific Attribute. The
LocalDistance
class used for an Attribute
should match its signature (i.e. don’t use
LocalDistanceEuclidean
for text Attributes).
These classes extend the abstract class
LocalDistance
, and are to be built through
the LocalDistanceFactory
class.
Unknown Location:.\src\Core\Distances\Unknown
This package contains the classes to compute different
kinds of distance between all the Individuals of the
train Population towards the Individuals in the test
Population, considering only one specific Attribute, for
which at least one of said Individuals lacks its value.
These classes extend the abstract class
Missing
, and are to be built through the
MissingFactory
class.
Location:.\src\Core\CBR\Models
This package contains the data structures to hold the
necessary information for the multiple computations of
the cbr cycle. The basic, most used classes in this
package are Attribute
,
Individual
and Population
.
Attribute
This class defines the properties of one of the multiple features of each case. It holds its identifier, its description, its type, and its weight.
Individual
This class defines a case. It holds an identifier, and
the values of all its features. It also references the
Population
to which the
Individual
belongs.
Population
This class defines a case base. It holds all of its
Individuals
and a collection of Attributes,
indicating which features its Individuals hold, and its
type. This package also contains, in the
Reuse
inner package, the data structures to
hold the outputs of the said computations.
Results
Location:.\src\Core\Models\Results
This package contains the classes needed to hold the data resulting from the cbr computations, such as distance matrixes, Population classifications, selections, etc.
Location:.\src\Core\CBR\Retrieve
Contains both the context reasoning and case selection methods.
Context filtering Location:.\src\Core\CBR\Retrieve\ContextReasoning
The classes in this package are built for the purpose of
filtering cases from a Population
, keeping
only those with features than meet specific criteria.
These classes extend the abstract class
ContextReasoning
, and are to be built
through the ContextReasnongFactory
class.
Selection
Location:.\src\Core\CBR\Retrieve\Selection
The classes in this package are built for the purpose of
selecting similar train cases (from the CBR’s train
Population) for every test case (from the CBR’s test
Population). Each class may select a different number of
cases meeting different specific criteria. These classes
extend the abstract class Selection
and are
to be built through the SelectionFactory
class.
Location:.\src\Core\CBR\Reuse
The classes in this package are built for the purpose of
classifying every test case considering the data of the
train cases selected for it in the Retrieve phase. These
classes extend the abstract class Reuse
and
are to be built through the ReuseFactory
class.
Location:.\src\Core\CBR\Revise
The classes in this package are built for the purpose of
checking whether the classification made in the Reuse
phase is correct, and make any possible corrections to
each misclassified case. These classes extend the
abstract class Revise
and are to be built
through the ReviseFactory
class.
Location:.\src\Core\CBR\Retain
The classes in this package are built for the purpose of
deciding which already classified test cases can be
useful as train ones, and add those meeting the criteria
to the train Population. These classes extend the
abstract class Retain
and are to be built
through the RetainFactory
class.
Location:.\src\Core\CBR\Review
The classes in this package are built for the purpose of
deciding which cases from the train Population are truly
relevant and which can be dropped following specific
criteria, in order to keep the case base as small as
possible without losing relevant information. These
classes extend the abstract class Review
and
are to be built through the ReviewFactory
class. It includes the restore procedures.
Location:.\src\Core\CBR\Exceptions
This package contains exception classes to clarify cbr execution errors and pinpoint them easily whenever they appear.
Location .\src\Core\BaseLearners
This package contains the classes intended for machine learning execution over the weights given to the features of the cases.
Location:.\src\Core\DistributedApproaches
This package contains the classes built for the purpose
of executing cbr functionalities in a distributed way.
The implemented distributed functionalities are both the
cbr cycles, in MultiAgent
, and the weight
learning phase, in MetaCBR
:
MultiAgent
Location:.\src\Core\DistributedApproaches\MultiAgent
Package which classes are intended for the distributed execution of multiple cbr cycles.
MetaCBR
Location:.\src\Core\DistributedApproaches\MultiAgent
Package which classes are intended for the distributed execution of a generic algorithm to learn the best Attribute weights for the cbr Populations.
Location:.\src\Core\Tools
This package holds multiple classes intended to encapsulate and reuse code of basic functionalities used throughout the whole of the cbr execution, such as statistics computation, string manipulation, etc.
Location:.\src\Core\IO
The IO
package contains the classes for
saving and reading data in CSV or JSON formats.
Location:.\src\Core\IO\Access2CSV
Location:.\src\Core\IO\Exceptions
This package contains exception classes to clarify in and out operation errors and pinpoint them easily whenever they appear.
Location:.\src\Core\IO\JSON
This package holds the Google’s Gson library for JSON
construction and reading. It also holds the custom
Jsoner
class, which for a given class allows
to transform its objects to a JSON string and from JSON a
String instantiates the original class object.
Location:.\src\Core\IO\PEPPER
This package holds the classes to allow building and
reading of the PEPPER standard JSONS from the cbr data.
This is needed because the Gson package needs an actual
object with the exact instantiation the JSON is
describing in order to make this JSONS and create objects
form them. It also contains a Manager
class,
which encapsulates the multiple Jsoners for all needed
data classes and has methods to build the said PEPPER
standard JSONS
and JSON
objects.
PEPPER
This package holds the classes intended to preprocess
incoming data into the format intended for the cbr
execution. For instance, it holds the
PhysicalActivity
class, which quantifies
steps into PhysicalActivity intensity.
The first step is to set the parameters of the CBR. The
easiest way to define the parameters is to use an
interpreter such as the PepperInterpret
(Section 5.2). The following
instructions create the interpret and define the patient
profile:
InterpretPepper interpret = new InterpretPepper();
interpret.setPatientData(patientGlow,patientGhigh,patientGsetpoint,
patientCHOmean,patientWeight);
The next instruction builds a CBR with train and test populations:
CBR cbr = interpret.construeixCBR(test,train);
These populations can both be null, and set afterwards
through the methods setTrain(Population) and
setTest(Population). The train and test populations will
be built from JSON
objects, seen in Section 5.3. The train population should
contain the list of individuals from the case base of the
given user, while the test population will contain only
one individual, that is a CBR JSON
object.
The train population will be built from a full population
JSON
object:
Population train = Manager.populationFromJSON(trainJSON);
cbr.setTrain(train);
The test population should be conformed of just one
individual, that is the current case of the patient,
built from a JSON CBR
object that should be
filled with the corresponding patient data. To build a
new population with just one individual, the JSON
Manager
will require an attributes
JSON
, seen in Section
5.4, with the list of attributes of the individual:
Population test = new Population();
test.setAttributes( Manager.attributesFromJSON( attributesJSON ) );
test.addIndividual( Manager.individualFromJSON( testIndividualJSON ) );
The required values to be initialised in the JSON
CBR
object, seen in Section
5.3, are:
PatiendId
CaseId
datetime
timeofday
typeofday
PremealBloodGlucose
PastPhysicalActivityIntensity
PastPhysicalActivityType
FuturePhysicalActivityIntensity
FuturePhysicalActivityType
BasalDose
InsulinOnBoard
CarbsOnBoard
Carbohydrates
Fats
AlcoholType
AlcoholQuantity
HoursOfSleep
PsychologicalStress
Happiness
Tiredness
HormoneCycle
Fever
DigestiveIllness
Medication
AmbientTemperature
Execute the Retrieve step with this instruction:
cbr.retrievePepper();
Execute the Reuse step with this instruction:
cbr.reusePepper();
This steps fill the ICRreuse
,
ISFreuse
and BolusReuse
attributes in the case. Convert the full test population
to JSON, or alternatively, convert just the current case
to JSON and send it to the server if it is necessary:
String testPopuJSON = Manager.toJSON( cbr.getTest() );
String testCaseJSON = Manager.toJSON( cbr.getTest().getIndividual(0) );
Before to perform this step, the following attributes should be filled:
ICRsafety
: ICR (insulin to carbs ratio)
value returned by safety system
ISFsafety
: ISF (insulin sensitivity
factor) value returned by the safety system
BolusSafety
: Bolus value returned by the
safety system
ICRuser
: ICR value calculated from the
bolus administered by the user (Section 5.1.4)
ISFuser
: ISF value calculated from the
bolus administered by the user (Section 5.1.2)
BolusUser
: final bolus administered by the
user
PostprandialMinGlucose
: minimum value of
the postprandial blood glucose. It can be calculated
from SafetyObject.CGM[].MeasuredValue
of
the JSON safety system object.
The following code executes the Revise step to correct
the solution and fill the revise values
ICRrevise
(Section
5.1.1), BolusRevise
(Section 5.1.3), ISFrevise
(Section 5.1.2):
cbr.revise();
This is the instant in which traceability of the patient can be stored. It can be done saving the JSONs of the test, train and attribute data in one or separated files:
serverTrain = Manager.toJSON( cbr.getTrain() ); serverTest = Manager.toJSON( cbr.getTest() ); serverAtt = Maneger.toJSON( cbr.getTrain().getAttributes() );
Execute the Retain step to add the new case to the case base:
cbr.retain();
The Review phase remove all the unnecessary cases:
cbr.review();
Execute the weight Learning phase:
cbr.weightLearning();
On the present section some of the used equations are explained.
The following equation is used in order to calculate the ICR revised during the revision step.
On where:
The following equation is used in order to calculate the Insulin sensitivity factor (ISF).
On where:
The following equation is used in order to calculate the bolus in the reuse step.
On where:
The following equation is used in order to calculate the ICR on several steps.
On where:
The following code is need in order to chose the methods there is the intention to use:
package pepperapp; import Core.CBR.Retrieve.Selection.Selection; import Core.CBR.Retrieve.ContextReasoning.ContextReasoning; import Core.CBR.Distances.Locals.LocalDistance; import Core.CBR.Distances.Globals.GlobalDistance; import Core.CBR.CBR; import Core.CBR.Exceptions.FactoryException; import Core.CBR.Models.*; import Core.CBR.Reuse.*; import Core.CBR.Revise.*; import Core.CBR.Retain.*; import Core.CBR.Review.*; import Core.BaseLearners.LearningAttributeWeights.LearnNot; import Core.BaseLearners.LearningAttributeWeights.LearningAttributeWeights; import Core.CBR.Distances.Globals.*; import Core.CBR.Distances.Locals.*; import Core.CBR.Distances.Unknown.*; import Core.CBR.Retrieve.ContextReasoning.FilteringByContext; import Core.CBR.Retrieve.Selection.SelectionNK; public class InterpretPepper{ // Default patient data, must be set to real values before revise step; double Glow = 5; double Ghigh = 7; double Gsetpoint = 6; double CHOmean = 70; double weight = 70; public InterpretPepper() { } public CBR construeixCBR(Population test, Population train) throws FactoryException { /** Distance computing objects */ Missing desconeguts = new SkipMissingFromTest(); GlobalDistance dist_glob = new GlobalDistanceWM(); LocalDistance dist_loc_num = new LocalDistanceEuclidean(); dist_loc_num.setMissingMethod(desconeguts); LocalDistance dist_loc_disc = new LocalDistanceEuclidean(); dist_loc_disc.setMissingMethod(desconeguts); LocalDistance dist_loc_text = new LocalDistanceBoolean(); dist_loc_text.setMissingMethod(desconeguts); LocalDistance dist_loc_data = new LocalDistanceDateStandard(); dist_loc_data.setMissingMethod(desconeguts); LocalDistance dist_loc_seq = new LocalDistanceSequencesDIST4MADCAPPablo(); dist_loc_seq.setMissingMethod(desconeguts); dist_glob.setLocalDistances(dist_loc_num, dist_loc_disc, dist_loc_text, dist_loc_data, dist_loc_seq); /** CBR phases objects */ Selection sel = new SelectionNK();sel.addParameters("3"); // Reuse reuse = new //ReuseMajoriaK();reuse.afegeixParametres("1"); Reuse reuse = new ReuseNumericSimilarityBased();reuse.afegeixParametres("3"); Revise revise = new RevisePepper(); ((RevisePepper)revise).setPatientData(Glow, Ghigh, Gsetpoint, CHOmean, weight); Retain retain = new TemporalAdaptiveRetain(); Review review = new ReviewPepper_CRR(); /** Medicines, illnesses, fever and hormone cycle have to match **/ ContextReasoning filter = new FilteringByContext(); filter.addParameters(/*"Drugs;=;"+*/"digestiveIllness;=;"+"fever;=;"+"hormonecycle;="); LearningAttributeWeights learn = new SalzbergModified("ICRrevise"); CBR cbr = new CBR(train, test, dist_glob, sel, reuse, revise, retain, "ICRrevise"); cbr.afegeixReview(review); cbr.afegeixLearn(learn); cbr.afegeixFiltrat(filter); return cbr; } public void setPatientData( double Glow, double Ghigh, double Gsetpoint, double CHOmean, double weight ){ this.Glow = Glow; this.Ghigh = Ghigh; this.Gsetpoint = Gsetpoint; this.CHOmean = CHOmean; this.weight = weight; } }
Description: this section describes how the case file is composed.
[ { "attributes": { "PatientId": "null", "CaseId": "null", "datetime": " null", "timeofday": "null", "typeofday": null, "PremealBloodGlucose": "null", "UserPastPhysicalActivityIntensity": "null ", "UserPastPhysicalActivityType": " null ", "PastPhysicalActivityIntensity": " null", "PastPhysicalActivityType": "null", "FuturePhysicalActivityIntensity": "null", "FuturePhysicalActivityType": "null", "BasalDose": "null", "InsulinOnBoard": "null", "CarbsOnBoard": "null", "Carbohydrates": "null", "Fats": "null", "MealAbsorptionRate": "null", "AlcoholType": "null", "AlcoholQuantity": “null", "HoursOfSleep": "null", "PsychologicalStress": null, "Happiness": "null", "Tiredness": "null", "HormoneCycle": "null", "Fever": "null", "DigestiveIllness": "null", "Medication": null, "AmbientTemperature": "null", "ICRreuse": "null", "ISFreuse": "null", "BolusReuse": "null", "TypeOfBolus": "null", "ICRsafety": "null", "ISFsafety": "null", "BolusSafety": "null", "ICRuser": "null", "ISFuser": "null", "BolusUser": "null", "PostprandialMinGlucose": "null", "ICRrevise": "null", "ISFrevise": "null", "BolusRevise": "null", "ExpertValidation": "null", "RejectCase": "null", "ReusedCases": "878718a6-cdb8-4757-95a4-9b593cb6de3f" }, "id": "null" } ]
Description: this section describes how the attributes file is composed.
[ { "id": "patientid", "description": "patientid", "type": -1, "weight": 1.0 }, { "id": "caseid", "description": "caseid", "type": -1, "weight": 1.0 }, { "id": "datetime", "description": "datetime", "type": -1, "weight": 1.0 }, { "id": "timeofday", "description": "timeofday", "type": 1, "weight": 1.0 }, { "id": "typeofday", "description": "typeofday", "type": 1, "weight": 1.0 }, { "id": "premealbloodglucose", "description": "premealbloodglucose", "type": -1, "weight": 1.0 }, { "id": "userpastphysicalactivityintensity", "description": "userpastphysicalactivityintensity", "type": -1, "weight": 1.0 }, { "id": "userpastphysicalactivitytype", "description": "userpastphysicalactivitytype", "type": -1, "weight": 1.0 }, { "id": "pastphysicalactivityintensity", "description": "pastphysicalactivityintensity", "type": 1, "weight": 1.0 }, { "id": "pastphysicalactivitytype", "description": "pastphysicalactivitytype", "type": -1, "weight": 1.0 }, { "id": "futurephysicalactivityintensity", "description": "futurephysicalactivityintensity", "type": 1, "weight": 1.0 }, { "id": "futurephysicalactivitytype", "description": "futurephysicalactivitytype", "type": -1, "weight": 1.0 }, { "id": "basaldose", "description": "basaldose", "type": -1, "weight": 1.0 }, { "id": "insulinonboard", "description": "insulinonboard", "type": -1, "weight": 1.0 }, { "id": "carbsonboard", "description": "carbsonboard", "type": -1, "weight": 1.0 }, { "id": "carbohydrates", "description": "carbohydrates", "type": -1, "weight": 1.0 }, { "id": "fats", "description": "fats", "type": -1, "weight": 1.0 }, { "id": "mealabsorptionrate", "description": "mealabsorptionrate", "type": 1, "weight": 1.0 }, { "id": "alcoholtype", "description": "alcoholtype", "type": -1, "weight": 1.0 }, { "id": "alcoholquantity", "description": "alcoholquantity", "type": 1, "weight": 1.0 }, { "id": "hoursofsleep", "description": "hoursofsleep", "type": -1, "weight": 1.0 }, { "id": "psychologicalstress", "description": "psychologicalstress", "type": 1, "weight": 1.0 }, { "id": "happiness", "description": "happiness", "type": -1, "weight": 1.0 }, { "id": "tiredness", "description": "tiredness", "type": 1, "weight": 1.0 }, { "id": "hormonecycle", "description": "hormonecycle", "type": -1, "weight": 1.0 }, { "id": "fever", "description": "fever", "type": -1, "weight": 1.0 }, { "id": "digestiveillness", "description": "digestiveillness", "type": -1, "weight": 1.0 }, { "id": "medication", "description": "medication", "type": -1, "weight": 1.0 }, { "id": "ambienttemperature", "description": "ambienttemperature", "type": -1, "weight": 1.0 }, { "id": "icrreuse", "description": "icrreuse", "type": -1, "weight": 1.0 }, { "id": "isfreuse", "description": "isfreuse", "type": -1, "weight": 1.0 }, { "id": "bolusreuse", "description": "bolusreuse", "type": -1, "weight": 1.0 }, { "id": "reusedcases", "description": "reusedcases", "type": -1, "weight": 1.0 }, { "id": "typeofbolus", "description": "typeofbolus", "type": -1, "weight": 1.0 }, { "id": "icrsafety", "description": "icrsafety", "type": -1, "weight": 1.0 }, { "id": "isfsafety", "description": "isfsafety", "type": -1, "weight": 1.0 }, { "id": "bolussafety", "description": "bolussafety", "type": -1, "weight": 1.0 }, { "id": "bolususer", "description": "bolususer", "type": -1, "weight": 1.0 }, { "id": "isfuser", "description": "isfuser", "type": -1, "weight": 1.0 }, { "id": "icruser", "description": "icruser", "type": -1, "weight": 1.0 }, { "id": "postprandialminglucose", "description": "postprandialminglucose", "type": -1, "weight": 1.0 }, { "id": "bolusrevise", "description": "bolusrevise", "type": -1, "weight": 1.0 }, { "id": "icrrevise", "description": "icrrevise", "type": -1, "weight": 1.0 }, { "id": "isfrevise", "description": "isfrevise", "type": -1, "weight": 1.0 }, { "id": "expertvalidation", "description": "expertvalidation", "type": -1, "weight": 1.0 }, { "id": "rejectcase", "description": "rejectcase", "type": -1, "weight": 1.0 }, ]