Building your first model

Installing MCHammer

Install the package as usual using Pkg.

julia> using Pkg
julia> Pkg.("MCHammer")

If you need to install direct, we recommend using ']' to go in the native Pkg manager.

(v1.1) pkg> add https://github.com/etorkia/MCHammer.jl

Loading MCHammer

To load the MCHammer package

julia> using MCHammer

Getting your environement setup for modeling

In order to build your first model, you will need to get a few more packages installed:

  • Distributions.jl : To build a simulation, you need distributions as inputs. Julia offers univariate and multivariate distributons covering most needs.

  • StatsBase.jl and Statistics.jl : These packages provide all the functions to analyze results and build models.

To load the support packages:

  julia> using Distributions, Statistics, StatsBase, DataFrames

Building a simple example

EVERY MONTE CARLO MODEL HAS 3 COMPONENTS

  • Inputs: Ranges or Single Values
  • A Model: Set of mathematical relationships f(x)
  • Outputs: The variable(s) of interest you want to analyze

Main Distributions for most modeling situations

Though the most used distributions are cite below, Julia's Distributions package has an impressive array of options. Please check out the complete library of distributions at Distributions.jl

  • Normal()
  • LogNormal()
  • Triangular()
  • Uniform()
  • Beta
  • Exponential
  • Gamma
  • Weibull
  • Poisson
  • Binomial
  • Bernoulli
In [28]:
# In order to define a simulated input you need to use the *rand* function. By assigning a a variable name, you can generate any simulated vector you want.

 input_variable = rand(Normal(0,1),100)
Out[28]:
100-element Array{Float64,1}:
 -0.1056253315578025 
 -0.7842779213346366 
 -0.7199843193289197 
 -0.3553414949106345 
 -2.4901305922970742 
  1.6421865929266963 
  0.5563354707314404 
 -1.1061967458902224 
  1.108233777209768  
  0.3906079526297676 
 -0.5949705948218603 
  1.5250950435549069 
  0.21884828304721668
  ⋮                  
  2.4341721813144535 
 -0.8105597372690737 
  0.817156591035643  
 -0.5446455673511615 
 -0.194198053196012  
  0.6444608367361812 
 -0.6819628768158978 
  1.248726634128034  
 -2.256016183089206  
  1.2114040479147767 
  0.8165198905722939 
 -0.07373926584547935

Creating a simple model

A model is either a visual or mathematical representation of a situation or system. The easiest example of a model is PROFIT = REVENUE - EXPENSES

Let's create a simple simulation model with 1000 trials with the following inputs:

Key Variables

julia> n_trials = 1000

julia> Revenue = rand(TriangularDist(2500000,4000000,3000000), n_trials)

julia> Expenses = rand(TriangularDist(1400000,3000000,2000000), n_trials)


The Model

`Profit = Revenue - Expenses`

Running the model in Julia

In [29]:
using Distributions, StatsBase, DataFrames, MCHammer

n_trials = 1000
Revenue = rand(TriangularDist(2500000,4000000,3000000), n_trials)
Expenses = rand(TriangularDist(1400000,3000000,2000000), n_trials)

#Create the Profit vector (OUTPUT)
Profit = Revenue - Expenses
Out[29]:
1000-element Array{Float64,1}:
  976563.4073711201        
       1.0486104316120055e6
       1.2125922265277612e6
  963857.6509167028        
       1.476809107585155e6 
       1.1851168400961212e6
  811163.0497121238        
  673238.3460020148        
  503335.29542519245       
       1.6180127587181288e6
       1.1780250495874803e6
 -292203.01681957254       
       1.1107313328670368e6
       ⋮                   
       1.3034112150359987e6
  757792.9831489492        
       1.5491446060104172e6
  947916.5673932862        
       1.7110966560926486e6
  910738.9365896229        
  360569.00728906924       
       1.71485153798351e6  
       1.9591764767637542e6
       1.8781278878390028e6
  710248.7905332441        
  639725.7014484056        

Analyzing the results

In [30]:
# the fractiles() allows you to get the percentiles at various increments. 

fractiles(Profit)
Out[30]:
11×2 Array{Any,2}:
 "P0.0"    -292203.0      
 "P10.0"         4.65989e5
 "P20.0"         6.66204e5
 "P30.0"         8.0237e5 
 "P40.0"         9.38521e5
 "P50.0"         1.03268e6
 "P60.0"         1.15557e6
 "P70.0"         1.28323e6
 "P80.0"         1.42063e6
 "P90.0"         1.64144e6
 "P100.0"        2.40401e6
