Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/notebooks/glucose.ipynb
Views: 531
Modeling and Simulation in Python
Chapter 18
Copyright 2017 Allen Downey
Code from the previous chapter
Read the data.
Interpolate the insulin data.
Initialize the parameters
To estimate basal levels, we'll use the concentrations at t=0
.
Create the initial condtions.
Make the System
object.
Numerical solution
In the previous chapter, we approximated the differential equations with difference equations, and solved them using run_simulation
.
In this chapter, we solve the differential equation numerically using run_ode_solver
, which is a wrapper for the SciPy ODE solver.
Instead of an update function, we provide a slope function that evaluates the right-hand side of the differential equations. We don't have to do the update part; the solver does it for us.
We can test the slope function with the initial conditions.
Here's how we run the ODE solver.
details
is a ModSimSeries
object with information about how the solver worked.
results
is a TimeFrame
with one row for each time step and one column for each state variable:
Plotting the results from run_simulation
and run_ode_solver
, we can see that they are not very different.
The differences in G
are less than 1%.
Optimization
Now let's find the parameters that yield the best fit for the data.
We'll use these values as an initial estimate and iteratively improve them.
make_system
takes the parameters and actual data and returns a System
object.
error_func
takes the parameters and actual data, makes a System
object, and runs odeint
, then compares the results to the data. It returns an array of errors.
When we call error_func
, we provide a sequence of parameters as a single object.
Here's how that works:
leastsq
is a wrapper for scipy.optimize.leastsq
Here's how we call it.
The first return value is a Params
object with the best parameters:
The second return value is a ModSimSeries
object with information about the results.
Now that we have best_params
, we can use it to make a System
object and run it.
Here are the results, along with the data. The first few points of the model don't fit the data, but we don't expect them to.
Interpreting parameters
Based on the parameters of the model, we can estimate glucose effectiveness and insulin sensitivity.
Here are the results.
Under the hood
Here's the source code for run_ode_solver
and leastsq
, if you'd like to know how they work.
Exercises
Exercise: Since we don't expect the first few points to agree, it's probably better not to make them part of the optimization process. We can ignore them by leaving them out of the Series
returned by error_func
. Modify the last line of error_func
to return errors.loc[8:]
, which includes only the elements of the Series
from t=8
and up.
Does that improve the quality of the fit? Does it change the best parameters by much?
Note: You can read more about this use of loc
in the Pandas documentation.
Exercise: How sensitive are the results to the starting guess for the parameters? If you try different values for the starting guess, do we get the same values for the best parameters?
Related reading: You might be interested in this article about people making a DIY artificial pancreas.