This model of social learning was independently introduced in Clifford and Sudbury (1973), Holley and Liggett (1975). The setting and dynamic process are the following:
It was shown that agents' states reach a consensus over any connected graph $G$ (Coalescing Random Walks).
import numpy as np
import scipy as sp
import networkx as nx
import matplotlib.pyplot as plt
%matplotlib inline
Implement the Voter Model and check how the number of agents' states changes with time. Run it for Karate club and Political Blogs networks.
G = nx.karate_club_graph()
y = range(G.number_of_nodes())
maxIter = 1000
numStates = np.zeros((maxIter,), dtype=int)
path = []
for i in xrange(maxIter):
numStates[i] = len(np.unique(y))
agent = np.random.choice(G.nodes())
adopt = np.random.choice(G.neighbors(agent))
y[agent] = y[adopt]
path.append((adopt, agent))
plt.plot(numStates)
[<matplotlib.lines.Line2D at 0x7f439625f050>]
numStates[-1]
1
# Some preprocessing for polblogs
A = nx.adj_matrix(nx.read_gml('polblogs.gml'))
G = nx.Graph(A)
for n,d in G.degree_iter():
if d == 0:
G.remove_node(n)
mapping = {}
i = 0
for n in G.nodes_iter():
mapping[n] = i
i+=1
G = nx.relabel_nodes(G,mapping)
plt.plot(numStates)
[<matplotlib.lines.Line2D at 0x7f4361143710>]
Try to write a code that identifies the path of opinion adoption starting from a particular node
G = nx.karate_club_graph()
y = range(G.number_of_nodes())
maxIter = 1000
numStates = np.zeros((maxIter,), dtype=int)
path = []
for i in xrange(maxIter):
numStates[i] = len(np.unique(y))
agent = np.random.choice(G.nodes())
adopt = np.random.choice(G.neighbors(agent))
y[agent] = y[adopt]
path.append((adopt, agent))
path[0:3]
[(16, 5), (3, 12), (2, 0)]
nx.draw(G, with_labels=True)
start = 6
rw = []
time = []
t = 0
for hop in path:
if hop[0] == start:
rw.append(hop)
time.append(t)
start = hop[1]
t+=1
pltrw = []
plttime = []
for i in xrange(len(rw)-1):
pltrw.extend((rw[i][0], rw[i][1], rw[i][1]))
plttime.extend((time[i], time[i], time[i+1]))
pltrw.extend((rw[-1][0], rw[1][1]))
plttime.extend((time[-1], time[-1]))
pltrw2 = pltrw[:]
plttime2 = plttime[:]
plt.figure(figsize=(5,10))
plt.plot(pltrw, plttime, pltrw2, plttime2)
[<matplotlib.lines.Line2D at 0x7f4360d83710>, <matplotlib.lines.Line2D at 0x7f4360d83990>]