[How I Use Machine Learning to Calculate My Son’s Type 1 Diabetes Insulin Pump Settings]
March 1st, 2023 - Estimated Read Time: 20 minutes
Update: April 19, 2023
Given there has been much more interest in this article than I anticipated, I've released my code for free as a package called InsuLearner as well as a follow-up article on how to install and run the software. But read this article first!
Disclaimer #1: I am not a doctor and this is not medical advice. I am sharing my ideas openly in case
they are helpful to a
diabetes community that has given a lot to help me and my family. Check with your doctor before
making
any changes to insulin pump settings.
Disclaimer #2: I have worked in machine learning for 10 years in the music, healthcare, and web domains.
This includes my
time as a data scientist with the diabetes data non-profit Tidepool,
where I originally
developed the pump settings estimation approach described below and built risk simulators for their
FDA-cleared closed-loop insulin delivery system, Tidepool Loop. It is
easy
to deceive yourself with machine learning. Check with your doctor before
making
any changes to insulin pump settings.
Table of Contents
- Background
- The Common Insulin Dosing Model
- Learning an Insulin Dosing Model
- Backdoor to Insulin Sensitivity Factor
- Estimating My Son's Settings From His Data
- Comparing to AACE Guidelines
- FAQ
- Conclusion
Background
My son was diagnosed with Type 1 Diabetes in 2017 when he was 14 months old. Anyone who has Type 1 or
knows someone with Type 1 is aware this is a burdensome condition. My son wears multiple medical
devices, and my wife and I count every carbohydrate he consumes. Each carbohydrate requires an insulin
dose, and slightly too much or too little insulin can be dangerous. Monitoring and controlling his blood
glucose requires constant vigilance every day and night for his lifetime. In short, it is hard.
While Type 1 diabetes sucks, the technology has improved immensely over the last several decades to make
it suck less. My son's Dexcom Continuous Glucose Monitor (CGM) lets me
monitor his blood glucose on my
phone. His Omnipod Dash insulin pump delivers precise amounts of
insulin
requiring fewer needle pokes.
And there exists in recent years a “brain”, called a Closed-Loop System or Artificial Pancreas, that
connects these devices and automatically delivers a dosage of insulin every 5 minutes.
These technology advances are amazing, but the person with Type 1 or their caregiver is still left to
figure out how much insulin to dose many times per day, even on closed-loop systems. It’s an extremely
finicky task since the dose is significantly affected by dozens of factors that are constantly changing
or even totally unknown, including amount of food, type of food, exercise, sickness, and growth
hormones. Many insulin pumps and closed-loop systems have an insulin dose calculator aimed to reduce
this complexity, but the calculator is heavily dependent on user-inputted settings. And the settings
that give dosage for good blood glucose control vary considerably from person to person based on things
like age, weight, time since diagnosis, etc. To my knowledge as of this writing, there is no
straightforward way for an individual with Type 1 to determine settings that will give reliably accurate
insulin doses. If you enter in “wrong” settings, blood glucose control can be poor, potentially
leading to dangerous situations.
Trying to establish good settings can be an extremely frustrating process. I know from personal
experience. Commonly, someone with Type 1 will make an initial guess, maybe with the help of an
endocrinologist or based on some basic formulas I’ll cover below, and then try to dial the settings in
through trial and error. But analyzing the blood glucose response to small adjustments of one or more of
these settings can easily lead to false conclusions about how to tweak the settings next. Insulin pumps
and closed-loop systems even allow for settings that can vary throughout the day, increasing the
complexity significantly. Especially for a child with Type 1 that is growing like my son, their body’s
insulin requirements - and thus the pump settings - change regularly. So there is a clear need for
better ways to personalize settings in the calculators, which is what led me to search for another
approach.
The Common Insulin Dosing Model
There are three main parameters in the dosing model that are input directly into insulin pumps and
closed-loop systems: Basal Rate, Carbohydrate Ratio (CIR), and Insulin Sensitivity Factor (ISF).
These
are used to compute insulin doses for three categories of glucose, respectively: glucose produced by the
body, glucose from consuming carbohydrates, and glucose from any unaccounted source.
The Basal Rate is a constant dosage over time of insulin intended to control for the glucose produced
within the body. Its units are units of insulin per hour (U/hr). Insulin pumps will deliver this as a
sort of “drip”, or people may use a long-acting insulin to approximate it.
The CIR computes how much insulin is given for consumed carbohydrates. Its units are grams of
carbohydrates per unit insulin (g / U). If a person’s CIR = 10 g / U that means a unit of insulin should
negate the rise in blood glucose from eating 10 grams of carbohydrates. And if that person were to eat a
meal that contains 50g carbohydrates, the bolus insulin to deliver is computed as Insulin = 50 / 10 =
5U.
The ISF is used to dose insulin to lower blood glucose when it is above a desired level. Its units
are the
aggregate change of blood glucose concentration in mg/dL per unit insulin (mg/dL / U). If a person’s ISF
= 100 mg/dL / U that means their blood glucose would be lowered by 100 mg/dL after a unit of insulin was
fully absorbed. For example, to compute the insulin amount to lower blood glucose from 300 mg/dL to a
level of 100 mg/dL, Insulin = (300 - 100) / 100 = 2U.
The ISF is of particular interest to many because it is used when glucose is unexpectedly high, which
occurs frequently and for many reasons. Some of these reasons include estimating too few carbs for a
meal, more glucose produced in the body than Basal Rate can manage, incorrect Basal Rate or CIR
settings, pump-site swelling hindering insulin absorption, adrenaline spike, and sickness.
Since the settings of the model are important and tweaking settings by trial and error is difficult, it
begs the question: can we use a person’s diabetes data to get a personalized estimate of their settings?
Yes. In fact the current
guidelines from the American Association of Clinical Endocrinology
(AACE) have equations for data-derived settings. The problem with these equations is that they aren’t
accurate for many people, including my son. The equations represent a high bias model, using
only a single piece of information about a person: the average of the Total Daily Dose (TDD) of insulin.
So then the question becomes: given the richness of diabetes data, can we use more data about a person
to get a more accurate prediction? Drawing on my background in machine learning and signal processing, I
developed the approach below that I now use and works well for my family.
Learning An Insulin Dosing Model
One way to approach learning the settings from data would be to try to predict the settings directly
from some data about a person by learning from a population. This is how the AACE recommendations above
work, which take in a person’s
TDD and output settings. To improve the accuracy of the AACE equations, we could increase the
complexity of the modeling, for example, by including more inputs in addition to TDD that affect insulin
needs
such as age, weight, or time since diagnosis. We should note that as we add more inputs, we need more
data due to the curse of
dimensionality in machine learning. But getting a lot of data for a large population is hard to
come by. Health data is
highly protected and rightly so. And even if we had a large dataset to learn
from, there are still pitfalls. For example, it can be difficult to know if a person’s settings are
“correct” in the dataset
even if they exhibit well-controlled blood glucose since behavior can make up for an inappropriate
setting.
In considering alternative solutions using data more readily available, I noticed that the settings
already function as a linear prediction model, which is helpful as a starting point. For
example, the CIR setting is trying to predict the amount of insulin (I) based on an input of the amount
of carbohydrates consumed (G) such that the sum of changes in blood glucose is zero after all the
insulin and carbohydrates are absorbed. If we describe this as an equation in the form y = m*x + b, we
have:
Note the inverse of CIR is the slope of the line. And if we plot the line described by this equation we get the blue line below.
This is a visual representation of how we typically conceive of using the CIR to determine an insulin dose. When we want to eat some carbs, we find the amount of carbs on the x-axis, go up to the blue line, and give the corresponding insulin value on the y-axis. And if the CIR (inverse of the slope) is correct, the net change in blood glucose after absorption will be zero.
Many people with insulin pumps actually have data on carbohydrates and insulin, so why not fit a line to that data and invert its slope to get a CIR? In practice this does not work well. As I mentioned previously, we need to use “correct” data (called ground truth data in ML) to fit the line. In historical diabetes data, this is surprisingly hard to come by. The carbs are possibly incorrect estimates and the insulin given for those carbs is computed by a probably incorrect CIR. And even if we try to cleverly deduce the correct amount of insulin for a meal retroactively, for example, we run into all kinds of problems such as multiple overlapping insulin and carb events that introduce a lot of noise.
It turns out that we can address our lack of ground truth data and make a more powerful model at the same time through a series of deductions about how the settings work. First, one of the inherent assumptions in the settings is they are event and time independent. In other words, usually we use the settings for a single meal event or single correction bolus event. But the settings don't assume that. The settings will predict the same amount of insulin for a single meal of 200g carbohydrates in one evening or for 8 meals of 25g carbohydrates in one week. Both of these scenarios actually fall on the same point on our blue plotted line above. This has an important implication: we can actually use a combination of multiple events in some time period to represent the correct amount of insulin for just a single event.
Further developing this idea, as we lengthen the time period containing multiple events representing a single data point, that period of time includes an increasingly higher percentage of fully absorbed carbs and insulin. So overlapping absorption of carbohydrates and insulin - one of the main sources of noise in using single events - are mitigated. One crucial point is as long as a person continues to take whatever insulin is needed to control their blood glucose in the time period (i.e. blood glucose doesn't go to infinity as carb events go to infinity), combining multiple events has the effect of increasingly making the amounts of total insulin and total carbs a less noisy “correct” match (Technical aside: I believe there may be a relation to a consistent estimator via the law of large numbers). Also, we can smartly choose the boundaries of the time period - for example during sleep when there is less event activity - to reduce noise even further.
That’s pretty cool, but you might notice one problem. Our combined insulin events in those time periods also include insulin events that were not related to the user-inputted meal carbohydrates such as correction boluses. But actually this turns out to be a feature instead of a problem when we take advantage of another pair of assumptions in the settings: 1) The settings assume the additional insulin we’ve included beyond consumed carbs is due to glucose produced in the body. And 2) the settings assume that glucose produced in the body is constant over time. With this in mind, we can add a constraint to our time periods that they must be equal duration. When we apply this constraint in the plot, it manifests as an upward shift in our linear model as shown below.
That is because for any point on the blue line - all equal data durations now - all of the “extra” insulin records in the time period are automatically categorized as Basal insulin needed for the constant endogenous glucose. Looking at the y-intercept (green dot) for this new linear model you might already recognize that this represents the total amount of Basal insulin required in the time period for that endogenous glucose! And we can easily convert the y-intercept to a Basal Rate by dividing the y-intercept value by the number of hours in the time period!
Now if we fit a line using data under the constraints described above, the parameters of that line (slope and y-intercept) will directly give us a CIR and Basal Rate that best predict the person’s insulin needs. Updating our linear model's equation it now predicts the amount of combined basal and carbohydrate insulin in the absorption period:
where TBI is Total Basal Insulin.
This is great because this requires only data from one person as opposed to a whole population. And that data is regularly available for many people. I’ll discuss further how I do this in practice with my son’s actual data as well as some caveats, but first we still have to consider the ISF.
A Backdoor to Insulin Sensitivity Factor (ISF)
Now that we’ve established a way to learn CIR and Basal Rate together from data, what about the ISF? The
ISF doesn’t neatly come out of the linear model above, but it is closely related by another value called
the Carbohydrate Sensitivity Factor (CSF). The CSF describes the total increase in blood glucose from
eating a gram of carbohydrate after the carbohydrate has been fully absorbed into the blood. Its units
are total change in blood glucose per gram carb (mg/dL / g). More concretely, suppose a person’s CSF is
5 mg/dL / g. When they are about to eat 10g carbohydrates with a starting blood glucose of 120 mg/dL,
the CSF says their blood glucose will have a total increase of CSF * 10 = 5 *
10 = 50 mg/dL. So their final blood glucose after the 10g carbs are fully absorbed will be 120 + 50 =
170 mg/dL.
We’re talking about ISF. Why are we bothering with CSF? Essentially, we want to estimate the CSF in
order to compute the ISF. This might seem like unneeded complexity, but bear with me. It makes for
better settings estimation.
The way CSF is related to ISF is that it is equivalent to the ratio ISF / CIR. So as an equation:
And then to compute ISF we rearrange that equation:
From this perspective, the ISF works in tandem with CIR to be essentially an inverse multiplier to the rise from “unknown” carbohydrates. As an example, suppose the CIR in our example above was estimated to be 12 g/U and suppose we didn’t give insulin for 10g of carbs that brought blood glucose of 170 mg/dL. The CIR says we should have given Insulin = 12 / 10 = 1.2U for those carbs. But if we pretend that we didn’t know about those carbs in the first place and simply observed the rise in blood glucose as the body processed them (a simulation of when blood glucose is high for an unknown reason), the ISF in the settings framework should also predict 1.2U is needed to lower blood glucose back to 120 mg/dL - i.e. the same amount of insulin that the CIR initially predicted. And that ISF is CIR * CSF = 12 * 5 = 60 mg/dL / U.
So why estimate CSF instead of estimating the ISF directly? Don’t we estimate them both in similar ways by observing changes in blood glucose for an input of carbs or insulin, respectively? Yes, they are measured similarly, but there are several reasons I use this approach. Those reasons generally fall into two categories: 1) it’s easier to get a cleaner estimate of CSF than ISF and 2) it helps ensure a better representation of the underlying biological processes we’re trying to model. I’ll discuss this a bit more in the next section, but if you're tired of reading and just want to believe me, jump to the section on settings estimation with actual data.
Noise in Estimating ISF vs CSF
Estimating ISF from day to day historical data is quite noisy since there are so many unknown factors that influence glucose observations. So one way to get a less noisy estimate is a more controlled experiment where we purposely reduce factors influencing blood glucose over the course of insulin absorption. As an example, we give an insulin bolus when blood glucose is relatively high, wait several hours for the insulin to fully absorb without giving more insulin or eating anything, and then measure the change in blood glucose to compute ISF. And then maybe repeat this many times and take an average of the measurements. But this is a challenge, especially for children, and still can have interference in the experiment.Compare this to the same process for estimating CSF: Eat a 5g glucose tablet in the morning when blood glucose is stable and in range, wait 30-40 minutes for glucose to fully absorb without giving insulin or eating anything, and then measure the change in blood glucose to compute CSF. Since this experiment is much shorter compared to the one above, it is easier to do (especially for children) and we’re less likely to have interference from other factors. Another reason we may have a cleaner CSF measurement is the body is not used to insulin delivery outside of a pancreas. So the ISF measurement may have more unwanted influences such as pump-site swelling. When measuring the CSF in contrast, eating carbohydrates is a more natural process and something the body has evolved to do.
A final more mathematical reason to use CSF instead of ISF is the CSF has been much more static over time than the ISF with my son. I have estimated my son’s CSF many times over the past 2 years since I developed this approach. Mostly this happens by accident when I give him something like a small piece of candy and forget temporarily to give insulin for it. But in general, the CSF measurements have been significantly more consistent than ISF measurements. In discussion with physicians on this topic, the biological process the CSF represents (i.e. the body breaking down consumed carbs into the blood) is likely tightly correlated to blood volume and body mass. So my son may need to grow significantly in order to see a significant change in his CSF. In contrast, his CIR has changed dramatically in the last two years as he’s grown, which means that his ISF has also changed dramatically due to how they move together in the equation above.
Computing ISF
In summary, the process I use to compute my son’s ISF is first estimating his CSF as described above. This has been in a fairly tight range averaging about 12.5 mg/dL / g. Then I take the CIR estimated from the linear model and compute ISF = CIR * 12.5. Since the CSF has been fairly constant, the ISF usually moves as a linear multiple of the new CIR estimate. This makes ISF largely an afterthought when I determine my son’s settings, which is ironic since it used to be the setting I was most concerned with.Estimating My Son's Settings From His Data
So finally, we have a framework for collecting historical data and using it to estimate the three
primary settings in the common insulin dosing model. The data discussion above indicated cleaner data
would be achieved for combining insulin and carbs over long and equal time periods where blood glucose
matched as well as possible at the time boundaries. In practice, my son’s closed-loop system tends to
bring him into range overnight. So I use the time periods beginning and ending at 6:00 am. I’ve found
that 24-hour durations tend to work reasonably well, though possibly multiple days per data point could
be better. There is a tradeoff in practice of choosing a longer absorption duration though. Longer
durations reduce noise but lose time resolution. If the time period is a month, the model can lose its
fidelity to accommodate more frequent (e.g. weekly) biological changes that affect insulin needs.
I downloaded a recent eight weeks of my son’s data using his Tidepool
account, which contains
all of his blood glucose readings from his Dexcom CGM and insulin from his Omnipod Dash pump. Combining
the insulin and carbohydrates totals in daily periods gives 56 data points, which are plotted below
(shared with my son’s permission) along with the fitted linear model.
You can see the data is nicely linear (R^2=0.79 goodness of fit) as we hope it would be. On the y-axis
are the total units of insulin delivered each day from 6:00am-6:00am. On the x-axis are the total
carbohydrates input in each day from 6:00am-6:00am. The linear model I fitted is the blue line
that goes through the data cloud. The purple box represents the estimated total daily basal insulin and
the orange triangle represents the estimated total daily insulin predicted for any amount of consumed
carbohydrates.
And in the lower right corner is the linear equation for the fitted model:
So to get my son’s insulin delivery settings I use the equations previously discussed:
Basal Rate = 6.23 / 24 = 0.3 U/hr
ISF = CIR * CSF = 13.06 * 12.5 = 163.29 mg/dL / U
These settings are my son’s current settings in his closed-loop system at the time of this writing and they are working well. We don't vary any settings throughout the day anymore. I found that the reduced complexity works better for us, and whatever time-based variability that may occur seems to be handled well by my son’s closed-loop system.
I have been using this ML approach for about 1.5 years to estimate his settings every few months as he has grown. It has nearly eliminated the headaches we had tweaking settings through trial and error. I’ll refrain from sharing A1C or Time in Range stats, even though I’m a huge proponent of evidence-based evaluation. Managing diabetes is a whole life experience, and it is poorly measured with blood glucose stats alone. But in moving to estimating his settings this way, we did see a clear improvement in his closed-loop system’s stability (and thus our need to intervene and how much we sleep) and his blood glucose control.
Comparison with AACE Guidelines
I think it’s helpful to understand how any proposed approach relates to other ways of thinking about
insulin pump settings. The most recent current
guidelines from American Association of Clinical
Endocrinology (AACE) for establishing ISF and CIR in a person with Type 1 suggests using the “1700 Rule”
and “450 Rule”, respectively. That is given a person's average Total Daily Dose (TDD) of insulin, ISF =
1700 / TDD and CIR = 450 / TDD.
For comparison, in the plot of my son’s data above is a red star in the middle of the data that
represents his TDD in the 8 week period, which is 17U. So based on the AACE guidelines and my son’s TDD:
ISF = 1700 / TDD = 1700 / 17 = 100 mg/dL / U
Similarly, Total Daily Basal (and thus basal rate) is often suggested to be set as 50% of the mean of his Total Daily Dose (TDD) of insulin. At 50% of TDD his basal rate would be set to 8.5U per day or 8.5 / 24 = 0.35 U/hr.
So if we compare directly the ML-derived settings to the AACE guidelines, we have very different values:
Setting Name | AACE Equations | ML Approach |
---|---|---|
CIR | 26 g / U | 13 g / U |
Basal Rate | 8.5 U / day | 6.2 U / day |
ISF | 100 mg/dL / U | 163 mg/dL / U |
The gray dotted line represents the linear prediction model but using the line parameters that would be representative of equations in the AACE guidelines. You can see it does not predict my son’s insulin needs very well. If he were to eat a lot of carbs (toward the right on the plot), the AACE settings would have under-predicted the amount of insulin he actually needed in that 24 hour time period. Similarly, when he ate very few carbs (toward the left), the AACE settings would have over-predicted the amount of insulin he actually needed in that 24 hour time period.
A note on the CSF and AACE settings: The CSF derived from these values is:
The TDD term cancels out so
This implies that anyone using these settings is expected to rise 3.8 mg/dL after absorbing 1g carb or 38 mg/dL after absorbing 10g carbs. This is nowhere near what I observe in my son, which would make me suspicious of the ISF computed by the AACE equations as well. But as discussed previously, the AACE guidelines are a high bias model. They are a sort of broad population average and may be expectedly unsuited for young children.
Another nice property of learning settings with the linear model is that unlike tweaking settings with trial and error, the linear model doesn’t rely on incremental improvements in previous settings. It predicts the best fitting settings directly from the historical data regardless of whether your settings in the historical data were incorrect. Instead, the ML approach relies on whether a person generally attempts to keep blood glucose in range within the selected time periods. So even if the initial bolus for a meal was too little due to an inappropriate CIR and caused high blood glucose, the ML method should work as long as more insulin was eventually given to bring blood glucose back towards a target.
FAQ
What if I don’t count carbs?
When learning anything from data there is a saying: “garbage in, garbage out”. In other words, the settings derived from a learned model are only as good as the data that goes into it. If you don’t at least try to count carbs somewhat accurately, this method will not work. But for many people who do count carbs, this may be a nice way to take advantage of that data.I think there is robustness in this approach to account for some types of noise in the data, but I have not analyzed how clean the data must be in order for this method to work well for anyone. My wife and I are pretty good about counting and entering carbs, but we often don’t enter low treatments or sometimes don’t enter other smaller amounts. Generally, I try to ensure what his closed-loop system sees is a fairly accurate representation of reality (e.g. no purposefully “fake” carbs).
(Technical aside: We can also analyze the hypothetical effects of certain carb counting errors. For example, if we were constantly underestimating carbohydrates, this would show up as a leftward shift of the true data on our plots. We would still get a reasonable fit of the data, but the model will assign the insulin for those “missing” carbs to the Basal Rate instead of CIR. In general, if we’re sometimes guessing too many carbs and sometimes guessing too few carbs, these errors should cancel out.)
How much data is needed to learn from?
Generally more data is better in machine learning. But for estimating settings that change over time, there can be too little data or too much data in certain circumstances. With too little data the estimation might be too noisy. I have not analyzed the amount of data required generally for robust estimation. And with too much history in the data, the model may not pick up on recent changes in insulin needs.I plotted 56 days of data above for this article, but I typically look at multiple plots of 15-60 days in the past and compare them when computing settings for my son. Sometimes my son has had a significant increased need for insulin (e.g. growth spurt) and using too much history biases the settings towards his insulin needs before his growth spurt.
Does this work for MDI?
One nice property of this approach is that it’s system-agnostic. It should work regardless of the insulin delivery system, even manual daily injections (MDI). The key is for the insulin and carbohydrate data to be recorded as accurately as possible.Are these ideas new?
I don’t know. I don’t keep up with the research in this area as much anymore. A few people with awareness in the industry with whom I’ve discussed this weren’t aware of its existence elsewhere.Anything else?
Use caution. I haven’t described any guardrails here for fitting the model, so it is possible to get a poorly fit model and wrong settings in some circumstances. Each time I compute new settings, I am extremely cautious about how I implement them in my son’s system. For example, if it computes a significant change to his CIR - and thus his ISF because they always move together with his CSF - I always sanity check and may only change them by a smaller amount at first and carefully observe for a day or two.Conclusion
I have no plans to push this approach anywhere, but will to continue to use it personally. I believe the
approach is promising and complementary to others that exist, though. So that’s why I’m sharing it
openly here using mostly non-mathematical language for broad accessibility in case the ideas are useful
to anyone in the diabetes community.
Also, I just covered the basics. It’s a significant effort to go down another level of detail, and I’m
not sure if there is interest. Let me know if that’s not the case. There are many more technical details
and also some interesting things (to me at least!) I’ve done in terms of weighting the data during
fitting according to glucose control or analyzing residuals once the model is fit.
Hopefully, the closed-loop systems will eventually be good enough that we don’t need any of this. Or
even better would be a cure so we can throw the systems away entirely! Please feel free to contact me
with questions or comments.