Skip to main content

7. Beyond Normality

Normal demand is a useful starting point, but it can be a poor description of some inventory items. Demand is often nonnegative and right-skewed: most periods are ordinary, with occasional unusually large orders. A Normal model is symmetric and assigns some probability to negative demand.

This chapter introduces the gamma distribution as one practical alternative. We will fit its parameters from demand summaries, account for a known minimum-demand offset, aggregate independent periods, and connect the distribution's upper tail to inventory targets and expected shortages. These are model-building tools, not an automatic rule that gamma is always better.

Diagnose the shape before choosing a model​

Consider this synthetic monthly sales sample for one item:

MonthUnits
Jan68
Feb73
Mar75
Apr76
May78
Jun79
Jul80
Aug81
Sep82
Oct84
Nov92
Dec112

The sample mean is about 81.7 units and the median is 79.5; the large December value pulls the mean upward. A fitted Normal curve may understate the chance of a large positive demand and may assign probability below zero. This does not establish that gamma is the correct model; it tells us to inspect the data, business calendar, and candidate distributions.

For observations x1,…,xnx_1,\ldots,x_n, the population-moment skewness is:

γ1=1n∑i=1n(xi−xˉ)3(1n∑i=1n(xi−xˉ)2)3/2\gamma_1 = \frac{\frac{1}{n}\sum_{i=1}^n(x_i-\bar{x})^3}{\left(\frac{1}{n}\sum_{i=1}^n(x_i-\bar{x})^2\right)^{3/2}}

Positive skew indicates a longer right tail, zero skew indicates symmetry in the third moment, and negative skew indicates a longer left tail. Different libraries use different sample corrections; state which convention is used when comparing values. Skewness alone does not describe the entire distribution.

Why inspect normality?​

Two common mismatches matter for inventory:

  • Support: an ordinary Normal distribution permits negative values. Clipping simulated values at zero changes the distribution and its mean; it is not a neutral implementation detail.
  • Tail shape: Normal demand is symmetric around its mean. A right-skewed item can have more unusually high demand than a Normal model predicts, which matters when setting a high service target.

Returns should usually be modeled as a separate flow unless the business can truly use a return to satisfy a future customer demand. Do not casually treat returns as negative demand.

Fit a gamma distribution by moments​

Use the shape-scale parameterization X∼Γ(k,θ)X\sim\Gamma(k,\theta), where k>0k>0 is the shape and θ>0\theta>0 is the scale. Its moments are:

μ=kθ,σ2=kθ2,γ1=2k\mu=k\theta,\qquad \sigma^2=k\theta^2,\qquad \gamma_1=\frac{2}{\sqrt{k}}

Matching a positive mean μ\mu and standard deviation σ\sigma gives:

k=μ2σ2,θ=σ2μ,γ1=2σμk=\frac{\mu^2}{\sigma^2},\qquad \theta=\frac{\sigma^2}{\mu},\qquad \gamma_1=\frac{2\sigma}{\mu}

Unlike the ordinary Normal distribution, gamma demand is supported on nonnegative values. Larger variation relative to the mean yields smaller kk and a more pronounced right tail. Be explicit about the software convention: some libraries use scale θ\theta, while others use a rate 1/θ1/\theta.

The explorer shows the gamma density on its nonnegative support and reports a moment-matched Normal model's probability below zero. It is a visual comparison of support and shape, not a goodness-of-fit test.

A known minimum or baseline demand​

If demand never falls below a credible operational baseline dmind_{min}, model:

D=dmin+X,X∼Γ(k′,θ′)D=d_{min}+X,\qquad X\sim\Gamma(k',\theta')

Fit the gamma component to the excess-demand mean μ′=μ−dmin\mu'=\mu-d_{min} and the original standard deviation σ\sigma:

k′=(μ−dmin)2σ2,θ′=σ2μ−dmin,γ1′=2σμ−dmink'=\frac{(\mu-d_{min})^2}{\sigma^2},\qquad \theta'=\frac{\sigma^2}{\mu-d_{min}},\qquad \gamma'_1=\frac{2\sigma}{\mu-d_{min}}

This requires μ>dmin\mu>d_{min} and σ>0\sigma>0. The floor should have a business or data-generating reason. Choosing the observed sample minimum automatically can overfit a small sample; validate the offset on new periods and compare tail behavior.

Aggregate demand over a policy risk period​

Let period demands be independent and identically distributed gamma variables with the same scale θ\theta. The sum of τ\tau periods is also gamma:

∑t=1τXt∼Γ(τk,θ)\sum_{t=1}^{\tau}X_t\sim\Gamma(\tau k,\theta)

For a demand floor dmind_{min} per period:

