Cycling Caloric Expenditure

Published by Alice Seaborn on Tuesday, 22 June, 2021

A study of the MET-based calculation behind estimates of caloric expenditures during cycling events. Includes both the discrete MET (DMET) calculation and the continuous MET (CMET) calculation developed through the statistical methods described in this project.

Table of Contents

  1. Abstract
  2. Background
  3. Discrete MET
  4. Continuous MET
  5. Power-based MET
  6. Experimental Data
    1. Zeopoxa
    2. Under Armour
    3. Garmin
    4. Comparison
  7. Conlusions


Sports scientists have developed methods for estimating the number of calories burned by an athlete during their workout. Among these methods is the metabolic equivalent for task (MET) calculation of caloric consumption that attempts to scale different athletic activities against each other according to their relative intensities. For cyclists, the MET scale provides calculations for caloric consumption based on the average speed of the cyclist throughout the workout. However, the scale does not provide for speeds between the specific zones of their study. Consequently, this scale results in inaccurate estimates for athletes who do not travel at the exact average speeds included in the scale. Within the scope of this study, I refer to the original scale as the discrete MET (DMET) model. Using a polynomial regression model, the gaps within the DMET model were closed to form a continuous MET (CMET) calculation that offers superior caloric expenditure estimates. In order to form some basis for comparison, the MET model for the stationary-bike and the models used by three major activity tracking applications were also studied.


The model through which caloric expenditure is calculated is a discrete system relying on a metric known as the metabolic equivalent for task (MET). The scale of METs has been optimized over the years through rigorous examinations. However, the MET units remain discrete integers and do not allow for continuous calculations to be performed. This limitation means that someone running at 6.0 miles per hour for an hour will otensibly burn the same number of calories as someone running 6.5 miles per hour for the same duration because the MET scale grants 10 MET units to any running activity between 6.0 and 6.7 miles per hour. See the table below.


Consider a cyclist weighing 155 pounds and biking for 3 hours at 15.98 mph average. This cyclist will burn 3690.48 calories during their workout. However, the same cyclist riding for the same duration averaging 15.99 mph will burn 4428.57 calories. A third hypothetical cyclist of the same weight riding for the same duration at 16.00 mph will also burn 4428.57 calories according to the METs scale.

This system of discrete calorie consumption simply does not render accurate results. The discontinuities must be accounted for by creating a continuous calculation. By applying polynomial regression models against the MEPs discreete distribution, a more accurate model of caloric expenditure can be created.

In addition to the development of continuous MET for bicycling, a continuous power-based approach to caloric consumption is created based on the stationary bike MET units, trading watts for average speed. Power is an ideal approach to calculating caloric expenditure because it accounts for external factors such as grade and wind. In a speed-based approach, caloric consumption decreases with grade because speed decreases with grade just as with wind resistance. However, we know that increased grades and net-headwinds increase the overall energy consumption. Ergo, the speed-based approach is inherently inefficient under such circumstances. Power, on the other hand, is a direct measure of the athlete's performance and adjusts accordingly to grade and wind just as the athlete does. Despite the superiority of this approach, power is not immediately available in the field because power pedals are expensive. The groundwork for this model is provided but cannot be experimentally verified.

Discrete MET

Prior to developing the continuous MET (CMET) model, it is important to develop a baseline dunderstanding of the current discrete MET (DMET) model and its flaws. The MET model provides a series of known points of metabolic equivalent outputs per given task (e.g. running, cycling, swimming, jumprope, etc.) based on the intensity through which the task is performed. For cycling, running and swimming the intensity is measured by the average speed throughout the workout. The MET value is then combined with the weight of the cyclist and duration of the task like so:

caloric expenditure=.0175METsweight  (kg)duration  (minutes) \text{caloric expenditure} = .0175 \cdot \text{METs} \cdot \text{weight} \; (\text{kg}) \cdot \text{duration} \; (\text{minutes})