In [31]:
density_chrt(Profit)
Summary Stats:
Length:         1000
Missing Count:  0
Mean:           1045622.486506
Minimum:        -292203.016820
1st Quartile:   742333.812023
Median:         1032683.646947
3rd Quartile:   1348395.823772
Maximum:        2404005.936698
Type:           Float64

Mean: 1.0456224865060581e6
Std.Dev: 456249.5746755252
Prob. of Neg.: 0.011

p10, p50, p90 : [4.65989e5, 1.03268e6, 1.64144e6]
Out[31]:
Sim. Values -6×10⁶ -5×10⁶ -4×10⁶ -3×10⁶ -2×10⁶ -1×10⁶ 0 1×10⁶ 2×10⁶ 3×10⁶ 4×10⁶ 5×10⁶ 6×10⁶ 7×10⁶ 8×10⁶ -5.0×10⁶ -4.8×10⁶ -4.6×10⁶ -4.4×10⁶ -4.2×10⁶ -4.0×10⁶ -3.8×10⁶ -3.6×10⁶ -3.4×10⁶ -3.2×10⁶ -3.0×10⁶ -2.8×10⁶ -2.6×10⁶ -2.4×10⁶ -2.2×10⁶ -2.0×10⁶ -1.8×10⁶ -1.6×10⁶ -1.4×10⁶ -1.2×10⁶ -1.0×10⁶ -8.0×10⁵ -6.0×10⁵ -4.0×10⁵ -2.0×10⁵ 0 2.0×10⁵ 4.0×10⁵ 6.0×10⁵ 8.0×10⁵ 1.0×10⁶ 1.2×10⁶ 1.4×10⁶ 1.6×10⁶ 1.8×10⁶ 2.0×10⁶ 2.2×10⁶ 2.4×10⁶ 2.6×10⁶ 2.8×10⁶ 3.0×10⁶ 3.2×10⁶ 3.4×10⁶ 3.6×10⁶ 3.8×10⁶ 4.0×10⁶ 4.2×10⁶ 4.4×10⁶ 4.6×10⁶ 4.8×10⁶ 5.0×10⁶ 5.2×10⁶ 5.4×10⁶ 5.6×10⁶ 5.8×10⁶ 6.0×10⁶ 6.2×10⁶ 6.4×10⁶ 6.6×10⁶ 6.8×10⁶ 7.0×10⁶ -5×10⁶ 0 5×10⁶ 1×10⁷ -5.0×10⁶ -4.5×10⁶ -4.0×10⁶ -3.5×10⁶ -3.0×10⁶ -2.5×10⁶ -2.0×10⁶ -1.5×10⁶ -1.0×10⁶ -5.0×10⁵ 0 5.0×10⁵ 1.0×10⁶ 1.5×10⁶ 2.0×10⁶ 2.5×10⁶ 3.0×10⁶ 3.5×10⁶ 4.0×10⁶ 4.5×10⁶ 5.0×10⁶ 5.5×10⁶ 6.0×10⁶ 6.5×10⁶ 7.0×10⁶ h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? -1.5×10⁻⁶ -1.0×10⁻⁶ -5.0×10⁻⁷ 0 5.0×10⁻⁷ 1.0×10⁻⁶ 1.5×10⁻⁶ 2.0×10⁻⁶ 2.5×10⁻⁶ -1.00×10⁻⁶ -9.50×10⁻⁷ -9.00×10⁻⁷ -8.50×10⁻⁷ -8.00×10⁻⁷ -7.50×10⁻⁷ -7.00×10⁻⁷ -6.50×10⁻⁷ -6.00×10⁻⁷ -5.50×10⁻⁷ -5.00×10⁻⁷ -4.50×10⁻⁷ -4.00×10⁻⁷ -3.50×10⁻⁷ -3.00×10⁻⁷ -2.50×10⁻⁷ -2.00×10⁻⁷ -1.50×10⁻⁷ -1.00×10⁻⁷ -5.00×10⁻⁸ 0 5.00×10⁻⁸ 1.00×10⁻⁷ 1.50×10⁻⁷ 2.00×10⁻⁷ 2.50×10⁻⁷ 3.00×10⁻⁷ 3.50×10⁻⁷ 4.00×10⁻⁷ 4.50×10⁻⁷ 5.00×10⁻⁷ 5.50×10⁻⁷ 6.00×10⁻⁷ 6.50×10⁻⁷ 7.00×10⁻⁷ 7.50×10⁻⁷ 8.00×10⁻⁷ 8.50×10⁻⁷ 9.00×10⁻⁷ 9.50×10⁻⁷ 1.00×10⁻⁶ 1.05×10⁻⁶ 1.10×10⁻⁶ 1.15×10⁻⁶ 1.20×10⁻⁶ 1.25×10⁻⁶ 1.30×10⁻⁶ 1.35×10⁻⁶ 1.40×10⁻⁶ 1.45×10⁻⁶ 1.50×10⁻⁶ 1.55×10⁻⁶ 1.60×10⁻⁶ 1.65×10⁻⁶ 1.70×10⁻⁶ 1.75×10⁻⁶ 1.80×10⁻⁶ 1.85×10⁻⁶ 1.90×10⁻⁶ 1.95×10⁻⁶ 2.00×10⁻⁶ -1×10⁻⁶ 0 1×10⁻⁶ 2×10⁻⁶ -1.0×10⁻⁶ -9.0×10⁻⁷ -8.0×10⁻⁷ -7.0×10⁻⁷ -6.0×10⁻⁷ -5.0×10⁻⁷ -4.0×10⁻⁷ -3.0×10⁻⁷ -2.0×10⁻⁷ -1.0×10⁻⁷ 0 1.0×10⁻⁷ 2.0×10⁻⁷ 3.0×10⁻⁷ 4.0×10⁻⁷ 5.0×10⁻⁷ 6.0×10⁻⁷ 7.0×10⁻⁷ 8.0×10⁻⁷ 9.0×10⁻⁷ 1.0×10⁻⁶ 1.1×10⁻⁶ 1.2×10⁻⁶ 1.3×10⁻⁶ 1.4×10⁻⁶ 1.5×10⁻⁶ 1.6×10⁻⁶ 1.7×10⁻⁶ 1.8×10⁻⁶ 1.9×10⁻⁶ 2.0×10⁻⁶ Frequency

