updating prediction to data provider

This commit is contained in:
Andy Eschbacher
2017-01-05 14:22:40 -05:00
parent fa3eecb233
commit d95ca54cdc
3 changed files with 101 additions and 2 deletions

View File

@@ -74,3 +74,11 @@ class AnalysisDataProvider:
return query_result
except plpy.SPIError, err:
plpy.error('Analysis failed: %s' % err)
def get_gwr_predict(self, params):
"""fetch data for gwr predict"""
query = pu.gwr_predict_query(params)
try:
query_result = plpy.execute(query)
return query_result
except plpy.SPIError, err:
plpy.error('Analysis failed: %s' % err)

View File

@@ -222,6 +222,7 @@ def gwr_query(params):
return query.format(**params).strip()
def gwr_predict_query(params):
"""
GWR query

View File

@@ -39,8 +39,7 @@ class GWR:
# unique ids and variable names list
rowid = np.array(query_result[0]['rowid'], dtype=np.int)
# TODO: should x, y be centroids? point on surface?
# lat, long coordinates
# x, y are centroids of input geometries
x = np.array(query_result[0]['x'], dtype=float)
y = np.array(query_result[0]['y'], dtype=float)
coords = zip(x, y)
@@ -90,3 +89,94 @@ class GWR:
return zip(coeffs, stand_errs, t_vals,
predicted, residuals, r_squared, bw, rowid)
def gwr_predict(self, subquery, dep_var, ind_vars,
bw=None, fixed=False, kernel='bisquare',
geom_col='the_geom', id_col='cartodb_id'):
"""
subquery: 'select * from demographics'
dep_var: 'pctbachelor'
ind_vars: ['intercept', 'pctpov', 'pctrural', 'pctblack']
bw: value of bandwidth, if None then select optimal
fixed: False (kNN) or True ('distance')
kernel: 'bisquare' (default), or 'exponential', 'gaussian'
"""
params = {'geom_col': geom_col,
'id_col': id_col,
'subquery': subquery,
'dep_var': dep_var,
'ind_vars': ind_vars}
query_result = self.data_provider.get_gwr_predict(params)
# unique ids and variable names list
rowid = np.array(query_result[0]['rowid'], dtype=np.int)
x = np.array(query_result[0]['x'])
y = np.array(query_result[0]['y'])
coords = np.array(zip(x, y))
# extract dependent variable
Y = np.array(query_result[0]['dep_var']).reshape((-1, 1))
n = Y.shape[0]
k = len(ind_vars)
X = np.zeros((n, k))
for attr in range(0, k):
attr_name = 'attr' + str(attr + 1)
X[:, attr] = np.array(
query_result[0][attr_name]).flatten()
# add intercept variable name
ind_vars.insert(0, 'intercept')
# split data into "training" and "test" for predictions
# create index to split based on null y values
train = np.where(Y != np.array(None))[0]
test = np.where(Y == np.array(None))[0]
if len(test) < 1:
plpy.error('No rows flagged for prediction: verify that rows '
'denoting prediction locations have a dependent '
'variable value of null')
# split dependent variable (only need training which is non-Null's)
Y_train = Y[train].reshape((-1, 1))
Y_train = Y_train.astype(np.float)
# split coords
coords_train = coords[train]
coords_test = coords[test]
# split explanatory variables
X_train = X[train]
X_test = X[test]
# calculate bandwidth if none is supplied
if bw is None:
bw = Sel_BW(coords_train, Y_train, X_train,
fixed=fixed, kernel=kernel).search()
# estimate model and predict at new locations
model = GWR(coords_train, Y_train, X_train, bw,
fixed=fixed, kernel=kernel).predict(coords_test, X_test)
coefficients = []
stand_errs = []
t_vals = []
r_squared = model.localR2.flatten()
predicted = model.predy.flatten()
m = len(model.predy)
for idx in xrange(m):
coefficients.append(json.dumps({var: model.params[idx, k]
for k, var in enumerate(ind_vars)}))
stand_errs.append(json.dumps({var: model.bse[idx, k]
for k, var in enumerate(ind_vars)}))
t_vals.append(json.dumps({var: model.tvalues[idx, k]
for k, var in enumerate(ind_vars)}))
return zip(coefficients, stand_errs, t_vals,
r_squared, predicted, rowid)