adds maxp algorithm

This commit is contained in:
Andy Eschbacher
2017-01-11 15:48:02 -05:00
parent a9bef6ba1d
commit ae767fc903
4 changed files with 99 additions and 0 deletions

16
src/pg/sql/22_maxp.sql Normal file
View File

@@ -0,0 +1,16 @@
-- max-p regionalization
CREATE OR REPLACE FUNCTION
CDB_MaxP(
subquery TEXT,
colnames TEXT[],
min_size int default 1,
initial int default 99,
geom_col TEXT DEFAULT 'the_geom',
id_col TEXT DEFAULT 'cartodb_id')
RETURNS TABLE (region_class text, p_val numeric, rowid bigint)
AS $$
from crankshaft.clustering import MaxP
maxp = MaxP()
return maxp.maxp(subquery, colnames, floor=min_size)
$$ LANGUAGE plpythonu;

View File

@@ -65,3 +65,17 @@ class AnalysisDataProvider:
return data
except plpy.SPIError, err:
plpy.error('Analysis failed: %s' % err)
def get_maxp(self, params):
"""fetch data for spatial markov"""
try:
query = pu.construct_neighbor_query('queen', params)
data = plpy.execute(query)
if len(data) == 0:
# TODO: replace with better message in PR#157
plpy.error('No non-null valued rows')
return data
except plpy.SPIError, err:
plpy.error('Analysis failed: %s' % err)

View File

@@ -2,3 +2,4 @@
from moran import *
from kmeans import *
from getis import *
from maxp import *

View File

@@ -0,0 +1,68 @@
"""
max-p clustering
"""
import pysal as ps
import numpy as np
import random
import crankshaft.pysal_utils as pu
from crankshaft.analysis_data_provider import AnalysisDataProvider
class MaxP:
def __init__(self, data_provider=None):
if data_provider:
self.data_provider = data_provider
else:
self.data_provider = AnalysisDataProvider()
def maxp(self, subquery, colnames, floor=1,
geom_col='the_geom', id_col='cartodb_id'):
"""
Inputs:
@param subquery (text): subquery to expose the data need for the
analysis. This query needs to expose all
of the columns in `colnames`, `id_col`, and
`geom_col`
@param colnames (list): list of column names (as strings)
@param floor (float): ...
@param geom_col (text): geometry column used for calculating the
spatial neighborhood
@param id_col (text): id column used for keeping the identity of
the data
Outputs: a list of tuples with the following columns:
classification_id: group that the geometry belongs to
rowid: identifier from id_col
"""
params = {'subquery': subquery,
'colnames': colnames,
'id_col': id_col,
'geom_col': geom_col}
resp = self.data_provider.get_maxp(params)
attr_vals = pu.get_attributes(resp, len(colnames))
weight = pu.get_weight(resp, w_type='queen')
r = ps.Maxp(weight, attr_vals,
floor=floor,
floor_variable=np.ones((weight.n, 1)))
cluster_classes = get_cluster_classes(weight.id_order, r.regions)
r.inference()
return zip(cluster_classes, [r.pvalue] * len(weight.id_order),
weight.id_order)
def get_cluster_classes(ids, clusters):
"""
"""
cluster_classes = []
for i in ids:
for r_id, r in enumerate(clusters):
if i in r:
cluster_classes.append(r_id)
return cluster_classes