This definition means that the confidence in the caloric expenditure is maximized at the points where DMET is defined and minimized where DMET is undefined. The model does not, however, provide any output for data points for which there has been no experimental verification. These deadzones present a serious issue for any athlete who does not perform at the exact points of the models certainty. This distribution represents experimentally known points of metabolic output for cycling. Note the seemingly exponential trend in MET units below.


Creating a Python model for DMET is trivial, as demonstrated below.

def calc_pounds_to_kg(pounds):
    return pounds/2.205

def dmet_cycling_met_units(speed):
    if speed <= 10.0:
        return 4
    elif speed <= 11.99:
        return 6
    elif speed <= 13.99:
        return 8
    elif speed <= 15.99:
        return 10
    elif speed <= 19.99:
        return 12
        return 14

def dmet_calories_per_minute(weight, speed):
    mets = dmet_cycling_met_units(speed)
    weight = calc_pounds_to_kg(weight)
    return 0.0175*mets*weight

def dmet_calc_total_calories_burned(weight, duration, speed):
    calories_per_minute = dmet_calories_per_minute(weight, speed)
    return calories_per_minute*duration

We can explore the falacy created by discrete models through an example. Using the model created above, consider the following scenarios for a cyclist biking the same duration but at different average speeds. Caloric expenditures for both 14.00 mph and 15.99 mph are equivalent, which is thermodynamically impossible. Controlling for other factors, increased speed must always yield increased calories burned.

>>> dmet_calc_total_calories_burned(155.0, 300, 14.00)
>>> dmet_calc_total_calories_burned(155.0, 300, 15.99)

The flat regions of the graph below represent areas of impossibly equivalent metabolic outputs due to the zones of undefined DMET values. To elaborate, this means that increased cycling speed does not also result in increased calories burned, despite violating the law of conservation of energy. A realistic model of caloric expenditure would reflect a graph whose slope was always potitive and probably also always increasing. Afterall, increased speed must always require increased energy to be burned. The sudden increases of metabolic output are equally ridiculous as the difference between 9.99 mph and 10.00 mph are over-dramatized due to the DMET inefficiencies.


Continuous MET

Equiped with a background understanding of the DMET model, improvements can now safely be pursued. From the distribution of the known DMET points, it is clear that an exponential model is needed. This exponential trend is rational because the difference in subjective effort between bicycling at 1 mph and 4 mph is not equivalent to the difference between bicycling 20 mph and 23 mph. As the speed increases, dramatically more effort is required to realize an equivalent increase in speed.

Note that while caloric expenditure is exponential with respect to speed, the human potential is logarithmic. In other words, human beings asymptotically approach a theoretical maximum performance at which further progress is limited by the constraints of our corporial manifestations.

We can develop a continuous model for expenditure by running a polynomial regression against the discrete data as shown below. Note that a first-order polynomial is linear, which does not fit the apparent trend of the DMET scatter plot. Second-order polynomials are parabolic/quadratic but they resulted in a region where the MET units decrease with an increase in speed which is not biomechanically possible and was therefore thrown out. Third-order polynomials yield good results as fourth-order polynomials and beyond were overfit.

>>> cycling_speeds = list([0.0, 10.0, 12.0, 16.0, 18.0, 20.0])
>>> met_units = list([4.0, 6.0, 8.0, 10.0, 12.0, 16.0])
>>> cmet_coefficients = np.polyfit(cycling_speeds, met_units, 3)
>>> cmet_polynomial = np.poly1d(cmet_coefficients)

Graphing the resulting polynomial, we are left with the following:


When determining the order of the polynomial model, it is important to study the distribution of the original dataset. I can tell by the discrete distribution that the relationship between cycling speed and MET units is most likely quadtratic. Ergo, I tried a second-order polynomial y=Ax2+Bx+Cy = Ax^{2} + Bx + C but I noticed a region in a plot of the resulting model whereby the derivative was negative. In other words, for a region of the graph, bicycling faster cost less energy. Controlling for wind and terrain, this is an irrational behavior for the model so it was thrown out. This behavior disappeared when a third-order (cubic) polynomial y=Ax3+Bx2+Cx+Dy = Ax^{3} + Bx^{2} + Cx + D was applied.