Dτ=τdmin+Γ(τk′,θ′),μτ=τμ,στ=τ σD_\tau=\tau d_{min}+\Gamma(\tau k',\theta'),\qquad \mu_\tau=\tau\mu,\qquad \sigma_\tau=\sqrt{\tau}\,\sigma

For continuous review, use τ=L\tau=L; for periodic review, use τ=L+R\tau=L+R. The risk-period safety stock for cycle service target α\alpha is the gamma quantile minus the expected demand:

ι=FDτ−1(α),SS=ι−μτ\iota=F^{-1}_{D_\tau}(\alpha),\qquad SS=\iota-\mu_\tau

Here ι\iota is the reorder point ss or order-up-to level SS, depending on the policy. In general this quantile requires a numerical library or table. SciPy's scipy.stats.gamma.ppf(alpha, a=shape, loc=offset, scale=scale) uses shape, location, and scale in that order. The lesson's Python exercises below avoid relying on SciPy by using precomputed CDF inputs where appropriate.

The exact sum result requires independent gamma variables with a common scale. If the period distributions have different scales, are correlated, or have changing parameters, the sum is not generally gamma; moment-matching another gamma is an approximation that should be validated.

Worked risk-period target with an offset​

Suppose weekly demand has mean 800 units, standard deviation 200, and a justified floor of 400. The gamma component has excess mean μ′=800−400=400\mu'=800-400=400, shape k′=4002/2002=4k'=400^2/200^2=4, and scale θ′=2002/400=100\theta'=200^2/400=100. For a five-week protection period, its shape is 5(4)=205(4)=20, its scale remains 100, and the offset is 5(400)=2,0005(400)=2{,}000 units.

If a numerical gamma quantile calculation gives the 95th percentile of Γ(20,100)\Gamma(20,100) as 2,787.92, the total inventory threshold is 2,000+2,787.92=4,787.922{,}000+2{,}787.92=4{,}787.92 units. Expected five-week demand is 5(800)=4,0005(800)=4{,}000, so the implied safety stock is about 788 units. The quantile here is illustrative; calculate it with a trusted distribution implementation and validate the chosen demand model on observed data.

From cycle service to expected shortage​

Cycle service asks whether demand exceeds the inventory threshold at all. Fill rate asks what fraction of units are supplied immediately. For risk-period demand DτD_\tau and inventory threshold ι\iota, expected units short are:

Us=E[(Dτ−ι)+]U_s=\mathbb{E}[(D_\tau-\iota)^+]

For X∼Γ(k,θ)X\sim\Gamma(k,\theta) with ι≥0\iota\ge 0, the gamma loss expression is:

LΓ(ι;k,θ)=kθ[1−FΓ(ι;k+1,θ)]−ι[1−FΓ(ι;k,θ)]L_\Gamma(\iota;k,\theta) =k\theta\left[1-F_\Gamma(\iota;k+1,\theta)\right] -\iota\left[1-F_\Gamma(\iota;k,\theta)\right]

