This short workshop is intended to introduce agent-based modeling and kickstart working with NetLogo. In the first part we will discuss why one would use ABM’s as a theoretical tool to understand democratic debate. In the second part, we will get you started with NetLogo, a very intuitive and easy tool to program simple ABMs. We explain the basics of NetLogo and show some simple and some more advanced code.
Today, we…
Diffusion model of innovation:
Some other NetLogo models:
Very useful in your NetLogo endeavors:
On actor-based thinking:
On the relation between ABM and CSS:
A more practical guide to starting with ABM:
If you want, you can do this little exercise to get your hands dirty with NetLogo coding.
For the hands-on part of the session, we looked at a simple alternative to Everett Rogers’ theory about the diffusion of innovation from a complexity perspective. Rogers argued that the often observed S-curve in the adoption of innovations is due to differences in individual tendencies to adopt an innovation. Assuming that (1) such a tendency is normally distributed in a population, and (2) people are aware of the number of others that have adopted the innovation, reveals the non-linear relationship between time and share of the population that adopted some innovation.
Alternatively, Agent-Based Modeling can offer a competing explanation that relies on network structure, but does not make assumptions about individual differences, nor assumes that people have complete information about the state of the world.
We programmed a simple diffusion model in NetLogo. Turtles are placed on a ring network and adopt the color trait of their neighbors depending on some threshold. The code includes a rewiring procedure that enabables the construction of long range ties.
BehaviorSpace
and report the results to the group.We ran an experiment in BehaviorSpace where we varied the proportion of rewiring between 0 and 0.1 with increments of 0.01. We asked NetLogo to count the number of agents that adopted the innovation at every tick and write the result to a csv file. The parameter settings of the experiment read:
["rewiring-proportion" [0 0.01 0.1]]
["infect-seed-neighbors" true]
["number-of-nodes" 500]
["average-node-degree" 4]
["threshold-value" 1]
This dataset is now ready to be analyzed in R (or any statistical software of course). The first thing to notice is that rewiring drastically changes the time until convergence. The distribution across conditions is very skewed, and therefore we cannot simply plot the number of agents that adopted the innovation, by rewiring proportion. We need to transform the data to an aggregated format where the mean proportion of agents that adopted the trait in a certain period, or percentile of the run is calculated. This function looks like:
DiffusionPercentiles <- function(Data=raw.df,Definition=10){
df <- data.frame(id=c(99),rewiring=c(99),ticks=c(99),percentile=c(99),adopted=c(99))
iterator <- 1
for(i in unique(Data$X.run.number.)){
increment <- max(Data$X.step.[Data$X.run.number==i]) * 1 / Definition
for(j in 1:Definition){
df[iterator,] <- c(
i,
Data$rewiring.proportion[Data$X.run.number.==i][1],
max(Data$X.step.[Data$X.run.number.==i]),
j,
mean(Data$count.turtles.with..color...green.[(Data$X.step. > 0 - increment + increment * j) & Data$X.step. < increment * j & Data$X.run.number. == i]))
iterator <- iterator + 1
}
}
return(df)
}
# and actually run the function:
df <- DiffusionPercentiles(Definition=10)
With this dataset, we can plot the mean convergence time, by rewiring proportion:
ggplot(data=df,aes(x=rewiring,y=ticks)) +
stat_summary(geom="bar", fun.y=mean, col='black',fill='lightgrey') +
stat_summary(geom="errorbar", fun.data=mean_cl_normal,width=.002,col='red') +
theme_linedraw()
Indeed, the distribution is rather skewed. When the network is free of any rewiring, the innovation diffuses neatly around the circle network. As more rewiring is introduced, the innovation can travel speedily across some longer ties to infect the larger network quicker. If we now plot the proportion of adopers by model period, we see that this explanation is indeed correct, and we nicely reproduce Rogers’ S-curve:
ggplot(data=df,aes(x=percentile,y=adopted)) +
stat_summary(geom="line", fun.y=mean,col='red') +
stat_summary(geom="errorbar", fun.data=mean_cl_normal,width=.5,col='red') +
stat_summary(geom="point", fun.y=mean,size=1) +
facet_wrap(rewiring ~ .,nrow=3) +
ylim(0,1) +
theme_linedraw()