The cubic model is superior to the DMET but presents its own challenges with the clearly concave-convex regions of the graph, whose inflection point exists somewhere between 7.5 and 12.5 mph where y¨=0\ddot{y} = 0. The inflection behavior suggests that the cyclist has optimal regions of velocity whereby the caloric consumption is lowered. Although this is probably true, the MET data does not try to support this assertion outright. Mathematically speaking inflection is guaranteed with a third degree polynomial because the second derivative is a linear equation, provided that the first coefficient is non-zero.

y=Ax3+Bx2+Cx+Dy˙=3Ax2+2Bx+Cy¨=6Ax+2B \begin{aligned} y &= Ax^{3} + Bx^{2} + Cx + D \\ \dot{y} &= 3Ax^2 + 2Bx + C \\ \ddot{y} &= 6Ax + 2B \end{aligned}

Using a lower order polynomial (e.g. y=Ax2+Bx+Cy = Ax^{2} + Bx + C for p2p_2) would result in a constant second derivative (y¨=2A\ddot{y} = 2A) and therefore y¨0\ddot{y} \neq 0 provided that A0A \neq 0. For derivatives of polynomials pn  s.t.n<2p_n \; \text{s.t.} n<2 then y¨=0\ddot{y} = 0 and therefore the inflection would not apply.

A continuous model can be developed from this regression by exporting the polynomial coefficients and processing the calculations against the polynomial rather than through a discrete table.

def coefficients():
    return np.array([3.19343066e-03, -6.25952515e-02,
                     5.62785754e-01, 3.98022780e+00])

def cmet_cycling_met_units(speed):
    polynomial = np.poly1d(coefficients())
    return polynomial(speed)

def cmet_calories_per_minute(weight, speed):
    mets = cmet_cycling_met_units(speed)
    weight = calc_pounds_to_kg(weight)
    return 0.0175*mets*weight

def cmet_calc_total_calories_burned(weight, duration, speed):
    calories_per_minute = cmet_calories_per_minute(weight, speed)
    return calories_per_minute*duration

Rerunning the simulations for the cycling biking at different average speeds, we can see a dramatic improvement in our estimates. Using the continuous MET calculation, no two speeds result in the same caloric output and small increases in speed result in proportional energy outputs as would be expected.

>>> cmet_calc_total_calories_burned(155.0, 300, 14.00)
>>> cmet_calc_total_calories_burned(155.0, 300, 15.99)

Inflection points not withstanding, the continuous model offers a number of advantages over the discrete model. Most notably is the constant positive derivative in the speed response. Controlling for terrain and wind conditions, when a cyclist goes faster they must expend more energy for the system to be considered energetically conservative. This CMET model is valid under those constraints.

Power-based MET

The MET units provide values for stationary bikes. On a stationary bike, the althete's performance cannot be measured in terms of speed but is instead measured as a function of power, commonly in the unit watts. Although this model is developed for the stationary bike, it controls for a number of factors such as wind and terrain by opting to measure the instantanious power applied by the athlete against the bike.

Ideally, power would be measured on a road bike and fed directly into this model and speed would be entirely ignored. Consequently, slower speeds uphill would reflect greater overall power and therefore greater caloric consumption, rather than lowered caloric consumption as suggested by the speed-based approach. Concordantly, headwinds and tailwinds would not calorically punish nor benefit the rider provided that applied power remained constant. In a speed-based model such scenarios would unjustly affect the estimated caloric consumption despite a constant applied power on behalf of the athlete, thereby violating the constraint of the conservation of energy with respect to the rider.

>>> power = list([50.0, 100, 150, 200, 250])
>>> power_mets = list([3.0, 5.5, 7.0, 10.5, 12.5])
>>> pmet_slope, pmet_intercept, r_value, p_value, std_err = stats.linregress(power, power_mets)
>>> print(f"METs = {round(pmet_slope, 3)} * power + {round(pmet_intercept, 3)}")
>>> print(f"R-Squared: {round(r_value, 3)} with P-Value: {round(p_value, 3)}\n")
METs = 0.048 * power + 0.5
R-Squared: 0.994 with P-Value: 0.001

