Skip to main content

11. Discrete Probabilistic Demand

Earlier lessons often assumed Normal demand, then introduced gamma as a continuous alternative. Those parametric families are convenient, but they can misrepresent a custom sales history.

This lesson builds a tailor-fitted discrete demand model from observations: start with histograms and their limits, improve with kernel density estimation (KDE), then discretize the smooth density into a probability mass function (PMF) suitable for simulation and later policy optimization.

Original teaching rewrite for this course. Numeric drills use synthetic samples; they mirror the chapter workflow without reprinting a commercial dataset or textbook figures.

Why leave parametric densities?​

A Normal or gamma model forces a fixed shape. Histograms and KDEs instead estimate density from the data, then compress the result onto integer demand values. The next chapter in the track uses such a custom PMF inside simulation-based policy search.

Histograms as a first density estimate​

A histogram splits the observed range into bins. Each bin’s height is the fraction (or count) of observations that fall inside it. A common inventory shortcut treats that frequency as a point mass at the bin center.

How a histogram is built​

  1. Choose left and right edges of the support.
  2. Divide that interval into kk bins.
  3. Count observations in each bin and convert counts to frequencies.
  4. Optionally assign each frequency to the bin midpoint.

That yields a crude discrete distribution—but only at the midpoints.

Four histogram limitations​

  1. Sparse support. Probability lives only on bin centers (e.g. 21.7% at 1375 and 0% at 1376).
  2. Arbitrary bin count. Changing kk changes the shape of the estimated density.
  3. Arbitrary edges. Shifting the left/right limits reshapes the same sample into a different “distribution.”
  4. Not smooth. Adjacent bins can jump abruptly even when the true process is gradual.

Histograms remain useful for exploration. They are a weak default for a simulation PMF.

Kernel density estimation​

Kernel density estimation places a small probability kernel around every observation, then sums and normalizes those kernels. You no longer choose bin edges or a bin count; each point gets its own local contribution.

Kernel: a probability density used to spread mass around one observation.

Bandwidth: the width of that kernel (for a Gaussian kernel, its standard deviation).

Box (squared) kernel​

A box kernel spreads equal density on an interval of width equal to the bandwidth centered at each observation. Overlapping boxes add. The result is continuous in the support sense (every nearby real value gets mass) but not smooth—edges of the boxes create flat stretches and abrupt slopes.

Bandwidth still matters: a narrow box is jagged; a wide box oversmooths multimodal structure.

Gaussian kernel​

A Normal kernel around each point yields a smooth density. The estimated PDF at xx is the average of Normal densities centered at the observations (scaled so the whole curve integrates to 1).

Larger bandwidth → smoother, flatter estimate. Smaller bandwidth → more peaks that hug the sample.

Choosing bandwidth: Scott and Silverman​

With nn observations and sample standard deviation σd\sigma_d:

hScott=σd n−1/5h_{\text{Scott}}=\sigma_d\,n^{-1/5} hSilverman=σd(43n)1/5h_{\text{Silverman}}=\sigma_d\left(\frac{4}{3n}\right)^{1/5}

Both are rules of thumb. Scott’s rule often undersmooths less aggressively than intuition wants in the other direction: in practice it can look too smooth (underfit). A common heuristic is to use about 0.9 hScott0.9\,h_{\text{Scott}} when the Scott curve looks too loose.

KDE support extends slightly beyond the sample min and max—which is desirable: never observing 1902 does not prove Pr⁡(D=1902)=0\Pr(D=1902)=0.

Near-zero demand: Gaussian kernels can leak probability onto negative demand. Fold that mass onto 0 when building a PMF (below).

Practical SciPy sketch​

scipy.stats.gaussian_kde(data, bw_method=...) accepts 'scott', 'silverman', or a scalar factor times σd\sigma_d. The object exposes .pdf(x). SciPy does not ship a vectorized KDE .cdf; integrate one point at a time, e.g. integrate_box_1d(-inf, x), or build your own loop.

From continuous KDE to a discrete PMF​

Simulation engines need a finite integer domain and a PMF that sums to 1. Continuous KDE lives on (−∞,∞)(-\infty,\infty) in theory, so truncate thoughtfully.

Bounds from the sample and bandwidth​

With safety factor mm (often 3 or 4):

