Source code for treasmo.moran_vec

from libpysal.weights.spatial_lag import lag_spatial as slag
import numpy as np
import random
from sklearn import preprocessing
import psutil

PERMUTATIONS = 0

def get_memory():
    # Get the virtual memory usage details
    memory = psutil.virtual_memory()
    # Calculate the free memory in MB
    free_memory_mb = (memory.available / 1024.0) / 1024.0
    return free_memory_mb

'''
def get_memory():
    with open('/proc/meminfo', 'r') as mem:
        free_memory = 0
        for i in mem:
            sline = i.split()
            if str(sline[0]) in ('MemFree:', 'Buffers:', 'Cached:'):
                free_memory += int(sline[1])
    return free_memory / 1024
'''

[docs]class Moran(object): """ Moran's I Global Autocorrelation Statistic Adapted from https://github.com/pysal/esda Parameters ------------ n : int number of observations w : W spatial weights instance transformation : string weights transformation, default is row-standardized "r". Other options include "B": binary, "D": doubly-standardized, "U": untransformed (general weights), "V": variance-stabilizing. permutations : int number of random permutations for calculation of pseudo-p_values Attributes ------------ w : W original w object permutations : int number of permutations I : array value of Moran's I sim : array (if permutations>0) vector of I values for permuted samples p_sim : array (if permutations>0) p-value based on permutations (one-tailed) null: spatial randomness alternative: the observed I is extreme if it is either extremely greater or extremely lower than the values obtained based on permutations Notes ----- Technical details and derivations can be found in :cite:`cliff81`. """ def __init__( self, n, w, transformation="r", permutations=PERMUTATIONS ): #y = np.asarray(y).flatten() #self.y = y w.transform = transformation self.w = w self.permutations = permutations self.n = n self.__moments()
[docs] def calc_i(self, X, seed=1, max_RAM=16): """ Function to calculate Moran's I of all features Parameters ------------ X: n x p array log-transformed feature matrix seed: int random seed to make the results reproducible max_RAM: int, float maximum limitation of memory (Gb) Returns --------- the fitted estimator. """ random.seed(seed) np.random.seed(seed) self.Z = preprocessing.StandardScaler().fit_transform(X) #self.Z = np.asarray(self.Z).flatten() self.Z[self.Z>10] = 10.0 self.Z[self.Z<-10] = -10.0 self.I = self.__calc(self.Z, max_RAM) if self.permutations: permutations = self.permutations sim = [ self.__calc(np.random.permutation(self.Z), max_RAM) for i in range(permutations) ] self.sim = sim = np.array(sim) above = self.sim >= np.repeat(self.I[np.newaxis,:],self.permutations,axis=0) #self.association_ larger = above.sum(axis=0) extreme = np.minimum(self.permutations - larger, larger) self.p_sim = (extreme + 1.0) / (self.permutations + 1.0)
#above = sim >= self.I #larger = above.sum() #if (self.permutations - larger) < larger: # larger = self.permutations - larger #self.p_sim = (larger + 1.0) / (permutations + 1.0) def __moments(self): n = self.n n2 = n * n s1 = self.w.s1 s0 = self.w.s0 s2 = self.w.s2 s02 = s0 * s0 def __calc(self, Z, max_RAM): ''' memory taken: 0.000008 * (3*n*p + 3*p) ''' free_memory = min(get_memory(), max_RAM*1024) if (free_memory*0.8) > (0.000008 * (3 * Z.shape[1] * Z.shape[0] + 3*Z.shape[1])): z2ss = np.square(Z).sum(axis=0) zl = slag(self.w, Z) inum = (Z * zl).sum(axis=0) return self.n / self.w.s0 * (inum / z2ss) else: out = np.zeros(Z.shape[1]) nt = (0.000008 * (3 * Z.shape[1] * Z.shape[0] + 3*Z.shape[1])) / (free_memory*0.8) + 1 nt = int(nt) nf = Z.shape[1] // nt for i in range(nt-1): z2ss = np.square(self.Z[:,(nf*i):(nf*(i+1))]).sum(axis=0) zl = slag(self.w, Z[:,(nf*i):(nf*(i+1))]) inum = (Z[:,(nf*i):(nf*(i+1))] * zl).sum(axis=0) out[(nf*i):(nf*(i+1))] = self.n / self.w.s0 * (inum / z2ss) z2ss = np.square(self.Z[:,(nf*(nt-1)):]).sum(axis=0) zl = slag(self.w, Z[:,(nf*(nt-1)):]) inum = (Z[:,(nf*(nt-1)):] * zl).sum(axis=0) out[(nf*(nt-1)):] = self.n / self.w.s0 * (inum / z2ss) return out
#z2ss = np.square(self.Z).sum(axis=0) #zl = slag(self.w, Z) #inum = (Z * zl).sum(axis=0)