changeset 915:13434f5017dd

work to save trajectory assignment to origin and destinations
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Tue, 04 Jul 2017 17:03:29 -0400
parents f228fd649644
children 7345f0d51faa
files python/ml.py python/storage.py scripts/learn-poi.py
diffstat 3 files changed, 57 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/python/ml.py	Wed Jun 28 23:43:52 2017 -0400
+++ b/python/ml.py	Tue Jul 04 17:03:29 2017 -0400
@@ -264,27 +264,37 @@
                         similarities[l][k] = similarities[k][l]
             print('Mean similarity to prototype: {}'.format((similarities[prototypeIndices[i]][cluster].sum()+1)/(n-1)))
             print('Mean overall similarity: {}'.format((similarities[cluster][:,cluster].sum()+n)/(n*(n-1))))
-                    
+
 # Gaussian Mixture Models
-def plotGMMClusters(model, labels, dataset = None, fig = None, colors = utils.colors, nUnitsPerPixel = 1., alpha = 0.3):
+def plotGMMClusters(model, labels = None, dataset = None, fig = None, colors = utils.colors, nUnitsPerPixel = 1., alpha = 0.3):
     '''plot the ellipse corresponding to the Gaussians
     and the predicted classes of the instances in the dataset'''
     if fig is None:
         fig = plt.figure()
-    tmpDataset = dataset/nUnitsPerPixel
+    axes = fig.get_axes()
+    if len(axes) == 0:
+        axes = [fig.add_subplot(111)]
     for i in xrange(model.n_components):
         mean = model.means_[i]/nUnitsPerPixel
         covariance = model.covariances_[i]/nUnitsPerPixel
+        # plot points
         if dataset is not None:
+            tmpDataset = dataset/nUnitsPerPixel
             plt.scatter(tmpDataset[labels == i, 0], tmpDataset[labels == i, 1], .8, color=colors[i])
-        plt.annotate(str(i), xy=(mean[0]+1, mean[1]+1))
-
-        # Plot an ellipse to show the Gaussian component                                                  
+        # plot an ellipse to show the Gaussian component                                                  
         v, w = np.linalg.eigh(covariance)
-        angle = np.arctan2(w[0][1], w[0][0])
-        angle = 180*angle/np.pi  # convert to degrees                                             
+        angle = 180*np.arctan2(w[0][1], w[0][0])/np.pi
         v *= 4
         ell = mpl.patches.Ellipse(mean, v[0], v[1], 180+angle, color=colors[i])
         ell.set_clip_box(fig.bbox)
         ell.set_alpha(alpha)
-        fig.axes[0].add_artist(ell)
+        axes[0].add_artist(ell)
+        plt.plot([mean[0]], [mean[1]], 'x'+colors[i])
+        plt.annotate(str(i), xy=(mean[0]+1, mean[1]+1))
+    if dataset is None: # to address issues without points, the axes limits are not redrawn
+        minima = model.means_.min(0)
+        maxima = model.means_.max(0)
+        xwidth = 0.5*(maxima[0]-minima[0])
+        ywidth = 0.5*(maxima[1]-minima[1])
+        plt.xlim(minima[0]-xwidth,maxima[0]+xwidth)
+        plt.ylim(minima[1]-ywidth,maxima[1]+ywidth)
--- a/python/storage.py	Wed Jun 28 23:43:52 2017 -0400
+++ b/python/storage.py	Tue Jul 04 17:03:29 2017 -0400
@@ -507,7 +507,7 @@
         elif dataType == 'bb':
             dropTables(connection, ['bounding_boxes'])
         elif dataType == 'pois':
-            dropTables(connection, ['gaussians2d'])
+            dropTables(connection, ['gaussians2d', 'objects_pois'])
         elif dataType == 'prototype':
             dropTables(connection, ['prototypes'])
         else:
@@ -645,6 +645,19 @@
         printDBError(error)
     connection.close()
 
+def savePOIAssignments(filename, objects):
+    'save the od fields of objects'
+    connection = sqlite3.connect(filename)
+    cursor = connection.cursor()
+    try:
+        cursor.execute('CREATE TABLE IF NOT EXISTS objects_pois (object_id INTEGER, origin_poi_id INTEGER, destination_poi_id INTEGER, PRIMARY KEY(object_id))')
+        for o in objects:
+            cursor.execute('INSERT INTO objects_pois VALUES({},{},{})'.format(o.getNum(), o.od[0], o.od[1]))
+        connection.commit()
+    except sqlite3.OperationalError as error:
+        printDBError(error)
+    connection.close()
+    
 def loadPOIs(filename):
     'Loads all 2D Gaussians in the database'
     from sklearn import mixture # todo if not avalaible, load data in duck-typed class with same fields
@@ -698,25 +711,25 @@
 #########################
 
 def writePrototypesToSqlite(prototypes,nMatching, outputFilename):
-    """ prototype dataset is a dictionary with  keys== routes, values== prototypes Ids """
+    ''' prototype dataset is a dictionary with  keys== routes, values== prototypes Ids '''
     connection = sqlite3.connect(outputFilename)
     cursor = connection.cursor()
 
