expose floor variable and new test file
This commit is contained in:
@@ -4,6 +4,7 @@ CREATE OR REPLACE FUNCTION
|
||||
CDB_MaxP(
|
||||
subquery TEXT,
|
||||
colnames TEXT[],
|
||||
floor_variable TEXT,
|
||||
min_size int default 1,
|
||||
initial int default 99,
|
||||
geom_col TEXT DEFAULT 'the_geom',
|
||||
@@ -12,5 +13,5 @@ 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)
|
||||
return maxp.maxp(subquery, colnames, floor_variable, floor=min_size)
|
||||
$$ LANGUAGE plpythonu;
|
||||
|
||||
@@ -67,7 +67,7 @@ class AnalysisDataProvider:
|
||||
plpy.error('Analysis failed: %s' % err)
|
||||
|
||||
def get_maxp(self, params):
|
||||
"""fetch data for spatial markov"""
|
||||
"""fetch data for max-p"""
|
||||
try:
|
||||
query = pu.construct_neighbor_query('queen', params)
|
||||
data = plpy.execute(query)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import pysal as ps
|
||||
import numpy as np
|
||||
import random
|
||||
import time
|
||||
|
||||
import crankshaft.pysal_utils as pu
|
||||
from crankshaft.analysis_data_provider import AnalysisDataProvider
|
||||
@@ -17,16 +18,20 @@ class MaxP:
|
||||
else:
|
||||
self.data_provider = AnalysisDataProvider()
|
||||
|
||||
def maxp(self, subquery, colnames, floor=1,
|
||||
geom_col='the_geom', id_col='cartodb_id'):
|
||||
def maxp(self, subquery, colnames, floor_variable,
|
||||
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 colnames (list): list of column names (as strings). This is
|
||||
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
|
||||
spatial neighborhood
|
||||
@param id_col (text): id column used for keeping the identity of
|
||||
@@ -39,23 +44,29 @@ class MaxP:
|
||||
params = {'subquery': subquery,
|
||||
'colnames': colnames,
|
||||
'id_col': id_col,
|
||||
'geom_col': geom_col}
|
||||
'geom_col': geom_col,
|
||||
'floor_variable':floor_variable,
|
||||
}
|
||||
|
||||
resp = self.data_provider.get_maxp(params)
|
||||
|
||||
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')
|
||||
start_time = time.time()
|
||||
r = ps.Maxp(weight, attr_vals,
|
||||
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)
|
||||
r.inference()
|
||||
# print "elapsed time: ", time.time() - start_time
|
||||
return zip(cluster_classes, [r.pvalue] * len(weight.id_order),
|
||||
weight.id_order)
|
||||
|
||||
|
||||
|
||||
def get_cluster_classes(ids, clusters):
|
||||
"""
|
||||
|
||||
|
||||
1
src/py/crankshaft/test/fixtures/maxp.json
vendored
Normal file
1
src/py/crankshaft/test/fixtures/maxp.json
vendored
Normal file
File diff suppressed because one or more lines are too long
62
src/py/crankshaft/test/test_clustering_maxp.py
Normal file
62
src/py/crankshaft/test/test_clustering_maxp.py
Normal file
@@ -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