Document the process being modeled. Describe the process being modeled and define the random variable to be collected.
Develop a plan for collecting the data and then collect the data.
Perform graphical and statistical analysis of the data. Using standard statistical analysis tools you should visually and statistically examine your data.
Hypothesize distributions: Using what you have learned from steps 1 - 3, you should hypothesize possible distributions for the data.
Estimate parameters. Once you have possible distributions in mind you need to estimate the parameters of those distributions.
Check the goodness of fit for hypothesized distributions. As part of this step you should perform some sensitivity analysis on your fitted model.
Recommend an appropriate distribution
| Distribution | Modeling Situations |
|---|---|
| Bernoulli(p) | independent trials with success probability \(p\) |
| Binomial(n,p) | sum of \(n\) Bernoulli trials with success probability \(p\) |
| Geometric(p) | number of Bernoulli trials until the first success |
| Negative Binomial(r,p) | number of Bernoulli trials until the \(r^{th}\) success |
| Discrete Uniform(a,b) | equally likely outcomes over range (a, b) |
| Discrete Uniform \(v_1, \cdots, v_n\) | equally likely over values \(v_i\) |
| Poisson(\(\lambda\)) | counts of occurrences in an interval, area, or volume |
| Distribution | Modeling Situations |
|---|---|
| Uniform | when you have no data, everything is equally likely to occur within an interval, machine task times |
| Normal | modeling errors, modeling measurements, length, etc., modeling the sum of a large number of other random variables |
| Exponential | time to perform a task, time between failures, distance between defects |
| Erlang | service times, multiple phases of service with each phase exponential |
| Weibull | time to failure, time to complete a task |
| Gamma | repair times, time to complete a task, replenishment lead time |
| Lognormal | time to perform a task, quantities that are the product of a large number of other quantities |
| Triangular | rough model in the absence of data assume a minimum, a maximum, and a most likely value |
| Beta | useful for modeling task times on bounded range with little data, modeling probability as a random variable |
mean - Measures the central tendency of the distribution
variance - Measures the spread about the mean
coefficient of variation - \(c_v = \frac{\sqrt{Var[X]}}{E[X]}\)
mode - Measures the most likely value
skewness - Measures the asymmetry of the distribution about its mean. Helpful in picking an appropriate distribution.
kurtosis - Measures the degree of peakedness of the distribution
order statistics - Used when comparing the sample data to the theoretical distribution via P-P plots or Q-Q plots.
quantiles (1st quartile, median, 3rd quartile) - Summarizes the distribution of the data.
minimum, maximum, and range - Indicates the range of possible values
The KSL Statistic class and its companion object will estimate all of these quantities except for the mode.
histogram or frequency plots - To illustrate the shape of the distribution use KSL classes Histogram, HistogramPlot, IntegerFrequency, and IntegerFrequencyPlot.
time series plot - To illustrate trends or patterns that may indicated dependence on time use KSL class ObservationsPlot.
autocorrelation plot - To illustrate the lag-k correlation as a function of lag use KSL class ACFPlot.
box plots - To illustrate the spread and outliers in the data use KSL class BoxPlot.
distribution fitting diagnostic plots
PPPlot and QQPlot.PMFComparisonPlot.CDFDiffPlot.DensityPlot.ECDFPlot.FitDistPlot.ParameterEstimatorIfc interface.
MVBSEstimatorIfc InterfaceMVBSEstimatorIfc - The purpose of this interface is to define a method that takes in data (in an array) and returns the estimated quantities in an array./**
* Given some data, produce multiple estimated statistics
* from the data and store the estimated quantities in
* the returned array. It is up to the user to interpret
* the array values appropriately.
*/
interface MVBSEstimatorIfc {
/**
* The name to associate with each dimension of the
* array that is returned by estimate(). The names
* should be unique. The order of the list of names should
* match the order of elements in the returned array.
*/
val names: List<String>
fun estimate(data: DoubleArray): DoubleArray
}ParameterEstimatorIfc Interface/**
* This interface defines a general function that uses 1-dimensional data, and estimates the parameters of some
* uni-variate distribution via some estimation algorithm. The basic contract is that the returned
* EstimatedParameters is consistent with the required parameter estimation.
*/
interface ParameterEstimatorIfc {
/**
* Indicates if the estimator requires that the range of the data be checked for a shift
* before the estimation process.
*/
val checkRange: Boolean
/**
* Estimates the parameters associated with some distribution. The returned [EstimationResult]
* needs to be consistent with the intent of the desired distribution.
* Note the meaning of the fields associated with [EstimationResult]
*/
fun estimateParameters(data: DoubleArray, statistics: StatisticIfc = Statistic(data)): EstimationResult
}The parameters of the following distributions can be estimated from data using the KSL.
BetaMOMParameterEstimatorBinomialMaxParameterEstimator or BinomialMOMParameterEstimatorExponentialMLEEstimatorGammaMLEParameterEstimator or GammaMOMParameterEstimatorGeneralizedBetaMOMParameterEstimatorLognormalMLEParameterEstimatorNegBinomialMOMParameterEstimatorNormalMLEParameterEstimatorPearsonType5MLEParameterEstimatorPoissonMLEParameterEstimatorTriangularParameterEstimatorUniformParameterEstimatorWeibullMLEParameterEstimator or WeibullPercentileParameterEstimatorestimateParameters(data: DoubleArray, statistics: StatisticIfc): EstimationResult
EstimationResult instanceEstimationResult stores information about the estimation process to be returned as a result of its application on the supplied data.Estimation Results:
The estimation was a SUCCESS!
Estimation message:
The normal parameters were estimated successfully using a MLE technique
Shift estimation results:
null
Estimated parameters:
RV Type = Normal
Double Parameters {mean=2.4138851463671918, variance=5.571943618235626}
Integer Parameters {}
Double Array Parameters {}
EstimationResultsuccess property indicates whether the parameter estimation process was successful.
success property is true, then the results should be meaningful.statistics property is a statistical summary of the original data.shiftedData property is the data if a shift was required.parameters property is the estimated parameters as an instance of RVParameters.message property is a text (string) representation of the distribution and its parameters.estimator property can be used for bootstrapping results.To implement your own scoring model, you need to sub-class from the abstract base class PDFScoringModel.
The primary method that needs to be implemented is the abstract score() function.
Score is a data class that indicates whether the score is valid or not and provides the metric that determined the score.
\[\tilde{F}_n(x_{(i)}) = \dfrac{i - 0.5}{n}\] Then, the P-P Plot sum of squared error criterion is defined as:
\[ \text{PP Squared Error} = \sum_{i = 1}^n (\tilde{F}_n(x_{(i)}) - \hat{F}(x_{(i)}))^2 \]
\[ A^2 = n\int_{-\infty}^{+\infty}\frac{\Big[ F_n(x) - F(x) \Big]^2}{F(x)(1-F(x))}\,dF(x) \]
\[ \begin{aligned} D^{+}_{n} & = \underset{1 \leq i \leq n}{\max} \Bigl\lbrace \tilde{F}_{n} \left( x_{(i)} \right) - \hat{F}(x_{(i)}) \Bigr\rbrace \\ & = \underset{1 \leq i \leq n}{\max} \Bigl\lbrace \frac{i}{n} - \hat{F}(x_{(i)}) \Bigr\rbrace \end{aligned} \]
\[ \begin{aligned} D^{-}_{n} & = \underset{1 \leq i \leq n}{\max} \Bigl\lbrace \hat{F}(x_{(i)}) - \tilde{F}_{n} \left( x_{(i-1)} \right) \Bigr\rbrace \\ & = \underset{1 \leq i \leq n}{\max} \Bigl\lbrace \hat{F}(x_{(i)}) - \frac{i-1}{n} \Bigr\rbrace \end{aligned} \]
\[ V_{k} = \sum_{i=1}^{m}w_i \times M_i \]
PDFModeler Class FunctionalityPDFModeler ClassPDFModeling class encapsulates the estimation and scoring process.PDFModelingResults, which will have the results of the entire fitting process.ContinuousCDFGoodnessOfFit class facilitates the performing of the following goodness of fit tests: Chi-Squared, Kolmogorov-Smirnov, Anderson-Darling, Cramer-Von Mises.\[ p_j = P\{b_{j-1} \leq X \leq b_{j}\} = \int\limits_{b_{j-1}}^{b_{j}} f(x) \mathrm{d}x \]
\[ k = \Bigg\lceil 4 \, \sqrt[5]{\frac{2(n-1)^2}{z_{1-\alpha}}} \, \Bigg\rceil \]
The KSL continuous distribution modeling framework allows the modeler to:
One hundred observations of the service time were collected using a portable digital assistant and are shown in here where the first observation is in row 1 column 1, the second observation is in row 2 column 1, the \(21^{st}\) observation is in row 1 column 2, and so forth.
val results = d.estimateAndEvaluateScores()
println("PDF Estimation Results for each Distribution:")
println("------------------------------------------------------")
results.sortedScoringResults.forEach(::println)
val topResult = results.sortedScoringResults.first()
val scores = results.evaluationModel.alternativeScoresAsDataFrame("Distributions")
println(scores)
println()
val values = results.evaluationModel.alternativeValuesAsDataFrame("Distributions")
println(values)
println()
val distPlot = topResult.distributionFitPlot()
distPlot.showInBrowser("Recommended Distribution ${topResult.name}")
println()
println("** Recommended Distribution** ${topResult.name}")
println()| Distributions | Overall Value |
|---|---|
| 36.83628655364795 + Exponential(mean=145.94151344635202) | 0.9696257711895793 |
| 36.83628655364795 + Weibull(shape=1.003714037935936, scale=151.6852597437524) | 0.9649927259316368 |
| 36.83628655364795 + Gamma(shape=0.9835042713420494, scale=148.38930312646863) | 0.9607705242493729 |
| GeneralizedBeta(min=29.310909090909092, max=789.7490909090909, alpha=0.7356153488826158, beta=2.9094053790945313) | 0.9219840879188533 |
| 36.83628655364795 + Lognormal(mean=250.46425448551713, variance=536239.5203995836) | 0.9200543546500699 |
| Normal(mean=182.77779999999996, variance=20053.73115470709) | 0.8327362903913982 |
| Triangular(minimum=29.310909090909092, mode=29.310909090909092, maximum=789.7490909090909) | 0.7211332196291593 |
| Uniform(minimum=29.310909090909092, maximum=789.7490909090909) | 0.32593468399612574 |
| 36.83628655364795 + PearsonType5(shape=0.1433904565135134, scale=0.05276408469245713) | 0.2733043272265799 |
We can use the following code to perform a goodness of fit analysis on the recommended distribution.
GOF Results for Distribution: Exponential(mean=145.94151344635202)
---------------------------------------------------------
Chi-Squared Test Results:
Bin Label P(Bin) Observed Expected
1 [ 0.00, 7.49) 0.050000 3 5.00000
2 [ 7.49,15.38) 0.050000 4 5.00000
3 [15.38,23.72) 0.050000 8 5.00000
4 [23.72,32.57) 0.050000 3 5.00000
5 [32.57,41.98) 0.050000 8 5.00000
6 [41.98,52.05) 0.050000 4 5.00000
7 [52.05,62.87) 0.050000 5 5.00000
8 [62.87,74.55) 0.050000 8 5.00000
9 [74.55,87.25) 0.050000 4 5.00000
10 [87.25,101.16) 0.050000 2 5.00000
11 [101.16,116.54) 0.050000 9 5.00000
12 [116.54,133.72) 0.050000 3 5.00000
13 [133.72,153.21) 0.050000 4 5.00000
14 [153.21,175.71) 0.050000 6 5.00000
15 [175.71,202.32) 0.050000 3 5.00000
16 [202.32,234.88) 0.050000 4 5.00000
17 [234.88,276.87) 0.050000 7 5.00000
18 [276.87,336.04) 0.050000 4 5.00000
19 [336.04,437.20) 0.050000 5 5.00000
20 [437.20,1596.00) 0.049982 6 4.99822 *** Warning: expected < 5 ***
Number of estimated parameters = 1
Number of intervals = 20
Degrees of Freedom = 18
Chi-Squared Test Statistic = 16.000784446070348
P-value = 0.5924925929222188
Hypothesis test at 0.05 level:
The p-value = 0.5924925929222188 is >= 0.05 : Do not reject hypothesis.
Goodness of Fit Test Results:
K-S test statistic = 0.0399213095618332
K-S test p-value = 0.9954253138552503
Anderson-Darling test statistic = 0.24859556182926212
Anderson-Darling test p-value = 0.9710833730000956
Cramer-Von-Mises test statistic = 0.025283543923658194
Cramer-Von-Mises test p-value = 0.9893094979248238
Finally, we can review the distribution plots and see that according the the P-P plot, Q-Q plot, histogram overlay, and empirical cumulative distribution overlay plot that the exponential distribution is an excellent probability model for this data.
val dist = NegativeBinomial(0.2, theNumSuccesses = 4.0)
val rv = dist.randomVariable
rv.advanceToNextSubStream()
val data = rv.sample(200)
val breakPoints = PMFModeler.makeZeroToInfinityBreakPoints(data.size, dist)
val pf = DiscretePMFGoodnessOfFit(data, dist, breakPoints = breakPoints)
println(pf.chiSquaredTestResults())Chi-Squared Test Results:
Bin Label P(Bin) Observed Expected
1 [ 0.00, 3.00) 0.016960 4 3.39200 *** Warning: expected < 5 ***
2 [ 3.00, 5.00) 0.039322 7 7.86432
3 [ 5.00, 6.00) 0.029360 10 5.87203
4 [ 6.00, 7.00) 0.035232 7 7.04643
5 [ 7.00, 8.00) 0.040265 7 8.05306
6 [ 8.00, 9.00) 0.044292 5 8.85837
7 [ 9.00,10.00) 0.047245 10 9.44893
8 [10.00,11.00) 0.049134 9 9.82689
9 [11.00,12.00) 0.050028 6 10.0056
10 [12.00,13.00) 0.050028 11 10.0056
11 [13.00,14.00) 0.049258 6 9.85162
12 [14.00,15.00) 0.047851 12 9.57015
13 [15.00,16.00) 0.045937 7 9.18734
14 [16.00,17.00) 0.043640 17 8.72798
15 [17.00,18.00) 0.041073 4 8.21457
16 [18.00,19.00) 0.038335 7 7.66693
17 [19.00,20.00) 0.035510 7 7.10200
18 [20.00,21.00) 0.032669 9 6.53384
19 [21.00,22.00) 0.029869 5 5.97379
20 [22.00,23.00) 0.027154 3 5.43072
21 [23.00,24.00) 0.024556 4 4.91126 *** Warning: expected < 5 ***
22 [24.00,26.00) 0.041903 13 8.38058
23 [26.00,28.00) 0.033376 9 6.67520
24 [28.00,31.00) 0.036998 6 7.39969
25 [31.00,36.00) 0.036799 7 7.35973
26 [36.00,Infinity) 0.033207 8 6.64147
Number of estimated parameters = 2
Number of intervals = 26
Degrees of Freedom = 23
Chi-Squared Test Statistic = 25.69659399548871
P-value = 0.31539706650371313
Hypothesis test at 0.05 level:
The p-value = 0.31539706650371313 is >= 0.05 : Do not reject hypothesis.
val f = IntegerFrequency(data)
val fp = f.frequencyPlot()
fp.showInBrowser()
val pmfModeler = PMFModeler(data)
val results = pmfModeler.estimateParameters(setOf(PoissonMLEParameterEstimator))
val e = results.first()
println(e)
val mean = e.parameters!!.doubleParameter("mean")
val pf = PoissonGoodnessOfFit(data.toDoubles(), mean = mean)
println(pf)
val plot = PMFComparisonPlot(data, pf.distribution)
plot.saveToFile("Lab_Count_PMF_Plot")
plot.showInBrowser()
Comments on Distribution Results