pep-8 changes and model accuracy fucntion parameter changes

This commit is contained in:
mehak-sachdeva
2016-12-07 15:21:00 -05:00
parent f8739b6a68
commit 4d2b37e6a3

View File

@@ -10,7 +10,8 @@ from sklearn import metrics
from sklearn.cross_validation import train_test_split
# Lower level functions
#----------------------
# ---------------------
def replace_nan_with_mean(array):
"""
@@ -28,6 +29,7 @@ def replace_nan_with_mean(array):
return array
def get_data(variable, feature_columns, query):
"""
Fetch data from the database, clean, and package into
@@ -40,10 +42,15 @@ def get_data(variable, feature_columns, query):
prepared data, packaged into NumPy arrays
"""
columns = ','.join(['array_agg("{col}") As "{col}"'.format(col=col) for col in feature_columns])
columns = ','.join(['array_agg("{col}") As "{col}"'.format(col=col)
for col in feature_columns])
try:
data = plpy.execute('''SELECT array_agg("{variable}") As target, {columns} FROM ({query}) As a'''.format(
data = plpy.execute('''
SELECT
array_agg("{variable}") As target,
{columns}
FROM ({query}) As a'''.format(
variable=variable,
columns=columns,
query=query))
@@ -54,34 +61,43 @@ def get_data(variable, feature_columns, query):
target = np.array(data[0]['target'])
# put n feature data arrays into an n x m array of arrays
features = np.column_stack([np.array(data[0][col], dtype=float) for col in feature_columns])
features = np.column_stack([np.array(data[0][col], dtype=float)
for col in feature_columns])
return replace_nan_with_mean(target), replace_nan_with_mean(features)
# High level interface
# --------------------
def create_and_predict_segment_agg(target, features, target_features, target_ids, model_parameters):
def create_and_predict_segment_agg(target, features, target_features,
target_ids, model_parameters):
"""
Version of create_and_predict_segment that works on arrays that come stright form the SQL calling
the function.
Version of create_and_predict_segment that works on arrays that come
straight form the SQL calling the function.
Input:
@param target: The 1D array of lenth NSamples containing the target variable we want the model to predict
@param features: Thw 2D array of size NSamples * NFeatures that form the imput to the model
@param target_ids: A 1D array of target_ids that will be used to associate the results of the prediction with the rows which they come from
@param model_parameters: A dictionary containing parameters for the model.
@param target: The 1D array of lenth NSamples containing the target
variable we want the model to predict
@param features: The 2D array of size NSamples * NFeatures that
form the imput to the model
@param target_ids: A 1D array of target_ids that will be used to
associate the results of the prediction with the rows which
they come from
@param model_parameters: A dictionary containing parameters for the
model.
"""
clean_target = replace_nan_with_mean(target)
clean_features = replace_nan_with_mean(features)
target_features = replace_nan_with_mean(target_features)
model, accuracy = train_model(clean_target, clean_features, model_parameters, 0.2)
model, accuracy = train_model(clean_target, clean_features,
model_parameters, 0.2)
prediction = model.predict(target_features)
accuracy_array = [accuracy]*prediction.shape[0]
return zip(target_ids, prediction, np.full(prediction.shape, accuracy_array))
return zip(target_ids, prediction,
np.full(prediction.shape, accuracy_array))
def create_and_predict_segment(query, variable, target_query, model_params):
@@ -90,15 +106,19 @@ def create_and_predict_segment(query, variable, target_query, model_params):
Stuart Lynn
"""
## fetch column names
# fetch column names
try:
columns = plpy.execute('SELECT * FROM ({query}) As a LIMIT 1 '.format(query=query))[0].keys()
columns = plpy.execute('''
SELECT *
FROM ({query}) As a
LIMIT 1'''.format(query=query))[0].keys()
except Exception, e:
plpy.error('Failed to build segmentation model: %s' % e)
## extract column names to be used in building the segmentation model
feature_columns = set(columns) - set([variable, 'cartodb_id', 'the_geom', 'the_geom_webmercator'])
## get data from database
# extract column names to be used in building the segmentation model
feature_columns = set(columns) - set([variable, 'cartodb_id',
'the_geom', 'the_geom_webmercator'])
# get data from database
target, features = get_data(variable, feature_columns, query)
model, accuracy = train_model(target, features, model_params, 0.2)
@@ -109,49 +129,65 @@ def create_and_predict_segment(query, variable, target_query, model_params):
def train_model(target, features, model_params, test_split):
"""
Train the Gradient Boosting model on the provided data and calculate the accuracy of the model
Train the Gradient Boosting model on the provided data and calculate
the accuracy of the model
Input:
@param target: 1D Array of the variable that the model is to be trianed to predict
@param features: 2D Array NSamples * NFeatures to use in trining the model
@param model_params: A dictionary of model parameters, the full specification can be found on the
scikit learn page for [GradientBoostingRegressor](http://scikit-learn.org/stable/modules/generated/sklearn.ensemble.GradientBoostingRegressor.html)
@parma test_split: The fraction of the data to be withheld for testing the model / calculating the accuray
@param target: 1D Array of the variable that the model is to be
trained to predict
@param features: 2D Array NSamples * NFeatures to use in trining
the model
@param model_params: A dictionary of model parameters, the full
specification can be found on the
scikit learn page for [GradientBoostingRegressor]
(http://scikit-learn.org/stable/modules/generated/sklearn.ensemble.GradientBoostingRegressor.html)
@parma test_split: The fraction of the data to be withheld for
testing the model / calculating the accuray
"""
features_train, features_test, target_train, target_test = train_test_split(features, target, test_size=test_split)
features_train, features_test, target_train, target_test =
train_test_split(features, target, test_size=test_split)
model = GradientBoostingRegressor(**model_params)
model.fit(features_train, target_train)
accuracy = calculate_model_accuracy(model, features, target)
accuracy = calculate_model_accuracy(model, features_test, target_test)
return model, accuracy
def calculate_model_accuracy(model, features, target):
def calculate_model_accuracy(model, features_test, target_test):
"""
Calculate the mean squared error of the model prediction
Input:
@param model: model trained from input features
@param features: features to make a prediction from
@param target: target to compare prediction to
@param features_test: test features set to make a prediction from
@param target_target: test target set to compare predictions to
Output:
mean squared error of the model prection compared to the target
mean squared error of the model prection compared to target_test
"""
prediction = model.predict(features)
return metrics.mean_squared_error(prediction, target)
prediction = model.predict(features_test)
return metrics.mean_squared_error(prediction, target_test)
def predict_segment(model, features, target_query):
def predict_segment(model, features_col, target_query):
"""
Use the provided model to predict the values for the new feature set
Input:
@param model: The pretrained model
@features: A list of features to use in the model prediction (list of column names)
@target_query: The query to run to obtain the data to predict on and the cartdb_ids associated with it.
@features_col: A list of features to use in the
model prediction (list of column names)
@target_query: The query to run to obtain the data to predict
on and the cartdb_ids associated with it.
"""
batch_size = 1000
joined_features = ','.join(['"{0}"::numeric'.format(a) for a in features])
joined_features = ','.join(['"{0}"::numeric'.format(a)
for a in features_col])
try:
cursor = plpy.cursor('SELECT Array[{joined_features}] As features FROM ({target_query}) As a'.format(
joined_features=joined_features,
target_query=target_query))
cursor = plpy.cursor('''
SELECT Array[{joined_features}] As features
FROM ({target_query}) As a'''
.format(
joined_features=joined_features,
target_query=target_query)
)
except Exception, e:
plpy.error('Failed to build segmentation model: %s' % e)
@@ -161,15 +197,20 @@ def predict_segment(model, features, target_query):
rows = cursor.fetch(batch_size)
if not rows:
break
batch = np.row_stack([np.array(row['features'], dtype=float) for row in rows])
batch = np.row_stack([np.array(row['features'], dtype=float)
for row in rows])
#Need to fix this. Should be global mean. This will cause weird effects
# Need to fix this to global mean. This will cause weird effects
batch = replace_nan_with_mean(batch)
prediction = model.predict(batch)
results.append(prediction)
try:
cartodb_ids = plpy.execute('''SELECT array_agg(cartodb_id ORDER BY cartodb_id) As cartodb_ids FROM ({0}) As a'''.format(target_query))[0]['cartodb_ids']
cartodb_ids = plpy.execute('''
SELECT array_agg(cartodb_id
ORDER BY cartodb_id) As cartodb_ids
FROM ({0}) As a'''
.format(target_query))[0]['cartodb_ids']
except Exception, e:
plpy.error('Failed to build segmentation model: %s' % e)