This page was generated from notebooks/MobilityMeasures.ipynb. Interactive online version: Binder badge

Measures of Income Mobility

Author: Wei Kang weikang9009@gmail.com, Serge Rey sjsrey@gmail.com

Income mobility could be viewed as a reranking pheonomenon where regions switch income positions while it could also be considered to be happening as long as regions move away from the previous income levels. The former is named absolute mobility and the latter relative mobility.

This notebook introduces how to estimate income mobility measures from longitudinal income data using methods in giddy. Currently, five summary mobility estimators are implemented in giddy.mobility. All of them are Markov-based, meaning that they are closely related to the discrete Markov Chains methods introduced in Markov Based Methods notebook. More specifically, each of them is derived from a transition probability matrix \(P\). Whether the final estimate is absolute or reletive mobility depends on how the original continuous income data are discretized.

The five Markov-based summary measures of mobility (Formby et al., 2004) are listed below:

Num

Measures

Symbol

1

\(M_P(P) = \frac{m-\sum_{i=1}^m p_{ii}}{m-1}\)

P

2

\(M_D(P) = 1- \left|det(P)\right|\)

D

3

\(M_{L2}(P) = 1-\left|\lambda_2 \right|\)

L2

4

\(M_{B1}(P) = \frac{m-m \sum_{i=1}^m \pi_i P_{ii}}{m-1}\)

B1

5

\(M_{B2}(P) = \frac{1}{m-1} \sum_{i=1}^m \sum_{j=1}^m \pi_i P_{ij} \left|i-j \right|\)

B2

\(\pi\) is the inital income distribution. For any transition probability matrix with a quasi-maximal diagonal, all of these mobility measures take values on \([0,1]\). \(0\) means immobility and \(1\) perfect mobility. If the transition probability matrix takes the form of the identity matrix, every region is stuck in its current state implying complete immobility. On the contrary, when each row of \(P\) is identical, current state is irrelevant to the probability of moving away to any class. Thus, the transition matrix with identical rows is considered perfect mobile. The larger the mobility estimate, the more mobile the regional income system is. However, it should be noted that these measures try to reveal mobility pattern from different aspects and are thus not comparable to each other. Actually the mean and variance of these measures are different.

We implemented all the above five summary mobility measures in a single method markov_mobility. A parameter measure could be specified to select which measure to calculate. By default, the mobility measure ‘P’ will be estimated.

def markov_mobility(p, measure="P", ini=None)
[1]:
import warnings

with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    # ignore NumbaDeprecationWarning: gh-pysal/libpysal#560
    from giddy import markov, mobility

?mobility.markov_mobility
Signature: mobility.markov_mobility(p, measure='P', ini=None)
Docstring:
Markov-based mobility index.

Parameters
----------
p       : array
          (k, k), Markov transition probability matrix.
measure : string
          If measure= "P",
          :math:`M_{P} = \frac{m-\sum_{i=1}^m P_{ii}}{m-1}`;
          if measure = "D",
          :math:`M_{D} = 1 - |\det(P)|`,
          where :math:`\det(P)` is the determinant of :math:`P`;
          if measure = "L2",
          :math:`M_{L2} = 1  - |\lambda_2|`,
          where :math:`\lambda_2` is the second largest eigenvalue of
          :math:`P`;
          if measure = "B1",
          :math:`M_{B1} = \frac{m-m \sum_{i=1}^m \pi_i P_{ii}}{m-1}`,
          where :math:`\pi` is the initial income distribution;
          if measure == "B2",
          :math:`M_{B2} = \frac{1}{m-1} \sum_{i=1}^m \sum_{
          j=1}^m \pi_i P_{ij} |i-j|`,
          where :math:`\pi` is the initial income distribution.
ini     : array
          (k,), initial distribution. Need to be specified if
          measure = "B1" or "B2". If not,
          the initial distribution would be treated as a uniform
          distribution.

Returns
-------
mobi    : float
          Mobility value.

Notes
-----
The mobility indices are based on :cite:`Formby:2004fk`.

Examples
--------
>>> import numpy as np
>>> import libpysal
>>> import mapclassify as mc
>>> from giddy.markov import Markov
>>> from giddy.mobility import markov_mobility
>>> f = libpysal.io.open(libpysal.examples.get_path("usjoin.csv"))
>>> pci = np.array([f.by_col[str(y)] for y in range(1929,2010)])
>>> q5 = np.array([mc.Quantiles(y).yb for y in pci]).transpose()
>>> m = Markov(q5)
The Markov Chain is irreducible and is composed by:
1 Recurrent class (indices):
[0 1 2 3 4]
0 Transient classes.
The Markov Chain has 0 absorbing states.
>>> m.p
array([[0.91011236, 0.0886392 , 0.00124844, 0.        , 0.        ],
       [0.09972299, 0.78531856, 0.11080332, 0.00415512, 0.        ],
       [0.        , 0.10125   , 0.78875   , 0.1075    , 0.0025    ],
       [0.        , 0.00417827, 0.11977716, 0.79805014, 0.07799443],
       [0.        , 0.        , 0.00125156, 0.07133917, 0.92740926]])