Here the PMET distribution suggests a linear regression model be used. and the demonstrated linear model clearly fits the trend. More development is needed to see how power on a stationary bike relates to power applied on the road. The R-Squared of 0.9940.994 is outstanding and indicates that the variance of the PMET distribution is effectively described by the linear regression model.


Experimental Data

Under Armor and similar sports technology companies have developed their own cycling ride-tracking systems. Included in the final ride report is an estimate of the caloric output. Within this section, the caloric outputs of these providers are explored. I am interested to see if the individual providers use different models to calculate caloric expenditure. Perhaps most importantly, I am interested in seeing if the distribution is exponential or linear with respect to the average speed.

MET units are not a recorded field in this case as the tracking software keeps MET values esoteric to the client. However, using the duration, distance, and estimated caloric output of each ride according to the tracker provider, the MET values were derived using the following formula:

Estimated MET (EMET)=CaloriesDuration0.0175Weight \text{Estimated MET (EMET)} = \frac{\text{Calories}}{\text{Duration} \cdot 0.0175 \cdot \text{Weight}}

My own body weight has fluctuated throughout these rides, adding potential layer of complexity to this analysis. However, my weight we set to a constant value to make the analysis more straight forward. All experimental data is loaded from the cycling tracker data CSV.


Starting with the Zeopoxa tracker, a clearly linear distribution is presented. Using a simple linear regression, a statistical model of the MET calculation was created. Surprisingly, the model resulted in an R-Squared value of $1.00$ which means that 100%100\% of the variation in the data was accounted for in the regression model. Were the model more complex, I would regard such a high value with suspicion but given that the distribution is so clear and there are no clear outliers, the regression is clearly performing properly.

Despite the strong results from the linear model, it is important to note the sampling bias in the dataset as most rides have average speeds greater than 10  mph10 \; \text{mph}. Ergo, the linear trend may not hold for extremely slow rides. Despite the bias, the sample with the lowest average speed still obeys the trend, suggesting that the linear model is truly appropriate for this dataset.

