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, 59, 43])
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).
¶ 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).
¶ (s1,s2)
move_type
(1,1)
[1, 16]
(1,0)
[17, 32]
(0,1)
[33, 48]
(0,0)
[49, 64]
¶ 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.
spillover
arrayDetect spillover locations for diffusion in LISA Markov.
Methods
__init__
(y, w[, permutations, ...])spillover
([quadrant, neighbors_on])Detect spillover locations for diffusion in LISA Markov.
Attributes
mfpt
sojourn_time
steady_state
- spillover(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