# Why are the bootstrap and CDF estimates of the 60% quantile significantly different?

Remove["Global*"]
data = N[{1.67655096, 1.73234376, 1.8965016000000001, 2.06723664,
2.19692088, 2.20885056, 2.21420304, 2.2199184, 2.25389304,
2.2695422400000003, 2.42848368, 2.62902024, 2.65727952,
2.76596208, 2.95570296, 3.15574056, 3.25290168,
3.5498735999999997, 3.8103760799999997, 3.88707984,
4.00737456, 4.1241312, 4.34081592, 4.56303456, 4.57950024}];
(*Define distribution*)
dist = LogNormalDistribution[\[Mu], \[Sigma]];
(*Find distribution parameters*)
FindDistributionParameters[data, dist]
(*Bootstrap*)
sample = RandomVariate[
dist /. {\[Mu] -> 1.030902937776725, \[Sigma] ->
0.30525966657758447}, 1000000];
Bootstrapping := {\[Mu], \[Sigma]} /.
FindDistributionParameters[RandomChoice[sample, Length@data], dist];
BootEstimates = ParallelTable[Bootstrapping, {10000}];
(*Bootstrap Standard Deviation estimation*)
BootStd =
StandardDeviation /@ Transpose[BootEstimates]
(*Bootstrap: There is a 60% probability that the true value of \[Mu] \
is below 1.0473.*)
{Quantile[#, 0.6]} & /@ Transpose[BootEstimates]

(*CDF calculation: There is a 60% probability that the true value of \
\[Mu] is below 3.029.*)
Solve[
CDF[LogNormalDistribution[1.030902937776725, 0.30525966657758447],
x] == 0.6]

• Are those parameters you plug into a LogNormalDistribution in the beginning supposed to be the exact same as those you plug into a NormalDistribution at the end? Commented Jan 29, 2018 at 18:39
• They should both be LogNormalDistribution; I fixed that. Commented Jan 29, 2018 at 18:45
• From the last line I get 3.029021378646146. Maybe you need an extra step: Mean[LogNormalDistribution[μ, 0.3052596665775844]] == 3.029021378646146 // Solve ? Commented Jan 29, 2018 at 18:54
• I think you are mixing up two different concepts. The bootstrap process (which you perform in a very nonstandard way - and I'll comment on that next) gets one an idea about the sampling distribution of the estimator of $\mu$ (and $\sigma$ for that matter). The last piece of code (Solve[...==0.6]) gets you the value of a single observation for which 60% of randomly selected values are less than that value.
– JimB
Commented Jan 29, 2018 at 20:41
• I look forward to your comment! Commented Jan 29, 2018 at 20:48

This is first an extended comment followed by an answer to the question.

Extended comment

Typically one chooses the usual nonparametric bootstrap by resampling from the observed data (labeled "Simple bootstrap below) or from a known functional form of a distribution but with the parameter estimates used in place of the unknown parameters:

(* Simple bootstrap *)
simpleBootstrap := {μ, σ} /.
FindDistributionParameters[RandomChoice[data, Length@data], dist];
simpleBS = ParallelTable[simpleBootstrap, {10000}];
simpleBSseμ = StandardDeviation[simpleBS[[All, 1]]]
simpleBSseσ = StandardDeviation[simpleBS[[All, 2]]]

(* Parametric bootstrap *)
mle = FindDistributionParameters[data, dist]
parametricBootstrap := {μ, σ} /.
FindDistributionParameters[RandomVariate[dist /. mle, Length@data],
dist];
parametricBS = ParallelTable[parametricBootstrap, {10000}];
parametricBSseμ = StandardDeviation[parametricBS[[All, 1]]]
parametricBSseσ = StandardDeviation[parametricBS[[All, 2]]]


Your method seems to be a parametric bootstrap but with an extra step of generating 1,000,000 samples from the estimated distribution. While the results will likely be nearly identical, that extra step is unnecessary.

The bootstrap is giving you the estimate of the value where 60% of the sampling distribution of the estimate of $\mu$ is below.

The Solve[...==0.6] part of your code which can be written as

InverseCDF[LogNormalDistribution[1.030902937776725, 0.30525966657758447], 0.6]


is giving you the estimated value for which a single random sample will be below 60% of the time.

So the two values are not comparable and certainly shouldn't be the same.

• The Wikipedia page on the bootstrap is a place to start. One of the references listed is statistics.stanford.edu/sites/default/files/BIO%2083.pdf. As far as built-in MMA functions, I don't think there are any. One needs to use the LogLikelihood` function you referenced in another question.