-    cursor.execute("CREATE TABLE IF NOT EXISTS prototypes (prototype_id INTEGER,routeIDstart INTEGER,routeIDend INTEGER, nMatching INTEGER, PRIMARY KEY(prototype_id))")
+    cursor.execute('CREATE TABLE IF NOT EXISTS prototypes (prototype_id INTEGER,routeIDstart INTEGER,routeIDend INTEGER, nMatching INTEGER, PRIMARY KEY(prototype_id))')
     
     for route in prototypes.keys():
         if prototypes[route]!=[]:
             for i in prototypes[route]:
-                cursor.execute("insert into prototypes (prototype_id, routeIDstart,routeIDend, nMatching) values (?,?,?,?)",(i,route[0],route[1],nMatching[route][i]))
+                cursor.execute('insert into prototypes (prototype_id, routeIDstart,routeIDend, nMatching) values (?,?,?,?)',(i,route[0],route[1],nMatching[route][i]))
                     
     connection.commit()
     connection.close()
     
 def readPrototypesFromSqlite(filename):
-    """
+    '''
     This function loads the prototype file in the database 
     It returns a dictionary for prototypes for each route and nMatching
-    """
+    '''
     prototypes = {}
     nMatching={}
 
--- a/scripts/learn-poi.py	Wed Jun 28 23:43:52 2017 -0400
+++ b/scripts/learn-poi.py	Tue Jul 04 17:03:29 2017 -0400
@@ -20,6 +20,8 @@
 parser.add_argument('--display', dest = 'display', help = 'display points of interests', action = 'store_true') # default is manhattan distance
 parser.add_argument('--assign', dest = 'assign', help = 'display points of interests', action = 'store_true')
 
+# TODO test Variational Bayesian Gaussian Mixture BayesianGaussianMixture
+
 args = parser.parse_args()
 
 objects = storage.loadTrajectoriesFromSqlite(args.databaseFilename, args.trajectoryType, args.nObjects)
@@ -29,6 +31,8 @@
 for o in objects:
     beginnings.append(o.getPositionAt(0).aslist())
     ends.append(o.getPositionAt(int(o.length())-1).aslist())
+    if args.assign:
+        o.od = [-1, -1]
 
 beginnings = np.array(beginnings)
 ends = np.array(ends)
@@ -38,42 +42,41 @@
     nDestinationClusters = args.nOriginClusters
 
 gmmId=0
+models = {}
 for nClusters, points, gmmType in zip([args.nOriginClusters, nDestinationClusters],
                                       [beginnings, ends],
                                       ['beginning', 'end']):
     # estimation
     gmm = mixture.GaussianMixture(n_components=nClusters, covariance_type = args.covarianceType)
-    model=gmm.fit(points)
-    if not model.converged_:
+    models[gmmType]=gmm.fit(points)
+    if not models[gmmType].converged_:
         print('Warning: model for '+gmmType+' points did not converge')
     if args.display or args.assign:
-        labels = model.predict(points)
+        labels = models[gmmType].predict(points)
     # plot
     if args.display:
         fig = plt.figure()
         if args.worldImageFilename is not None and args.unitsPerPixel is not None:
             img = plt.imread(args.worldImageFilename)
             plt.imshow(img)
-        ml.plotGMMClusters(model, labels, points, fig, nUnitsPerPixel = args.unitsPerPixel)
+        ml.plotGMMClusters(models[gmmType], labels, points, fig, nUnitsPerPixel = args.unitsPerPixel)
         plt.axis('image')
         plt.title(gmmType)
-        print(gmmType+' Clusters:\n{}'.format(ml.computeClusterSizes(labels, range(model.n_components))))
+        print(gmmType+' Clusters:\n{}'.format(ml.computeClusterSizes(labels, range(models[gmmType].n_components))))
     # save
-    storage.savePOIs(args.databaseFilename, model, gmmType, gmmId)
+    storage.savePOIs(args.databaseFilename, models[gmmType], gmmType, gmmId)
     # save assignments
     if args.assign:
-        pass # savePOIAssignments(
+        for o, l in zip(objects, labels):
+            if gmmType == 'beginning':
+                o.od[0] = l
+            elif gmmType == 'end':
+                o.od[1] = l
     gmmId += 1
 
+if args.assign:
+    storage.savePOIAssignments(args.databaseFilename, objects)
+
 if args.display:
     plt.axis('equal')
     plt.show()
-
-# fig = plt.figure()
-# if args.worldImageFilename is not None and args.pixelsPerUnit is not None:
-#     img = plt.imread(args.worldImageFilename)
-#     plt.imshow(img)
-# ml.plotGMMClusters(, , fig, nPixelsPerUnit = args.pixelsPerUnit)
-# plt.axis('equal')
-# plt.title()
-# print('Destination Clusters:\n{}'.format(ml.computeClusterSizes(endModel.predict(ends), range(args.nClusters))))