expose floor variable and new test file
This commit is contained in:
@@ -4,6 +4,7 @@ CREATE OR REPLACE FUNCTION
|
|||||||
CDB_MaxP(
|
CDB_MaxP(
|
||||||
subquery TEXT,
|
subquery TEXT,
|
||||||
colnames TEXT[],
|
colnames TEXT[],
|
||||||
|
floor_variable TEXT,
|
||||||
min_size int default 1,
|
min_size int default 1,
|
||||||
initial int default 99,
|
initial int default 99,
|
||||||
geom_col TEXT DEFAULT 'the_geom',
|
geom_col TEXT DEFAULT 'the_geom',
|
||||||
@@ -12,5 +13,5 @@ RETURNS TABLE (region_class text, p_val numeric, rowid bigint)
|
|||||||
AS $$
|
AS $$
|
||||||
from crankshaft.clustering import MaxP
|
from crankshaft.clustering import MaxP
|
||||||
maxp = MaxP()
|
maxp = MaxP()
|
||||||
return maxp.maxp(subquery, colnames, floor=min_size)
|
return maxp.maxp(subquery, colnames, floor_variable, floor=min_size)
|
||||||
$$ LANGUAGE plpythonu;
|
$$ LANGUAGE plpythonu;
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ class AnalysisDataProvider:
|
|||||||
plpy.error('Analysis failed: %s' % err)
|
plpy.error('Analysis failed: %s' % err)
|
||||||
|
|
||||||
def get_maxp(self, params):
|
def get_maxp(self, params):
|
||||||
"""fetch data for spatial markov"""
|
"""fetch data for max-p"""
|
||||||
try:
|
try:
|
||||||
query = pu.construct_neighbor_query('queen', params)
|
query = pu.construct_neighbor_query('queen', params)
|
||||||
data = plpy.execute(query)
|
data = plpy.execute(query)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
import pysal as ps
|
import pysal as ps
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import random
|
import random
|
||||||
|
import time
|
||||||
|
|
||||||
import crankshaft.pysal_utils as pu
|
import crankshaft.pysal_utils as pu
|
||||||
from crankshaft.analysis_data_provider import AnalysisDataProvider
|
from crankshaft.analysis_data_provider import AnalysisDataProvider
|
||||||
@@ -17,16 +18,20 @@ class MaxP:
|
|||||||
else:
|
else:
|
||||||
self.data_provider = AnalysisDataProvider()
|
self.data_provider = AnalysisDataProvider()
|
||||||
|
|
||||||
def maxp(self, subquery, colnames, floor=1,
|
def maxp(self, subquery, colnames, floor_variable,
|
||||||
geom_col='the_geom', id_col='cartodb_id'):
|
floor=1,
|
||||||
|
geom_col='the_geom', id_col='cartodb_id'):
|
||||||
"""
|
"""
|
||||||
Inputs:
|
Inputs:
|
||||||
@param subquery (text): subquery to expose the data need for the
|
@param subquery (text): subquery to expose the data need for the
|
||||||
analysis. This query needs to expose all
|
analysis. This query needs to expose all
|
||||||
of the columns in `colnames`, `id_col`, and
|
of the columns in `colnames`, `id_col`, and
|
||||||
`geom_col`
|
`geom_col`
|
||||||
@param colnames (list): list of column names (as strings)
|
@param colnames (list): list of column names (as strings). This is
|
||||||
@param floor (float): ...
|
used to calculate intra-regional homogeneity.
|
||||||
|
@param floor_variable (text): name of column variable for the floor
|
||||||
|
@param floor (int): the minimum bound for a variable that has to be
|
||||||
|
obtained in each region,
|
||||||
@param geom_col (text): geometry column used for calculating the
|
@param geom_col (text): geometry column used for calculating the
|
||||||
spatial neighborhood
|
spatial neighborhood
|
||||||
@param id_col (text): id column used for keeping the identity of
|
@param id_col (text): id column used for keeping the identity of
|
||||||
@@ -39,23 +44,29 @@ class MaxP:
|
|||||||
params = {'subquery': subquery,
|
params = {'subquery': subquery,
|
||||||
'colnames': colnames,
|
'colnames': colnames,
|
||||||
'id_col': id_col,
|
'id_col': id_col,
|
||||||
'geom_col': geom_col}
|
'geom_col': geom_col,
|
||||||
|
'floor_variable':floor_variable,
|
||||||
|
}
|
||||||
|
|
||||||
resp = self.data_provider.get_maxp(params)
|
resp = self.data_provider.get_maxp(params)
|
||||||
|
|
||||||
attr_vals = pu.get_attributes(resp, len(colnames))
|
attr_vals = pu.get_attributes(resp, len(colnames))
|
||||||
|
floor_column_id = colnames.index(floor_variable)
|
||||||
|
# print "floor_column_id: ", floor_column_id
|
||||||
weight = pu.get_weight(resp, w_type='queen')
|
weight = pu.get_weight(resp, w_type='queen')
|
||||||
|
start_time = time.time()
|
||||||
r = ps.Maxp(weight, attr_vals,
|
r = ps.Maxp(weight, attr_vals,
|
||||||
floor=floor,
|
floor=floor,
|
||||||
floor_variable=np.ones((weight.n, 1)))
|
floor_variable= attr_vals.transpose()[floor_column_id],
|
||||||
|
initial=10)
|
||||||
|
# print r.regions
|
||||||
cluster_classes = get_cluster_classes(weight.id_order, r.regions)
|
cluster_classes = get_cluster_classes(weight.id_order, r.regions)
|
||||||
r.inference()
|
r.inference()
|
||||||
|
# print "elapsed time: ", time.time() - start_time
|
||||||
return zip(cluster_classes, [r.pvalue] * len(weight.id_order),
|
return zip(cluster_classes, [r.pvalue] * len(weight.id_order),
|
||||||
weight.id_order)
|
weight.id_order)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_cluster_classes(ids, clusters):
|
def get_cluster_classes(ids, clusters):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|||||||
+1
File diff suppressed because one or more lines are too long
@@ -0,0 +1,62 @@
|
|||||||
|
import unittest
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
# from mock_plpy import MockPlPy
|
||||||
|
# plpy = MockPlPy()
|
||||||
|
#
|
||||||
|
# import sys
|
||||||
|
# sys.modules['plpy'] = plpy
|
||||||
|
from helper import fixture_file
|
||||||
|
from crankshaft.clustering import MaxP
|
||||||
|
from crankshaft.analysis_data_provider import AnalysisDataProvider
|
||||||
|
import crankshaft.clustering as cc
|
||||||
|
|
||||||
|
from crankshaft import random_seeds
|
||||||
|
import json
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
|
||||||
|
class FakeDataProvider(AnalysisDataProvider):
|
||||||
|
def __init__(self, fixturedata):
|
||||||
|
self.your_maxp_data = fixturedata
|
||||||
|
|
||||||
|
def get_maxp(self, params):
|
||||||
|
"""
|
||||||
|
Replace this function name with the one used in your algorithm,
|
||||||
|
and make sure to use the same function signature that is written
|
||||||
|
for this algo in analysis_data_provider.py
|
||||||
|
"""
|
||||||
|
return self.your_maxp_data
|
||||||
|
|
||||||
|
class MaxPTest(unittest.TestCase):
|
||||||
|
"""Testing class for max-p regionalization"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.neighbor_data = json.loads(
|
||||||
|
open(fixture_file('maxp.json')).read())
|
||||||
|
self.neighbor_data = self.neighbor_data['rows']
|
||||||
|
self.params = {"subquery": "select * from fake_table",
|
||||||
|
"colnames": ['population','median_hh_income'],
|
||||||
|
"floor_variable": 'population',
|
||||||
|
"floor": 260000}
|
||||||
|
|
||||||
|
def test_maxp(self):
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
data = [{'id': d['id'],
|
||||||
|
'attr1': d['attr1'],
|
||||||
|
'attr2':d['attr2'],
|
||||||
|
'neighbors': d['neighbors']} for d in self.neighbor_data]
|
||||||
|
|
||||||
|
random_seeds.set_random_seeds(1234)
|
||||||
|
maxp = MaxP(FakeDataProvider(data))
|
||||||
|
regions = maxp.maxp('select * from research_nothing',['population','median_hh_income'],floor_variable='population',floor=260000)
|
||||||
|
region_labels = [a[0] for a in regions]
|
||||||
|
data_regionalized = zip(data,region_labels)
|
||||||
|
for i in set(region_labels):
|
||||||
|
sum_pop = 0
|
||||||
|
for n in data_regionalized:
|
||||||
|
if n[1] == i:
|
||||||
|
sum_pop += n[0]['attr1']
|
||||||
|
self.assertGreaterEqual(sum_pop, 260000)
|
||||||
Reference in New Issue
Block a user