For an offset gamma with risk-period floor mτm_\tau, shift the inventory threshold to I′=ι−mτI'=\iota-m_\tau and evaluate the loss of the gamma component. If I′≤0I'\le0, every nonnegative gamma-component demand exceeds that shifted threshold, so expected shortage is kθ−I′k\theta-I'; for I′>0I'>0, use LΓ(I′;k,θ)L_\Gamma(I';k,\theta). This keeps offset handling explicit rather than applying a zero-location formula to the unshifted threshold.

A simple long-run fill-rate approximation for periodic review is:

β≈1−UsμdR\beta\approx 1-\frac{U_s}{\mu_dR}

The denominator is expected demand per replenishment cycle. For continuous review with fixed order quantity, the cycle-demand denominator is QQ. This approximation and the loss expression rely on a specified shortage model; backorders, lost sales, and timing details can change the operational fill rate. Cycle service and fill rate are related but are not interchangeable.

Select a model carefully​

Use diagnostics to decide what to investigate, not to declare a winner automatically.

Compare skewness as a first screen​

A Normal distribution has theoretical skewness 0. A moment-matched gamma has skewness 2σ/μ2\sigma/\mu; an offset gamma has 2σ/(μ−dmin)2\sigma/(\mu-d_{min}). As a rough screen, compare ∣γobs−γcandidate∣|\gamma_{obs}-\gamma_{candidate}| across candidates. If observed skewness is much closer to one candidate, that is a useful signal for further testing. It does not prove that the candidate matches the actual tail or service-level quantiles.

Compare empirical and fitted distributions​

A histogram can reveal asymmetry and outliers. If comparing candidates with a histogram, use the same bin edges and range. Convert each candidate's CDF into probability mass per bin, F(bj+1)−F(bj)F(b_{j+1})-F(b_j), and compare like with like. Density heights have units of inverse demand and depend on bin width; normalizing histogram heights by their sum is not generally a probability-density normalization unless the bin width is also accounted for.

For empirical bin proportions pjp_j and model bin probabilities qjq_j, one possible summary is:

RMSE=1B∑j=1B(pj−qj)2RMSE=\sqrt{\frac{1}{B}\sum_{j=1}^{B}(p_j-q_j)^2}

An RMSE over bin probabilities is one summary, not a universal goodness-of-fit test. It weights all bins equally unless designed otherwise and may prioritize the center over the high-demand tail that drives shortages. For inventory decisions, inspect upper quantiles, exceedance counts, and service performance on held-out periods. A more advanced fit that fails out-of-sample checks is not an improvement.

Practice: fit, aggregate, and evaluate​

Concept check​

Quiz

Gamma demand and model fit

1 / 5

For a moment-matched Gamma(k, theta) with mean mu and standard deviation sigma, which parameter formulas use the shape-scale convention?

Pick an answer to see if you are right.

Rank the distribution-selection workflow​

Put these steps in dependency order. Do not pick a model before checking its support and the data used to fit it.

Quiz

Select and validate a demand model

1 / 1

Choose a practical candidate distribution for an inventory item.

OrderDrag the handle to rearrange — top should be first.

  1. 1Document the chosen model, assumptions, and conditions that should trigger a refit.
  2. 2Estimate mean, standard deviation, skewness, and candidate parameters from training data.
  3. 3Check quantiles and service performance on held-out periods under the intended inventory policy.
  4. 4Compare candidate distributions using common bins or a suitable fit diagnostic, paying attention to the upper tail.
  5. 5Inspect the demand definition, time bucket, returns, zeros, and any credible minimum.

Drag items into the correct order (or use ↑↓), then check.

Python practice: measure sample skewness​

Use population moments for this exercise so the result matches the chapter's formula. The first sample has a right-tail outlier; the second is symmetric.

SampleObservations
A1, 1, 1, 1, 5
B1, 2, 3, 4, 5

Implement population_skewness(values). Return the standardized third central moment; raise ValueError if the data have zero variance.

Python practice: fit gamma parameters​

The table contains summary statistics for synthetic demand streams. minimum is an externally justified operating floor, not a value to blindly set to the smallest observation in every sample. Use the population-moment convention stated above.

StreamMeanSDMinimum floor
A100250
B1002540
C802030

Implement fit_gamma(mean, sd, minimum). Return (offset, shape, scale, theoretical_skew), without rounding inside the function.

Python practice: aggregate a floored demand model​

For independent, identical periods, gamma shapes add, the common scale stays fixed, and a per-period floor adds once per period. Use this table to check the aggregation.

CasePer-period meanSDFloorPeriods τ\tau
A10025405
B8020304

Implement aggregate_gamma(mean, sd, minimum, periods). Return (risk_mean, risk_sd, risk_offset, shape, scale).

Python practice: expected units short​

For X∼Γ(k,θ)X\sim\Gamma(k,\theta) and inventory I≥0I\ge0, expected shortage is:

LΓ(I;k,θ)=kθ[1−F(I;k+1,θ)]−I[1−F(I;k,θ)]L_\Gamma(I;k,\theta)=k\theta[1-F(I;k+1,\theta)]-I[1-F(I;k,\theta)]

Gamma CDF values are supplied in this table so the code exercise can focus on implementing the loss identity without requiring SciPy.

Shape kkScale θ\thetaInventory IIF(I;k,θ)F(I;k,\theta)F(I;k+1,θ)F(I;k+1,\theta)
210200.5939940.323324
210100.2642410.080302

Implement gamma_loss(shape, scale, inventory, cdf_k, cdf_k_plus_one) and return expected units short. These are model calculations, not a substitute for checking whether the fitted tail is realistic.

Takeaways​

  • Normality is convenient, not guaranteed; support and upper-tail fit matter to inventory decisions.
  • For moment-matched Γ(k,θ)\Gamma(k,\theta), k=μ2/σ2k=\mu^2/\sigma^2, θ=σ2/μ\theta=\sigma^2/\mu, and skewness is 2/k2/\sqrt{k}.
  • An offset gamma requires a defensible floor and μ>dmin\mu>d_{min}; fitting the sample minimum blindly can overfit.
  • Independent same-scale gamma periods aggregate exactly by adding shapes; different scales or correlated periods need another model or an explicit approximation.
  • Quantiles and expected-shortage formulas connect the chosen distribution to cycle service and fill rate, but model validation should focus on held-out upper-tail behavior.

Previous: Inventory Policy Simulation Lab.

Next: Multi-Echelon Inventory Optimization — coordinate safety stock across connected locations.