Scalable, Real-Time Heart Rate Variability Biofeedback for Precision Health: A Novel Algorithmic Approach
This tutorial offers foundational knowledge needed for building a real-time algorithm that provides heart rate variability biofeedback (HRV-B). To make this tutorial accessible for a broader audience, I used only python for these demonstrations, even though our final data science product actually required multiple languages. You can find all the tutorial notebooks in github at this link. To model HRV-B, you do need to understand a little bit about the science behind it, so we will pepper this tutorial with a little neurophysiology. Don’t worry, it won’t get too spicy.
What is Heart Rate Variability Biofeedback?
Heart rate variability biofeedback (HRV-B) is a clinically effective therapy, in which people can improve their mental and physical well-being by specialized breathing techniques combined with real-time heart-rate monitoring. HRV-B can be beneficial for several health or wellness-related needs, ranging from depression and anxiety, to cardiovascular disease, asthma, cancer fatigue, women’s health, better sleep, peak athletic performance, stress resilience, and brain health (see references section).
How is HRV-B Different from Other Breathing & Mindfulness Offerings?
HRV-B is a unique offering in a digital health and wellness space flooded with relaxation and mindfulness apps. Most of these apps seek to improve stress using content, such as brief audio recordings to aid mindfulness, meditation and well-being. One key differentiator with HRV-B is the ability to provide real-time, physiologically based feedback. You might think of HRV-B as a way to hack your own nervous system, and the network of rich connections between the heart and the brain (Nashiro et al., 2022). With real-time HRV biofeedback, we can retrain our nervous system so that, in a stressful moment, we are responding instead of reacting.
Loading & Understanding the Data
Now, let’s get into the data! First, we use pandas to load a time series from a csv file into a DataFrame object, which contains so-called “raw RR intervals.” An RR interval is defined as the distance in milliseconds between subsequent heartbeats (or more precisely the R-waves), measured using an electrocardiogram. Our data are actually a proxy for a heartbeat series, derived from an ear clip device using photoplethysmography (PPG) and the device’s peak detection algorithm. These distinctions are beyond the scope of this tutorial, but worth acknowledging.
Many people assume that the healthy heart beats steadily like a metronome, but in fact, there is substantial variation in these RR intervals. Much research has shown that higher HRV (or more variation) is associated with better health and a lower likelihood of mortality (Lehrer et al., 2020; Dekker et al., 2000). Through slow-paced breathing like HRV-B, we can transiently induce large increases in HRV, which stimulate baroreceptors in the heart that connect to the brain. Over time, this may “train” our nervous systems, much like weight lifting or physical therapy.
Transforming the Data
Now let’s transform the data from one test user (see sample DataFrame head above). First, we need to create a time vector (units = seconds) and transform the raw RR intervals into instant heart rate. Here’s a preprocessing function that transforms the data and returns the modified DataFrame object (see github).
Visualizing the Data
To plot the HRV-B data, we will use the matplotlib library. Below, you’ll see different segments of the test user’s data plotted in different colors. You can find the python function used for plotting in github here. Each segment represents an experimental condition, reflecting different ways of breathing and mental challenge conditions, which we will explain in more detail during the talk. About 20 seconds in, there is a potential ectopic beat or artifact, which we will also discuss how to handle.
Letting the Breath Move the Heart Rate
You can see that there are very large undulating sinusoidal waves happening, especially in the beginning part of the waveform (see above, navy). This is the effect of slow-paced breathing on the heart. Now, here’s a quick visual example of the HRV biofeedback pacer that guides the user to breathe at a preset pace of 6 breaths per minute (see below). Try it yourself! This pace establishes the rhythmic pattern (or frequency) you will see in the data, while the color of the pacer provides biofeedback based on your HRV-B performance metrics. The bigger the sinusoidal waves are, the bluer the pacer will be. Above, where the plot turns red and the sinusoidal form disappears, this is because the user shifted to breathing very quickly. So, you can see that the breath has a distinct impact on the shape of the waveform.
What Metric Does the Algorithm Need to Measure?
Published research studies of HRV-B and domain experts will typically quantify a study participant’s “performance” during a session by extracting frequency domain metrics from an entire time series, analyzed retrospectively. The Lomb-Scargle algorithm is preferable because it performs better on the unevenly spaced RR intervals than a Fast Fourier Transform (FFT) (Delane et al., Annu Int Conf IEEE 2016). The resultant power spectra are typically natural-log transformed. In the tutorial (see github), we help illustrate this technique and explore different ways to visualize frequency metrics (e.g., below).
The Challenges of Short Windows
Unfortunately, this “retrospective” approach does not work well for a real-time algorithm. In real-time, we need to take small, rolling windows of data — say 30 seconds or less — and output a biofeedback performance metric, which we will call “resonance” (see Schaffer & Meehan, 2020). The breathing pace in this example is 6 breaths per minute, meaning that 30 seconds of data will contain only 3 breaths or cycles. Frequency analysis methods make trade-offs in the frequency versus time domains. Practically, this means that when the window segment is a short slice of messy real-life data, these analytic methods struggle with poorer accuracy, edge effects and spectral leakage. The figures below demonstrate how the precision of frequency metrics degrades as the signal window becomes smaller. On the left, we analyze 3 minutes of data, and on the right, the first 30 second window.
Fitting a Sinusoidal Function
One way to understand frequency analysis is as a technique that decomposes a complex signal and expresses it as the sum of sinusoids with different frequencies (Downey, 2016). In the case of a real-time HRV-B algorithm, we really are only interested in the power in the breathing frequency. So, we can try applying a nonlinear curve-fitting model with a sinusoidal function to our data.
To first give you a quick orientation, there are four main parameters in a sinusoidal function. We unpack it more in this tutorial notebook. Given a time vector, this function will output an array with the sinusoidal transformation.
Once we have fit the sine wave within a bandwidth around the breathing frequency, then the amplitude is the main parameter we will focus on. This reflects how much variability our breathing can induce in our heart rate at a given pace. Below, we have plotted our simple sine function, to illustrate how varying the amplitude parameter changes the waveform. In an actual HRV-B session, the amplitude of this waveform reflects a phenomenon known as HRV-B “resonance” or “coherence” (Schaffer & Meehan, 2020). (I recommend using peer-reviewed scientific articles to read up on these concepts, as the way these terms are described elsewhere tends to confuse the metaphorical with the mathematical.)
The last tutorial notebook (code snippet below) illustrates how to use a non-linear least squares function from SciPy’s optimize library to fit a rolling sine wave to RR interval data. Specifically, it uses the Trust Region Levenberg-Marquardt (LM) algorithm.
Shaping Behavior Change through Algorithms
Our ultimate goal is to scaffold behavior change by feeding back real-time model parameter results to the user as biofeedback. So, we want to anticipate how the model output will impact the user experience. Plotting the result, you will see raw heart rate data on top, the rolling model predictions in the middle, and the amplitude parameter on the bottom. This particular input signal has undesirable high-frequency activity/noise and artifacts.
On one hand, the model does a pretty good job of identifying the breathing frequency, based on the plotted predictions in teal. However, the amplitude parameter (in purple) shows some instability in a few places. Since we want to use this amplitude parameter as the “resonance metric” to drive live biofeedback, users would likely be disturbed if the color of the pacer were to change color too quickly back and forth, giving a strobe effect. In the talk, we explore several options, which improve upon this fragility.
As a last note, we found that this python implementation differs from implementations of bounded LM algorithms in other programming languages (e.g., javascript) that you may need for real-time app-based implementation. You will want to benchmark the performance in the actual library you intended to use, and understand how its performance differs from this python example.
Wrapping up Post
In this post, I provided an overview of the components for building a real-time heart rate variability biofeedback algorithm. We also learned what HRV-B is, why it offers market differentiation, and what some of the main challenges are in translating knowledge from a traditional clinical/research context to a digital health context. In my upcoming talk at ODSC West 2022, titled, “Scalable, Real-Time Heart Rate Variability Biofeedback for Precision Health: A Novel Algorithmic Approach,” I will go deeper into the nuts and bolts of building a model for these data.
Originally posted on OpenDataScience.com
Read more data science articles on OpenDataScience.com, including tutorials and guides from beginner to advanced levels! Subscribe to our weekly newsletter here and receive the latest news every Thursday. You can also get data science training on-demand wherever you are with our Ai+ Training platform. Subscribe to our fast-growing Medium Publication too, the ODSC Journal, and inquire about becoming a writer.
Originally posted on OpenDataScience.com
Read more data science articles on OpenDataScience.com, including tutorials and guides from beginner to advanced levels! Subscribe to our weekly newsletter here and receive the latest news every Thursday. You can also get data science training on-demand wherever you are with our Ai+ Training platform. Subscribe to our fast-growing Medium Publication too, the ODSC Journal, and inquire about becoming a writer.