changeset 731:b02431a8234c dev

made prototypecluster generic, in ml module, and added randominitialization
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Tue, 11 Aug 2015 11:38:05 -0400
parents a850a4f92735
children ad31520e81b5
files python/events.py python/ml.py
diffstat 2 files changed, 55 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/python/events.py	Tue Aug 11 10:52:04 2015 -0400
+++ b/python/events.py	Tue Aug 11 11:38:05 2015 -0400
@@ -2,7 +2,7 @@
 '''Libraries for events
 Interactions, pedestrian crossing...'''
 
-import moving, prediction, indicators, utils, cvutils
+import moving, prediction, indicators, utils, cvutils, ml
 from base import VideoFilenameAddable
 
 import numpy as np
@@ -295,60 +295,8 @@
         print('unknown type of point: '+pointType)
     return allPoints
 
-def prototypeCluster(interactions, similarityMatrix, alignmentMatrix, indicatorName, minSimilarity, minClusterSize = None):
-    '''Finds exemplar indicator time series for all interactions
-    Returns the prototype indices (in the interaction list) and the label of each indicator (interaction)
-
-    if an indicator profile (time series) is different enough (<minSimilarity), 
-    it will become a new prototype. 
-    Non-prototype interactions will be assigned to an existing prototype
-    if minClusterSize is not None, the clusters will be refined by removing iteratively the smallest clusters
-    and reassigning all elements in the cluster until no cluster is smaller than minClusterSize'''
-
-    # sort indicators based on length
-    indices = range(similarityMatrix.shape[0])
-    def compare(i, j):
-        if len(interactions[i].getIndicator(indicatorName)) > len(interactions[j].getIndicator(indicatorName)):
-            return -1
-        elif len(interactions[i].getIndicator(indicatorName)) == len(interactions[j].getIndicator(indicatorName)):
-            return 0
-        else:
-            return 1
-    indices.sort(compare)
-    # go through all indicators
-    prototypeIndices = [indices[0]]
-    for i in indices[1:]:
-        if similarityMatrix[i][prototypeIndices].max() < minSimilarity:
-             prototypeIndices.append(i)
-
-    # assignment
-    indices = [i for i in range(similarityMatrix.shape[0]) if i not in prototypeIndices]
-    assign = True
-    while assign:
-        labels = [-1]*similarityMatrix.shape[0]
-        for i in prototypeIndices:
-            labels[i] = i
-        for i in indices:
-            prototypeIndex = similarityMatrix[i][prototypeIndices].argmax()
-            labels[i] = prototypeIndices[prototypeIndex]
-        clusterSizes = {i: sum(np.array(labels) == i) for i in prototypeIndices}
-        smallestClusterIndex = min(clusterSizes, key = clusterSizes.get) 
-        assign = (clusterSizes[smallestClusterIndex] < minClusterSize)
-        print prototypeIndices, smallestClusterIndex, clusterSizes[smallestClusterIndex]
-        if assign:
-            prototypeIndices.remove(smallestClusterIndex)
-            indices.append(smallestClusterIndex)
-
-    return prototypeIndices, labels
-
-def prototypeMultivariateCluster(interactions, similarityMatrics, indicatorNames, minSimilarities, minClusterSize):
-    '''Finds exmaple indicator time series (several indicators) for all interactions
-
-    if any interaction indicator time series is different enough (<minSimilarity),
-    it will become a new prototype. 
-    Non-prototype interactions will be assigned to an existing prototype if all indicators are similar enough'''
-    pass
-
+def prototypeCluster(interactions, similarityMatrix, indicatorName, minSimilarity, minClusterSize = None, randomInitialization = False):
+    return ml.prototypeCluster([inter.getIndicator(indicatorName) for inter in interactions], similarityMatrix, minSimilarity, minClusterSize, randomInitialization)
 
 class Crossing(moving.STObject):
     '''Class for the event of a street crossing
--- a/python/ml.py	Tue Aug 11 10:52:04 2015 -0400
+++ b/python/ml.py	Tue Aug 11 11:38:05 2015 -0400
@@ -111,13 +111,59 @@
 	code,distance = vq(features,centroids) # code starting from 0 (represent first cluster) to k-1 (last cluster)
 	return code,sigma	
 
-def motionPatterLearning(objects, maxDistance):
+def prototypeCluster(instances, similarityMatrix, minSimilarity, minClusterSize = None, randomInitialization = False):
+    '''Finds exemplar (prototype) instance that represent each cluster
+    Returns the prototype indices (in the instances list) and the cluster label of each instance
+
+    the elements in the instances list must have a length (method __len__), or one can use the random initialization
+    the positions in the instances list corresponds to the similarityMatrix
+
+    if an instance is different enough (<minSimilarity), 
+    it will become a new prototype. 
+    Non-prototype instances will be assigned to an existing prototype
+    if minClusterSize is not None, the clusters will be refined by removing iteratively the smallest clusters
+    and reassigning all elements in the cluster until no cluster is smaller than minClusterSize'''
+
+    # sort instances based on length
+    indices = range(similarityMatrix.shape[0])
+    if randomInitialization:
+        indices = np.random.permutation(indices)
+    else:
+        def compare(i, j):
+            if len(instances[i]) > len(instances[j]):
+                return -1
+            elif len(instances[i]) == len(instances[j]):
+                return 0
+            else:
+                return 1
+        indices.sort(compare)
+    # go through all instances
+    prototypeIndices = [indices[0]]
+    for i in indices[1:]:
+        if similarityMatrix[i][prototypeIndices].max() < minSimilarity:
+             prototypeIndices.append(i)
+
+    # assignment
+    indices = [i for i in range(similarityMatrix.shape[0]) if i not in prototypeIndices]
+    assign = True
+    while assign:
+        labels = [-1]*similarityMatrix.shape[0]
+        for i in prototypeIndices:
+            labels[i] = i
+        for i in indices:
+            prototypeIndex = similarityMatrix[i][prototypeIndices].argmax()
+            labels[i] = prototypeIndices[prototypeIndex]
+        clusterSizes = {i: sum(np.array(labels) == i) for i in prototypeIndices}
+        smallestClusterIndex = min(clusterSizes, key = clusterSizes.get) 
+        assign = (clusterSizes[smallestClusterIndex] < minClusterSize)
+        if assign:
+            prototypeIndices.remove(smallestClusterIndex)
+            indices.append(smallestClusterIndex)
+
+    return prototypeIndices, labels
+
+def motionPatternLearning(objects, maxDistance):
     ''' 
     Option to use only the (n?) longest features per object instead of all for speed up
     TODO'''
     pass
-
-def prototypeCluster():
-    ''' 
-    TODO'''
-    pass