>>> Zeopoxa = tracking_data[tracking_data["Provider"] == "Zeopoxa"].reset_index(drop=True)
>>> zeopoxa_average_speed = Zeopoxa["Average Speed"]
>>> zeopoxa_estimated_met = Zeopoxa["Estimated MET Units"]
>>> zeopoxa_slope, zeopoxa_intercept, r_value, p_value, std_err = stats.linregress(zeopoxa_average_speed,
>>> print(f"METs = {round(zeopoxa_slope, 3)} * average speed + {round(zeopoxa_intercept, 3)}")
>>> print(f"R-Squared: {round(r_value, 3)} with Standard Error: {round(std_err, 3)}\n")
METs = 0.561 * average speed + 0.301
R-Squared: 1.0 with Standard Error: 0.001

The linear distribution is interesting given that the METs cycling model suggests a logistic or exponential relationship between average speed and caloric output. The linear relationship is likely the result of a simpler model for calculating cycling speeds but without reverse engineering the application there is no way to be sure.


Under Armour

The Zeopoxa application has several GPS bugs that render the application less reliable. When I learned that Under Armour's MapMyRide app integrates with MyFitnessPal I decided to change tracking applications. The R-Squared value was similarly strong without any outliers to suggest a statistical error. The sampling bias of faster rides still occurs although the slowest sample still strongly obeys the trend, suggesting an appropriate model selection has been made.

>>> UnderArmour = tracking_data[tracking_data["Provider"] == "Under Armour"].reset_index(drop=True)
>>> under_armour_average_speed = UnderArmour["Average Speed"]
>>> under_armour_estimated_met = UnderArmour["Estimated MET Units"]
>>> under_armour_slope, under_armour_intercept, r_value, p_value, std_err = stats.linregress(under_armour_average_speed,
>>> print(f"METs = {round(under_armour_slope, 3)} * average speed + {round(under_armour_intercept, 3)}")
>>> print(f"R-Squared: {round(r_value, 3)} with Standard Error: {round(std_err, 3)}\n")
METs = 0.971 * average speed + -3.84
R-Squared: 0.999 with Standard Error: 0.013

One obvious fault with this model is the negative y-intercept value. This model suggests, absurdly, that with an average speed of 3.96  mph\approx 3.96 \; \text{mph} the cyclist would burn no energy and that at any lesser speed the cyclist would actually gain energy. Both of these consequences of the model violate the laws of thermodynamics. A positive y-intercept can be explained by the basal metabolic rate, a person still burns energy at rest, but a negative y-intercept should never occur. Additionally, the slope of the model for Under Armour is inexplicably 73%73\% higher that the Zeopoxa model. Nevertheless the linear trend still holds and clearly Under Armour is using a linear model for their caloric calculations.



The Garmin Forerunner 310XT makes its own estimates as to the number of calories burned per ride based on its own observations. However, small pauses during the workout are removed because the device can be easily paused and restarted at traffic lights and stop signs. For this reason, the average speed of a ride on the Garmin device is noticably and intentionally higher than the same ride tracked from the users phone. For this reason, the distribution suffered from a sampling bias whereby the average speed of each ride was higher than average though not dishonestly higher.

>>> Garmin = tracking_data[tracking_data["Provider"] == "Garmin"].reset_index(drop=True)
>>> garmin_average_speed = Garmin["Average Speed"]
>>> garmin_estimated_met = Garmin["Estimated MET Units"]
>>> garmin_slope, garmin_intercept, r_value, p_value, std_err = stats.linregress(garmin_average_speed,
>>> print(f"METs = {round(garmin_slope, 3)} * average speed + {round(garmin_intercept, 3)}")
>>> print(f"R-Squared: {round(r_value, 3)} with Standard Error: {round(std_err, 3)}\n")
METs = 0.608 * average speed + 1.369
R-Squared: 0.917 with Standard Error: 0.046

Although the Garmin tracking data suggests a linear trend, the distribution has a much larger variance than the previous datasets. This increased variance suggests that another factor must have been used to calculate the MET units for caloric output. I would assume that the average gradient of the ride is a logical second factor in determining how many calories the ride required.

Regardless of the larger variance, the linear regression model still explains approximately 91.7%91.7\% of the variance of the original dataset. This high R-Squared value still suggests that a vast majority of the dataset's variance comes from the average speed of the ride.



Ultimately, all three tracking providers used a linear model despite the logistic model presented by the road cycling MET data. While Zeopoxa and Garmin had similar results in terms of the slope of the linear regression, the Garmin data had a much larger distribution. This distribution suggests that the average speed of the ride is the dominant though not the only factor in determining the caloric needs of the ride. The Under Armour model, while linear, had a much larger slope than the other two trackers and had a negative y-intercept, violating clear biochemical constraints. Despite these differences, the high R-Squared value of the Under Armour model confirms that 99.9%99.9\% of the variance in the dataset is explained by the linear regression. Such a large vote of confidence does not leave enough room for a second factor to be considered influential when calculating caloric consumption.



Expanding the discrete model into the continuous domain improves the resulting predictions for caloric expenditure. Using a third-order polynomial model, the undefined regions of the discrete met values could be accounted for. Whereas the discrete model failed to scale with gradual increases in speed, the continous model ensures that increases in speed will always reflect increases in energy (calories) consumed.

Additionally, the power-based approach of a stationary-bike suggests a linear relationship between power output and calories consumed, offering a potentially superior model to caloric expenditure on the road once the relationship between power and road performance is better understood.

In order to determine how these models may be used in production, the cycling data from three major tracking applications/devices was evaluated. All three tracking providers used a linear model of caloric consumption. Of the three providers, two trackers used models whose coefficients were strongly related and one tracker used a model whose extrema violated essential biomechanical principals. Without a model to link the linear stationary-bike power output to the average speed of a road bike, the comparison between the power-based approach and the three road bike trackers could not be made.