Sensitivity Analysis

In [32]:
# First we need to create a sensitivity table with hcat() using both the input and output vectors. 
s_table = hcat(Profit, Revenue, Expenses)

#We then need to convert to a DataFrame
s_table = DataFrame(s_table)
names!(s_table, [:Profit, :Revenue, :Expenses])
Out[32]:

1,000 rows × 3 columns

ProfitRevenueExpenses
Float64Float64Float64
19.76563e53.12433e62.14777e6
21.04861e63.28707e62.23846e6
31.21259e63.3611e62.14851e6
49.63858e52.75171e61.78785e6
51.47681e63.51377e62.03696e6
61.18512e63.16447e61.97935e6
7811163.02.87815e62.06698e6
86.73238e52.88134e62.2081e6
95.03335e52.87459e62.37125e6
101.61801e63.70633e62.08832e6
111.17803e62.851e61.67298e6
12-292203.02.64037e62.93257e6
131.11073e62.84189e61.73116e6
141.06254e63.55715e62.49461e6
157.36977e52.71128e61.9743e6
161.54512e63.21127e61.66616e6
171.18807e63.2577e62.06963e6
181.00617e62.80086e61.79469e6
198.75621e53.00293e62.12731e6
201.17191e63.24763e62.07572e6
211.57849e63.35465e61.77616e6
227.24918e52.72535e62.00043e6
231.63241e63.38086e61.74845e6
249.10269e53.09464e62.18438e6
252.19581e63.71803e61.52222e6
261.38676e62.90936e61.52259e6
271.68844e63.92133e62.23289e6
281.69671e63.86693e62.17022e6
298.16937e52.88717e62.07024e6
30252953.02.6132e62.36024e6
In [33]:
# To produce a sensitivity tornado chart, we need to select the output against which the inputs are measured for effect.
sensitivity_chrt(s_table, 1, 3)
2×6 DataFrame
│ Row │ name     │ correlation │ abs_cor  │ PPMC     │ cont_var  │ impact   │
│     │ AnyAnyAnyAnyAnyAny      │
├─────┼──────────┼─────────────┼──────────┼──────────┼───────────┼──────────┤
│ 1   │ Revenue  │ 0.684183    │ 0.684183 │ 0.697044 │ 0.492873  │ Positive │
│ 2   │ Expenses │ -0.694006   │ 0.694006 │ -0.71426 │ -0.507127 │ Negative │
Out[33]:
% Contribution to Variance -3.5 -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 -3.0 -2.9 -2.8 -2.7 -2.6 -2.5 -2.4 -2.3 -2.2 -2.1 -2.0 -1.9 -1.8 -1.7 -1.6 -1.5 -1.4 -1.3 -1.2 -1.1 -1.0 -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0 -4 -2 0 2 4 -3.0 -2.8 -2.6 -2.4 -2.2 -2.0 -1.8 -1.6 -1.4 -1.2 -1.0 -0.8 -0.6 -0.4 -0.2 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0 Positive Negative impact h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? Revenue Expenses Input Variables with Biggest Impact