L=⌊dmin⁡−m h⌋,U=⌈dmax⁡+m h⌉L=\left\lfloor d_{\min}-m\,h\right\rfloor,\qquad U=\left\lceil d_{\max}+m\,h\right\rceil

For a single Normal kernel, Φ(−3)≈0.0013\Phi(-3)\approx 0.0013, so mass below dmin⁡−3hd_{\min}-3h from the lowest observation’s kernel is tiny; across nn kernels the tail is still small if other kernels sit higher. Floor LL and ceil UU for a conservative integer grid.

Then take domain x=L,L+1,…,U−1x=L,L+1,\ldots,U-1 (or through UU, consistently), evaluate the KDE PDF on xx, and normalize:

pmfi=f(xi)∑jf(xj)\mathrm{pmf}_i=\frac{f(x_i)}{\sum_j f(x_j)}

Sampling: numpy.random.choice(x, size=..., p=pmf).

Fold negative demand to zero​

If any xi<0x_i<0 carry mass:

  1. Add ∑xi<0pmfi\sum_{x_i<0}\mathrm{pmf}_i onto the probability at 00.
  2. Drop all negative support from xx and pmf.

Mean and variance from a PMF​

μd=∑ipmfi xi\mu_d=\sum_i \mathrm{pmf}_i\,x_i Vard=∑ixi2 pmfi−μd2,σd=Vard\mathrm{Var}_d=\sum_i x_i^2\,\mathrm{pmf}_i-\mu_d^2,\qquad \sigma_d=\sqrt{\mathrm{Var}_d}

Independence reminder​

A good per-period fit does not automatically describe lead-time demand. Autocorrelation (high after high, or high after low) breaks the independent-period assumption. When dependence matters, simulate demand over the risk period as a path, not as i.i.d. draws of one-period PMFs.

Recap path​

  1. Prefer KDE over raw histograms when you need a custom density.
  2. Use a Gaussian kernel for smoothness; set bandwidth with Scott/Silverman (or a tuned fraction of Scott).
  3. Truncate with dmin⁡−mhd_{\min}-mh and dmax⁡+mhd_{\max}+mh, evaluate PDF on integers, normalize to a PMF.
  4. Clamp negative mass to 0; report μd\mu_d and σd\sigma_d from the discrete support.
  5. Feed that PMF into simulation / policy search (next lessons).

Practice​

Concept check​

Quiz

Histograms, KDE, and discrete PMFs

1 / 5

Which is a core limitation of using a histogram as an inventory demand PMF?

Pick an answer to see if you are right.

Rank the KDE → PMF workflow​

Quiz

Build a custom discrete demand PMF

1 / 1

You have a cleaned one-period demand sample and want an integer PMF for simulation.

OrderDrag the handle to rearrange — top should be first.

  1. 1If needed, fold negative mass onto 0 and compute μ_d, σ_d from the final PMF.
  2. 2Set integer bounds with sample min/max ± m · bandwidth and evaluate the PDF on that grid.
  3. 3Choose a bandwidth (Scott, Silverman, or a tuned fraction of Scott).
  4. 4Fit the Gaussian KDE on the observations with the chosen bandwidth.
  5. 5Normalize the evaluated PDF values so the discrete probabilities sum to 1.

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

Code: Scott bandwidth and truncation bounds​

Implement Scott’s rule and the integer domain bounds used before discretizing a KDE.

Code: normalize PDF weights, then moments and clamp​

First turn raw nonnegative weights into a PMF. Then compute mean/SD and fold negative support onto zero.

Takeaways​

  • Histograms need arbitrary bins and edges; they put mass only on midpoints and stay jagged.
  • Gaussian KDE places a Normal kernel on each observation; bandwidth (Scott/Silverman or a tuned fraction) controls smoothness.
  • Discretize by truncating with dmin⁡−mhd_{\min}-mh / dmax⁡+mhd_{\max}+mh, evaluating the PDF on integers, and normalizing.
  • Fold negative KDE mass onto 0 for operational demand.
  • PMF moments μd,σd\mu_d,\sigma_d follow from ∑pixi\sum p_i x_i and ∑pixi2−μd2\sum p_i x_i^2-\mu_d^2; check independence before stacking periods.

Previous: Newsvendor Model.

Next: Simulation Optimization — search inventory policies when closed forms fail.