From 9a80244e76df5c33034cd0fdc0ce34dade3a193e Mon Sep 17 00:00:00 2001 From: Andy Eschbacher Date: Tue, 6 Dec 2016 10:14:37 -0500 Subject: [PATCH] adds tests and pgsql file --- src/pg/sql/11_kmeans.sql | 19 +++++++++ .../crankshaft/test/test_clustering_kmeans.py | 39 ++++++++++++++++--- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/pg/sql/11_kmeans.sql b/src/pg/sql/11_kmeans.sql index 0899e81..6100d27 100644 --- a/src/pg/sql/11_kmeans.sql +++ b/src/pg/sql/11_kmeans.sql @@ -9,6 +9,25 @@ RETURNS table (cartodb_id integer, cluster_no integer) as $$ $$ LANGUAGE plpythonu; +-- Non-spatial k-means clustering +-- query: sql query to retrieve all the needed data + +CREATE OR REPLACE FUNCTION CDB_KMeansNonspatial( + query TEXT, + colnames TEXT[], + num_clusters INTEGER, + id_colname TEXT DEFAULT 'cartodb_id', + standarize BOOLEAN DEFAULT true +) +RETURNS TABLE(cluster_label text, cluster_center json, silhouettes numeric, rowid bigint) AS $$ + + from crankshaft.clustering import Kmeans + kmeans = Kmeans() + return kmeans.nonspatial(query, colnames, num_clusters, + id_colname, standarize) +$$ LANGUAGE plpythonu; + + CREATE OR REPLACE FUNCTION CDB_WeightedMeanS(state Numeric[],the_geom GEOMETRY(Point, 4326), weight NUMERIC) RETURNS Numeric[] AS diff --git a/src/py/crankshaft/test/test_clustering_kmeans.py b/src/py/crankshaft/test/test_clustering_kmeans.py index 93633b0..5e096ca 100644 --- a/src/py/crankshaft/test/test_clustering_kmeans.py +++ b/src/py/crankshaft/test/test_clustering_kmeans.py @@ -2,17 +2,12 @@ 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 Kmeans from crankshaft.analysis_data_provider import AnalysisDataProvider import crankshaft.clustering as cc - from crankshaft import random_seeds + import json from collections import OrderedDict @@ -54,3 +49,35 @@ class KMeansTest(unittest.TestCase): self.assertEqual(len(np.unique(labels)), 2) self.assertEqual(len(c1), 20) self.assertEqual(len(c2), 20) + + +class KMeansNonspatialTest(unittest.TestCase): + """Testing class for k-means non-spatial""" + + def setUp(self): + self.params = {"subquery": "SELECT * FROM TABLE", + "n_clusters": 5} + + def test_kmeans_nonspatial(self): + """ + test for k-means non-spatial + """ + # data from: + # http://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html#sklearn-cluster-kmeans + data_raw = [OrderedDict([("col1", [1, 1, 1, 4, 4, 4]), + ("col2", [2, 4, 0, 2, 4, 0]), + ("rowids", [1, 2, 3, 4, 5, 6])])] + + random_seeds.set_random_seeds(1234) + kmeans = Kmeans(FakeQueryRunner(data_raw)) + clusters = kmeans.nonspatial('subquery', ['col1', 'col2'], 2) + print str([c[0] for c in clusters]) + + cl1 = clusters[0][0] + cl2 = clusters[3][0] + + for idx, val in enumerate(clusters): + if idx < 3: + self.assertEqual(val[0], cl1) + else: + self.assertEqual(val[0], cl2)