(1) Estimate Shorrock1 mobility index:

>>> mobi_1 = markov_mobility(m.p, measure="P")
>>> print("{:.5f}".format(mobi_1))
0.19759

(2) Estimate Shorrock2 mobility index:

>>> mobi_2 = markov_mobility(m.p, measure="D")
>>> print("{:.5f}".format(mobi_2))
0.60685

(3) Estimate Sommers and Conlisk mobility index:

>>> mobi_3 = markov_mobility(m.p, measure="L2")
>>> print("{:.5f}".format(mobi_3))
0.03978

(4) Estimate Bartholomew1 mobility index (note that the initial
distribution should be given):

>>> ini = np.array([0.1,0.2,0.2,0.4,0.1])
>>> mobi_4 = markov_mobility(m.p, measure = "B1", ini=ini)
>>> print("{:.5f}".format(mobi_4))
0.22777

(5) Estimate Bartholomew2 mobility index (note that the initial
distribution should be given):

>>> ini = np.array([0.1,0.2,0.2,0.4,0.1])
>>> mobi_5 = markov_mobility(m.p, measure = "B2", ini=ini)
>>> print("{:.5f}".format(mobi_5))
0.04637
File:      ~/giddy/giddy/mobility.py
Type:      function

US income mobility example

Similar to Markov Based Methods notebook, we will demonstrate the usage of the mobility methods by an application to data on per capita incomes observed annually from 1929 to 2009 for the lower 48 US states.

[2]:
with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    # ignore NumbaDeprecationWarning: gh-pysal/libpysal#560
    import libpysal

import numpy as np
import mapclassify as mc
[3]:
income_path = libpysal.examples.get_path("usjoin.csv")
f = libpysal.io.open(income_path)
# each column represents an state's income time series 1929-2010
pci = np.array([f.by_col[str(y)] for y in range(1929, 2010)])
# each row represents an state's income time series 1929-2010
q5 = np.array([mc.Quantiles(y).yb for y in pci]).transpose()
m = markov.Markov(q5)
m.p
The Markov Chain is irreducible and is composed by:
1 Recurrent class (indices):
[0 1 2 3 4]
0 Transient classes.
The Markov Chain has 0 absorbing states.
[3]:
array([[0.91011236, 0.0886392 , 0.00124844, 0.        , 0.        ],
       [0.09972299, 0.78531856, 0.11080332, 0.00415512, 0.        ],
       [0.        , 0.10125   , 0.78875   , 0.1075    , 0.0025    ],
       [0.        , 0.00417827, 0.11977716, 0.79805014, 0.07799443],
       [0.        , 0.        , 0.00125156, 0.07133917, 0.92740926]])

After acquiring the estimate of transition probability matrix, we could call the method markov_mobility to estimate any of the five Markov-based summary mobility indice.

1. Shorrock1’s mobility measure

\begin{equation} M_{P} = \frac{m-\sum_{i=1}^m P_{ii}}{m-1} \end{equation}

measure = "P"
[4]:
mobility.markov_mobility(m.p, measure="P")
[4]:
0.19758992000997844

2. Shorroks2’s mobility measure

\begin{equation} M_{D} = 1 - |\det(P)| \end{equation}

measure = "D"
[5]:
mobility.markov_mobility(m.p, measure="D")
[5]:
0.606848546236956

3. Sommers and Conlisk’s mobility measure

\begin{equation} M_{L2} = 1 - |\lambda_2| \end{equation}

measure = "L2"
[6]:
mobility.markov_mobility(m.p, measure="L2")
[6]:
0.03978200230815976

4. Bartholomew1’s mobility measure

\begin{equation} M_{B1} = \frac{m-m \sum_{i=1}^m \pi_i P_{ii}}{m-1} \end{equation}

\(\pi\): the inital income distribution

measure = "B1"
[7]:
pi = np.array([0.1, 0.2, 0.2, 0.4, 0.1])
mobility.markov_mobility(m.p, measure="B1", ini=pi)
[7]:
0.2277675878319787

5. Bartholomew2’s mobility measure

\begin{equation} M_{B2} = \frac{1}{m-1} \sum_{i=1}^m \sum_{j=1}^m \pi_i P_{ij} |i-j| \end{equation}

\(\pi\): the inital income distribution

measure = "B1"
[8]:
pi = np.array([0.1, 0.2, 0.2, 0.4, 0.1])
mobility.markov_mobility(m.p, measure="B2", ini=pi)
[8]:
0.04636660119478926

Next steps

  • Markov-based partial mobility measures

  • Other mobility measures:

    • Inequality reduction mobility measures (Trede, 1999)

  • Statistical inference for mobility measures

References