giddy.markov.LISA_Markov

class giddy.markov.LISA_Markov(y, w, permutations=0, significance_level=0.05, geoda_quads=False)[source]

Markov for Local Indicators of Spatial Association

Parameters
yarray

(n, t), n cross-sectional units observed over t time periods.

wW

spatial weights object.

permutationsint, optional

number of permutations used to determine LISA significance (the default is 0).

significance_levelfloat, optional

significance level (two-sided) for filtering significant LISA endpoints in a transition (the default is 0.05).

geoda_quadsbool

If True use GeoDa scheme: HH=1, LL=2, LH=3, HL=4. If False use PySAL Scheme: HH=1, LH=2, LL=3, HL=4. (the default is False).

Examples

>>> import libpysal
>>> import numpy as np
>>> from giddy.markov import LISA_Markov
>>> np.set_printoptions(suppress=True) #prevent scientific format
>>> f = libpysal.io.open(libpysal.examples.get_path("usjoin.csv"))
>>> years = list(range(1929, 2010))
>>> pci = np.array([f.by_col[str(y)] for y in years]).transpose()
>>> w = libpysal.io.open(libpysal.examples.get_path("states48.gal")).read()
>>> lm = LISA_Markov(pci,w)
>>> lm.classes
array([1, 2, 3, 4])
>>> lm.steady_state
array([0.28561505, 0.14190226, 0.40493672, 0.16754598])
>>> lm.transitions
array([[1087.,   44.,    4.,   34.],
       [  41.,  470.,   36.,    1.],
       [   5.,   34., 1422.,   39.],
       [  30.,    1.,   40.,  552.]])
>>> lm.p
array([[0.92985458, 0.03763901, 0.00342173, 0.02908469],
       [0.07481752, 0.85766423, 0.06569343, 0.00182482],
       [0.00333333, 0.02266667, 0.948     , 0.026     ],
       [0.04815409, 0.00160514, 0.06420546, 0.88603531]])
>>> lm.move_types[0,:3]
array([11, 11, 11])
>>> lm.move_types[0,-3:]
array([11, 11, 11])

Now consider only moves with one, or both, of the LISA end points being significant

>>> np.random.seed(10)
>>> lm_random = LISA_Markov(pci, w, permutations=99)
>>> lm_random.significant_moves[0, :3]
array([11, 11, 11])
>>> lm_random.significant_moves[0,-3:]
array([59, 43, 27])

Any value less than 49 indicates at least one of the LISA end points was significant. So for example, the first spatial unit experienced a transition of type 11 (LL, LL) during the first three and last tree intervals (according to lm.move_types), however, the last three of these transitions involved insignificant LISAS in both the start and ending year of each transition.

Test whether the moves of y are independent of the moves of wy

>>> "Chi2: %8.3f, p: %5.2f, dof: %d" % lm.chi_2
'Chi2: 1058.208, p:  0.00, dof: 9'

Actual transitions of LISAs

>>> lm.transitions
array([[1087.,   44.,    4.,   34.],
       [  41.,  470.,   36.,    1.],
       [   5.,   34., 1422.,   39.],
       [  30.,    1.,   40.,  552.]])

Expected transitions of LISAs under the null y and wy are moving independently of one another

>>> lm.expected_t
array([[1123.2809778 ,   11.53773565,    0.34752216,   33.83376439],
       [   3.50272664,  528.47388155,   15.917888  ,    0.10550381],
       [   0.15387808,   23.21635562, 1466.90710117,    9.72266513],
       [   9.60775143,    0.09868563,    6.23537392,  607.05818902]])

If the LISA classes are to be defined according to GeoDa, the geoda_quad option has to be set to true

>>> lm.q[0:5,0]
array([3, 2, 3, 1, 4])
>>> lm = LISA_Markov(pci,w, geoda_quads=True)
>>> lm.q[0:5,0]
array([2, 3, 2, 1, 4])
Attributes
chi_2tuple

(3 elements) (chi square test statistic, p-value, degrees of freedom) for test that dynamics of y are independent of dynamics of wy.

classesarray

(4, 1) 1=HH, 2=LH, 3=LL, 4=HL (own, lag) 1=HH, 2=LL, 3=LH, 4=HL (own, lag) (if geoda_quads=True)

