How to determine distribution of real-world data and then apply same distribution to model with Agents.jl

Hello,

Goal: trying to determine distribution from 4Q22 data set and apply the same distribution to a network model using Agents.jl. See 4Q22 data on xy-grid.

Background: I had an earlier post on Discourse where I guessed that the distribution was Poisson, but the data are not normally distributed. See actual grid of data below,

Latest attempt: I used the “fit” function in Distributions.jl to get the following info on the 4Q22 data.
Gamma result: Gamma{Float64}(α=14.01547510539733, θ=6.195715980420822)
Exponential result: Exponential{Float64}(θ=86.83590308370044)
Poisson result: Poisson{Float64}(λ=86.83590308370044)

Gamma seems the best option, but still looks normally distributed. See xy, xyz grids and code below. Should I take a different approach? Am I misunderstanding or misapplying the results from “fit”?


Thank you. Best.

Blockquote##Gamma distribution for x and y coordinates
xes = rand(Gamma(14), n_banks)
yes = rand(Gamma(6), n_banks)

#=
##Erlang distribution for x and y coordinates
shape = 7
xrate = .5
yrate = 1.0
uninsured_values = rand(Erlang(shape, xrate), n_banks)
investments_values = rand(Erlang(shape, yrate), n_banks)
=#

#add Bank agents;
#for i in 1:n_banks
for (x, y) in zip(xes, yes)    #Poisson
    add_agent!(Bank, model,
    #pos=(x,y),      #Poisson
    pos=(round(Int, x), round(Int, y)),    #Gamma
    #uninsured = uninsured_values[i],
    #investments = investments_values[i],
    uninsured = rand(),        #Poisson
    investments = 2 * rand(),    #Poisson
    totDep = 100,    
    AFS_securities = rand(1:10),
    social_network = rand(1:3),    
    vul = false,
    health = true,
    acolor = :black,
    interest_rate = rand(1:10),
    )
end

Why don’t you just sample from the empirical distribution?

Hello,

How would I sample the distribution?

I may be misinterpreting my data. The way the agent-based model is set-up, each bank agent gets placed on a 2D or 3D grid. On the 2D grid, I can “eyeball” it to see that there is a normal distribution since all quadrants appear to be equally covered. Thanks for your insights.

I’m not sure I really understand your problem, but what I think it is currently is you have a population of real world observations with some values of “investments” and “uninsured” and you now want to build an Agents.jl model in which there are simulated agents with those values as well, and you want the distribution of investment and uninsured across the agents in your model to follow the distribution that you observe.

If that’s right, then why don’t you just instantiate the agents by drawing from the actual data you have? I’m not sure what format your data is in, but for most collections you can just do rand(collection, n) to get n random draws.

E.g. if your data is a vector of tuples (investment, uninsured):

julia> data = [(120, 34), (75, 65), (160, 23)]
3-element Vector{Tuple{Int64, Int64}}:
 (120, 34)
 (75, 65)
 (160, 23)

julia> rand(data)
(120, 34)

julia> rand(data, 5)
5-element Vector{Tuple{Int64, Int64}}:
 (120, 34)
 (75, 65)
 (75, 65)
 (75, 65)
 (120, 34)

Ahhh…so I have a CSV file with 10K rows of the real world data. What would the code look like to call the dataframe and add agents accordingly? Instead of creating the agents with random variables, I’d call the dataframe? Thanks again.

Blockquote
df = CSV.read(“////CallReport/4Q22CallDataDistribution3.csv”, DataFrame)

uninsured = rand(df, :Uninsured),
investments = 2 * rand(df, :Investments),

You probably want to capture the correlation between uninsured and investment, so you’d want to sample rows rathern than a value from each column separately. Something like:

function draw_values(df)
    row = rand(1:nrow(df))
    return df[row, [:Investments, :Uninsured]
end

and then an agent is initialized as

vals = draw_values(df)
add_agent!(Bank, model, 
    pos = (vals.Investments, vals.Uninsured),
    (...)
)

(take with a grain of salt, it’s been a very long time since I’ve used Agents.jl…)

Wow. Now I get it! Thank you ever so much. You’re the best.

Have a great day.

1 Like