Random Walks

Script to demonstrate a one dimensional random walk.

We assume that a step can be taken either to the left or to the right. We would like to find out how far away from the starting we would find someone that is doing a random walk as a function of the steps that he/she has taken. We will find that the most probable position to find the random walker is always at the origin. But, the probability of finding it at distances farther away from the origin keeps increasing as the total number of steps taken increases.


In [1]:
%matplotlib inline

In [2]:
import numpy as np
from numpy.random import choice
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde
import itertools

Here we define the Walker class.


In [3]:
class Walker():
    def __init__(self, origin=0, nsteps=1000):
        self._origin = 0
        self._nsteps = nsteps
        self._location = self._origin
        self._choice = np.array([-1,1])
        
    
    @property
    def origin(self): return self._origin
    

    @property
    def nsteps(self): return self._nsteps
    
    @property
    def distance_from_origin(self):
        return self._location - self._origin
    
    
    def walk(self):
        steps = choice(self._choice, self._nsteps)
        self._location = self._origin + np.sum(steps)
        return self
    
    
    def walk2(self):
        d = self._origin
        for i in range(self._nsteps):
            d += choice([-1,1], 1)
        return d

This is the actual simulation where we set all the parameters and simulate. For each walker, we collect the distance from origin. We use this information later to plot a histogram of the distances where each walker is found at the end of the walk.


In [4]:
nwalkers = [10000]
nsteps = [100, 1000, 10000, 100000]
origin = 0

distance_from_origin_of_walkers = {}
for inwalkers in nwalkers:
    distance_from_origin_of_walkers[inwalkers] = {}
    
    for insteps in nsteps:
        distance_from_origin_of_walkers[inwalkers][insteps] = {}

        distance_travelled = []    
        for iwalker in range(inwalkers):
            walker = Walker(origin=origin, nsteps=insteps)
            distance_travelled.append(walker.walk().distance_from_origin)
        
        distance_travelled = np.array(distance_travelled).flatten()
        distance_from_origin_of_walkers[inwalkers][insteps]['distance_travelled'] = distance_travelled

Here we make a histogram of the distances of all the walkers, and fit a kernel density estimator to the histogram. As expected, we find that the shape is Gaussian.


In [8]:
colors = itertools.cycle(['blue', 'green', 'red', 'cyan'])
for inwalkers in nwalkers:
    for insteps in nsteps:
        color = colors.next()
        distance_travelled = distance_from_origin_of_walkers[inwalkers][insteps]['distance_travelled']
        # plt.hist(distance_travelled, normed=True, color=color)
        x_grid = np.linspace(-400,400,1001)
        kernel = gaussian_kde(distance_travelled, bw_method=0.3)
        plt.plot(x_grid, kernel.evaluate(x_grid), color=color, label='nsteps: %i' % (insteps))

plt.xlabel('Distance')
plt.ylabel('Probability')
plt.legend()
plt.axis([-400, 400, 0, 0.04])


Out[8]:
[-400, 400, 0, 0.04]