Generalised Urn Model with Triggering
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
WHAT IS IT?
This model's scope is a NetLogo implementation of the Generalised Urn Model with Triggering (GUMT) proposed by Tria et al (2017)
The model can explain the popularity distributions (especially the "rich get richer" phenomenon) found in a range of online and social media systems, where old items tend to have the highest popularity, but critically, newer "trending" items also have the ability to gain popularity.
HOW IT WORKS
The model is based on "Polya's Urn" approach to probability, where randomly drawing a coloured ball, leads to the addition of more balls of the same colour to the urn, thereby making it more likely to come out again.
The additional "triggering" rule simulates the "adjacent possible" by adding balls of new colours when a previously unselected ball is chosen. This is the UMT
To make the model more amenable to novelties from the adjacent possible, the GUMT introduces the idea of a category or "cohort", where a new set of balls share the same cohort. If we weight the probabability towards drawing from balls within the current cohort, we create a slight balancing bias in favour of newer colours.
HOW TO USE IT
The initial-colour-count is the amount of colours initially in the urn; this number is also used with the triggering rule for the number of new colours to be added on each trigger.
Without the triggering rule, the model is a simple Polyas Urn. Use the triggering switch to turn on triggering.
Inputs
In addition to the starting number of balls, the GUMT uses differential weights as inputs to the model:
- Non-cohort weight is the weighting for balls that are in the actual history (have been drawn before, but are not in the current cohort (current meaning the cohort of the previously drawn ball)
- Ap-weight is the weighting for balls in the current cohort that have not yet been drawn (adjacent possible)
- Non-cohort-ap-weight is the weighting for balls in other cohorts in the adjacent possible.
If all weights are set to 1, then the model is reduced to the standard UMT.
Outputs
The model outputs are
- The gini-index which is used as a sign of equality of distribution. This is 0 for an evenly distributed ball count, but 1 if only one colour has all the balls.
- The youth-index is an indicator of the ages of colours. This will be 0 if all the balls are coming from the original colours, but increases up to 1 if all the balls come from newer colours.
THINGS TO NOTICE
The underlying trend and default mode is for balls drawn first to be most common. This is shown in the label counts and the distribution chart. Also, the gini curve shows that most of the total numbers is made up of balls drawn early on. The "popularity by time slot" plot shows that most popular balls at any one time tend to be those created at time 0.
THINGS TO TRY
The weighting sliders can be used to adjust the probabilities of picking balls from the adjacent possible or from other cohorts, affecting the eventual distributions of the balls. Try to aim for a shallower gini distribution and to have more varied points in the time slot chart.
At the end of a run (say 300 ticks), compare the final gini-index and youth-index from the inputs you have chosen. A lower gini-index and higher-youth index indicate a more evenly distributed population with better representation of new items.
NETLOGO FEATURES
The model uses the rnd extension to allow random selections with individual weightings for each agent, that can be calculated dynamically. This allows for the adjustments of bias toward the current cohort and the adjacent possible colours.
RELATED MODELS
The model is quite closely linked to the Wealth Distribution model in the models library (Social Science section), which has a similar unequal distribution in favour of a small number of individuals - in this case linked more with the availability of environmental resources than pure probabilities.
CREDITS AND REFERENCES
Tria, F., Loreto, V. & Monechi, B., 2017. Waves of novelties in the expansion into the adjacent possible. PLoS ONE, pp.1–18.
Comments and Questions
extensions[rnd] globals[selected-colour-count current-cohort last-cohort last-colour max-ball-index ball-colours ball-pile-x ball-pile-y colour-created-time ball-counts ball-in-transit gini-index youth-index time-to-unlocked] turtles-own[in-transit cohort ball-index adjacent-possible ball-created-time] to setup ca reset-ticks set-default-shape turtles "circle" import-drawing "urn.png" ;set initial-colour-count 3 set selected-colour-count 0 set ball-in-transit false set current-cohort 1 set last-cohort 1 set max-ball-index 0 set ball-counts [] set ball-colours [15 65 95 125 85 45 55 135 75 35 25 5 115 13 63 93 123 83 43 53 133 73 33 23 2 113 17 67 97 127 87 47 57 137 77 37 27 7 117] set ball-pile-x [-14 -11 -8 -5 -2 1 4 7 10 13 -14 -11 -8 -5 -2 1 4 7 10 13 -14 -11 -8 -5 -2 1 4 7 10 13 -14 -11 -8 -5 -2 1 4 7 10 13] set ball-pile-y [14 14 14 14 14 14 14 14 14 14 10 10 10 10 10 10 10 10 10 10 6 6 6 6 6 6 6 6 6 6 2 2 2 2 2 2 2 2 2 2] set colour-created-time [] set time-to-unlocked 0 set gini-index 0 set youth-index 0 ; add initial balls repeat initial-colour-count [ start-new-colour set ball-counts lput 1 ball-counts ] ask turtles[ ; Act like these initial balls have been "instantiated" set adjacent-possible false ; Put each initial ball in a different cohort set cohort current-cohort set current-cohort current-cohort + 1 ] setup-plots end ; Main function pick a new ball and move it to the pile. to go pick-ball set ball-in-transit true if behaviorspace-run-number = 0 [move-to-pile] set ball-counts [] clear-output tick set-current-plot "gini-curve" clear-plot do-plotting update-labels end ; Select a new ball from the urn, triggering additions to pick-ball set last-colour 0 let last-ball-index 0 ; hatch according to turtle weights ask rnd:weighted-one-of turtles [colour-weight][ hatch 1 [ setxy 0 -2.2 set shape "circle" set size 2 let mycolor color ; set turtle vars set in-transit true set last-colour color set last-ball-index ball-index set last-cohort cohort set ball-created-time ticks ; ball colour is "instantiated", so no longer in the adjacent possible ask turtles with [color = mycolor] [set adjacent-possible false] ] ] if triggering [ ; we add new colours if the ball was from the adjacent possible if count turtles with [color = last-colour] = 2 [ set selected-colour-count selected-colour-count + 1 ; Is this from the adjacent possible? if (selected-colour-count > (initial-colour-count - 1)) [ ; do we still have new colours? ifelse (max-ball-index + initial-colour-count < length(ball-colours)) [ set current-cohort current-cohort + 1 ; Create balls of new colours repeat initial-colour-count + 1[ start-new-colour ] ] [ ; Store the time the last colour was unlocked if time-to-unlocked = 0 [set time-to-unlocked ticks] ] ] ] ] end ; Allow for different weights to different types of balls - used by the weighted-random function to-report colour-weight ; Initially use 1 across the board if max-ball-index = initial-colour-count[ report 1 ] ; total of balls that have been drawn before ;let drawn-count count turtles with [not adjacent-possible] let mycohort cohort ; is the current ball from the adjacent possible? (colours with only 1 ball) ifelse not adjacent-possible[ ifelse last-cohort = mycohort [ report 1 ] [ report non-cohort-weight ] ] ; balls in the adjacent possible [ ifelse last-cohort = mycohort [ report ap-weight ] [ report non-cohort-ap-weight ] ] end ; triggers creation of a new ball colour to start-new-colour create-turtles 1 [ set ball-index max-ball-index setxy 0 -2.2 set color item ball-index ball-colours let x item ball-index ball-pile-x let y item ball-index ball-pile-y facexy x y ; for the inherited trajectory setxy x y set shape "circle" set in-transit false set size 2 set max-ball-index max-ball-index + 1 set cohort current-cohort set adjacent-possible true ; keep track of how far into the model the new colour is added set colour-created-time lput ticks colour-created-time ; add a new pen to the distribution plot set-current-plot "distribution" create-temporary-plot-pen word "ball" ball-index ] end ; Animate the ball moving to the relevant pile to move-to-pile while [ball-in-transit] [ ; See if it has reached pile ask turtles with [in-transit][ ifelse ycor > item ball-index ball-pile-y [ ; ball has reached the pile set shape "checker piece 2" set size 3 set ball-in-transit false set in-transit false ] [ fd 0.008 ] ] ] end ; this updates the charts dynamically as we have new colours being added so can't store the pens to do-plotting let current-pen 0 repeat max-ball-index [ set-current-plot "distribution" set-current-plot-pen word "ball" current-pen set-plot-pen-color item current-pen ball-colours plotxy ticks count turtles with [color = item current-pen ball-colours] set-current-plot "gini-curve" set-current-plot-pen "gini" set ball-counts lput count turtles with [color = item current-pen ball-colours] ball-counts plotxy item current-pen colour-created-time sum ball-counts set current-pen current-pen + 1 ] let current-tick-interval floor(ticks / 10) if ticks mod 10 = 0 and current-tick-interval > 0 [ ;record most popular after intervals of 10 ticks set-current-plot "Popular by time slot" set-current-plot-pen "appearance" ;get the colour of the most popular in the time slot let current-index 0 let colour-count 0 let last-colour-count 0 let top-colour 0 let youth-sum 0 repeat max-ball-index [ let current-colour item current-index ball-colours set colour-count count turtles with [(color = current-colour) and (ball-created-time >= (current-tick-interval - 1) * 10 ) and (ball-created-time < current-tick-interval * 10) ] set youth-sum youth-sum + (item current-index ball-counts * item current-index colour-created-time) if colour-count > last-colour-count[ set last-colour-count colour-count set top-colour current-colour ] set current-index current-index + 1 ] let youth-ticks ticks ; calculate youth index if (time-to-unlocked < ticks and time-to-unlocked > 0)[ set youth-ticks time-to-unlocked ] set youth-index youth-sum / (sum(ball-counts) * youth-ticks) ;get the created time of the top colour in the interval set-plot-pen-color top-colour let top-colour-index [ball-index] of one-of turtles with [color = top-colour] let appearance-time item top-colour-index colour-created-time plotxy current-tick-interval * 10 appearance-time ] ;calculate gini-index let sorted-count sort ball-counts let cum-count 0 let index 0 set gini-index 0 ;print word "number of colours: " max-ball-index ;print word "counts: " ball-counts repeat max-ball-index [ set cum-count cum-count + ((max-ball-index - index ) * item index sorted-count) set index (index + 1) ] set gini-index (1 / max-ball-index) * (max-ball-index + 1 - (2 * ( cum-count / sum(ball-counts)))) update-plots end ; this procedure puts the colour count labels onto the relevant patches to update-labels let current-colour 0 repeat max-ball-index [ ask patch item current-colour ball-pile-x (item current-colour ball-pile-y - 2)[ set plabel item current-colour ball-counts ;count turtles with [color = item current-colour ball-colours] ] set current-colour current-colour + 1 ] end to-report gini report gini-index end to-report youth report youth-index end
There is only one version of this model, created about 8 years ago by Paul Matthews.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
Generalised Urn Model with Triggering.png | preview | Preview for 'Generalised Urn Model with Triggering' | about 8 years ago, by Paul Matthews | Download |
urn.png | png | Urn image - should be placed in same folder as model | about 8 years ago, by Paul Matthews | Download |
This model does not have any ancestors.
This model does not have any descendants.