expected_tarray

(4, 4), expected number of transitions under the null that dynamics of y are independent of dynamics of wy.

move_typesmatrix

(n, t-1), integer values indicating which type of LISA transition occurred (q1 is quadrant in period 1, q2 is quadrant in period 2).

Move Types

q1

q2

move_type

1

1

1

1

2

2

1

3

3

1

4

4

2

1

5

2

2

6

2

3

7

2

4

8

3

1

9

3

2

10

3

3

11

3

4

12

4

1

13

4

2

14

4

3

15

4

4

16

parray

(k, k), transition probability matrix.

p_valuesmatrix

(n, t), LISA p-values for each end point (if permutations > 0).

significant_movesmatrix

(n, t-1), integer values indicating the type and significance of a LISA transition. st = 1 if significant in period t, else st=0 (if permutations > 0).

Significant Moves1

(s1,s2)

move_type

(1,1)

[1, 16]

(1,0)

[17, 32]

(0,1)

[33, 48]

(0,0)

[49, 64]

Significant Moves2

q1

q2

s1

s2

move_type

1

1

1

1

1

1

2

1

1

2

1

3

1

1

3

1

4

1

1

4

2

1

1

1

5

2

2

1

1

6

2

3

1

1

7

2

4

1

1

8

3

1

1

1

9

3

2

1

1

10

3

3

1

1

11

3

4

1

1

12

4

1

1

1

13

4

2

1

1

14

4

3

1

1

15

4

4

1

1

16

1

1

1

0

17

1

2

1

0

18

.

.

.

.

.

.

.

.

.

.

4

3

1

0

31

4

4

1

0

32

1

1

0

1

33

1

2

0

1

34

.

.

.

.

.

.

.

.

.

.

4

3

0

1

47

4

4

0

1

48

1

1

0

0

49

1

2

0

0

50

.

.

.

.

.

.

.

.

.

.

4

3

0

0

63

4

4

0

0

64

steady_statearray

(k, ), ergodic distribution.

transitionsarray

(4, 4), count of transitions between each state i and j.

spilloverarray

Detect spillover locations for diffusion in LISA Markov.

__init__(self, y, w, permutations=0, significance_level=0.05, geoda_quads=False)[source]

Initialize self. See help(type(self)) for accurate signature.

Methods

__init__(self, y, w[, permutations, …])

Initialize self.

spillover(self[, quadrant, neighbors_on])

Detect spillover locations for diffusion in LISA Markov.

Attributes

fmpt

sojourn_time

steady_state

spillover(self, quadrant=1, neighbors_on=False)[source]

Detect spillover locations for diffusion in LISA Markov.

Parameters
quadrantint

which quadrant in the scatterplot should form the core of a cluster.

neighbors_onbinary

If false, then only the 1st order neighbors of a core location are included in the cluster. If true, neighbors of cluster core 1st order neighbors are included in the cluster.

Returns
resultsdictionary

two keys - values pairs: ‘components’ - array (n, t) values are integer ids (starting at 1) indicating which component/cluster observation i in period t belonged to. ‘spillover’ - array (n, t-1) binary values indicating if the location was a spill-over location that became a new member of a previously existing cluster.

Examples

>>> import libpysal
>>> from giddy.markov import LISA_Markov
>>> f = libpysal.io.open(libpysal.examples.get_path("usjoin.csv"))
>>> years = list(range(1929, 2010))
>>> pci = np.array([f.by_col[str(y)] for y in years]).transpose()
>>> w = libpysal.io.open(libpysal.examples.get_path("states48.gal")).read()
>>> np.random.seed(10)
>>> lm_random = LISA_Markov(pci, w, permutations=99)
>>> r = lm_random.spillover()
>>> (r['components'][:, 12] > 0).sum()
17
>>> (r['components'][:, 13]>0).sum()
23
>>> (r['spill_over'][:,12]>0).sum()
6

Including neighbors of core neighbors >>> rn = lm_random.spillover(neighbors_on=True) >>> (rn[‘components’][:, 12] > 0).sum() 26 >>> (rn[“components”][:, 13] > 0).sum() 34 >>> (rn[“spill_over”][:, 12] > 0).sum() 8