Product adoption curve estimation is a marketing domain that can benefit from agent-based modeling. As I am currently working on an agent-based modeling framework I wanted to add a simple word-of-mouth agent-based product sales model to this blog. The model can be used as a simple baseline for further modifcations (customizing). I am implementing this model in Python. The framework applied by me can be found here:
- Link: abm_framework
I have already shared two other examples applying above framework. In the first example I developed an agent-based SIR model. Such models can e.g. be used to model disease spread.
In another example I implemented a social segregation model in Python.
I will now briefly discuss the word-of-mouth model and show its implementation in Python.
Simple conceptual word-of-mouth model
This example applies a grid-based simulation environment with a single agent population. Each agent is characterized by a binary variable. The variable represents whether the agent has already purchased the new product (product adoption), or not.
The following logic is applied:
- For each iteration, all agents are called once (in random sequence)
- When an agent is called the agent assesses its neighbourhood
- If the agent has already purchased the new product neighbours are influenced by the agent and convinced to purchase the new product with a specified probability. Or vice versa, the agent is convinced by any neighbour that has already purchased the product (with the same probability)
- Agents can only purchase the product once. Once they have purchased the product their status remains unchanged
Agent-based word-of-mouth model in Python
The code below applies the abm_framework and implements above word-of-mouth model.
__author__ = "Linnart Felkl"
__email__ = "LinnartSF@gmail.com"
if __name__ == "__main__":
print("demo starts")
import sys
from pathlib import Path
file = Path(__file__).resolve()
parent, root = file.parent, file.parents[1]
sys.path.append(str(root))
# remove the current file's directory from sys.path, unless already removed
try:
sys.path.remove(str(parent))
except ValueError:
pass
import data
import stats
import config
import framework
import random
import animation
# setup database manager and connection
db = data.Database("sqlite3", config.path_databasefile)
db_manager = data.Manager(db)
# create an empty environment
env = framework.Environment(1, True, 20, 20, db_manager)
# create initial of customers
attrs = ["purchased"]
datatypes = ["INTEGER"]
pops = framework.Populations(amount = 1, env = env, db_manager = db_manager, attributes = attrs, datatypes = datatypes)
pops.add_population(name = "customers",
size = 100,
attributes = attrs,
datatypes = datatypes,
initialvals = [0]
)
# model specific global settings (parameter values)
_prob_recommend = 0.03
_impactarea = 2
_initialclients = 1
# setup simulation
sim = framework.Simulation(200)
# make sure that environment and agents tables in database are ready
pops.write_env_to_db(sim.Iteration)
pops.write_agents_to_db(sim.Iteration)
agents = pops.get_agents()
# set initial purchases
for _ in range(_initialclients):
agent = random.choice(agents)
agent.set_attr_value("purchased", 1)
# execute simulation run; with centralized simulation control
while sim.run():
# select one random agent after the other
random.shuffle(agents)
for agent in agents:
# get that agents neighbourhood
neighbours = env.get_neighbourhood(agent, mode = "moore", radius = _impactarea)
for neighbour in neighbours:
if agent.get_attr_value("purchased") == 1 and neighbour.get_attr_value("purchased") == 0 and random.uniform(0,1) < _prob_recommend: neighbour.set_attr_value("purchased", 1)
if agent.get_attr_value("purchased") == 0 and neighbour.get_attr_value("purchased") == 1 and random.uniform(0,1) < _prob_recommend:
agent.set_attr_value("purchased", 1)
break
# update results in database, for agents and for environment
pops.write_agents_to_db(sim.Iteration)
pops.write_density_to_db(sim.Iteration)
# get dataframes with simulation results
agents_df = db_manager.get_agentsdf()
density_df = db_manager.get_densitydf()
# visualize simulation data
stats.set_fontsizes(8,10,12)
stats.plot_avgattr_lines(["purchased"], agents_df)
stats.save_plot("avgpurchasingshare")
animation.animate_density(
df = density_df,
filename = "purchasinganimation",
attr = "purchased",
defaultsize = 50,
color = "blue",
tpf = 0.05
)
# end program
db.close()
print("demo ends")
I discuss the simulation results in the following section.
Word-of-mouth simulation results
Below line plot was generated by the abm_framework and shows the total share of customers that have already purchased the product. With the given model settings the market is fully penetrated . Product adoption follows a somewhat s-shaped adoption curve. This is what I would have expected from the model settings.
Below animation furthermore shows product adoption throughout the grid. This simulation started with a single agent. This is why product adoption spreads from there. The grid is endless, meaning that when exiting the grid on e.g. the right side, you enter the grid on the left side. When exiting the grid on the top, you enter the grid at the bottom. The grid has no boundary.
Results will differ when you adjust model settings and conditions. Results will also be affected by any additional mechanisms in the model. Using this simple baseline word-of-mouth agent-based model you can create your own modified product adoption model.
Concluding remarks on word-of-mouth ABM model
In this article I presented another application of the abm_framework in Python. The framework supports smaller grid-based agent-based modeling. Using the model I was able to implement a simple baseline word-of-mouth agent-based model. The model shows how product adoption follows an s-shaped curve, and how the market, in this case, is fully penetrated after some time. You can use this simple baseline model to create your own modified version. For example you could implement a model with several competing products. Or you could implement a model with various customer groups and a range of different user experiences.
Data scientist focusing on simulation, optimization and modeling in R, SQL, VBA and Python
Leave a Reply