# HG changeset patch # User Nicolas Saunier # Date 1439353446 14400 # Node ID 0e875a7f57592d46b01c7a4699d6bdb456d482c2 # Parent 1d4dcb5c870867f5c861d95fc514068300a196fa modified prototypeCluster algorithm to enforce similarity when re-assigning and to compute only the necessary similarities diff -r 1d4dcb5c8708 -r 0e875a7f5759 python/events.py --- a/python/events.py Tue Aug 11 12:55:09 2015 -0400 +++ b/python/events.py Wed Aug 12 00:24:06 2015 -0400 @@ -295,8 +295,8 @@ print('unknown type of point: '+pointType) return allPoints -def prototypeCluster(interactions, similarityMatrix, indicatorName, minSimilarity, minClusterSize = None, randomInitialization = False): - return ml.prototypeCluster([inter.getIndicator(indicatorName) for inter in interactions], similarityMatrix, minSimilarity, minClusterSize, randomInitialization) +def prototypeCluster(interactions, similarities, indicatorName, minSimilarity, similarityFunc = None, minClusterSize = None, randomInitialization = False): + return ml.prototypeCluster([inter.getIndicator(indicatorName) for inter in interactions], similarities, minSimilarity, similarityFunc, minClusterSize, randomInitialization) class Crossing(moving.STObject): '''Class for the event of a street crossing diff -r 1d4dcb5c8708 -r 0e875a7f5759 python/ml.py --- a/python/ml.py Tue Aug 11 12:55:09 2015 -0400 +++ b/python/ml.py Wed Aug 12 00:24:06 2015 -0400 @@ -111,12 +111,14 @@ code,distance = vq(features,centroids) # code starting from 0 (represent first cluster) to k-1 (last cluster) return code,sigma -def prototypeCluster(instances, similarityMatrix, minSimilarity, minClusterSize = None, randomInitialization = False): +def prototypeCluster(instances, similarities, minSimilarity, similarityFunc = None, 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 + the positions in the instances list corresponds to the similarities + if similarityFunc is provided, the similarities are calculated as needed (this is faster) if not in similarities (negative if not computed) + similarities must still be allocated with the right size if an instance is different enough (= minSimilarity: + labels[i] = prototypeIndices[prototypeIdx] + else: + labels[i] = -1 # outlier clusterSizes = {i: sum(np.array(labels) == i) for i in prototypeIndices} - smallestClusterIndex = min(clusterSizes, key = clusterSizes.get) + smallestClusterIndex = min(clusterSizes, key = clusterSizes.get) assign = (clusterSizes[smallestClusterIndex] < minClusterSize) if assign: prototypeIndices.remove(smallestClusterIndex) diff -r 1d4dcb5c8708 -r 0e875a7f5759 scripts/learn-motion-patterns.py --- a/scripts/learn-motion-patterns.py Tue Aug 11 12:55:09 2015 -0400 +++ b/scripts/learn-motion-patterns.py Wed Aug 12 00:24:06 2015 -0400 @@ -42,18 +42,23 @@ lcss = utils.LCSS(metric = args.metric, epsilon = args.epsilon) nTrajectories = len(trajectories) -similarities = np.zeros((nTrajectories, nTrajectories)) -for i in xrange(nTrajectories): - for j in xrange(i): - similarities[i,j] = lcss.computeNormalized(trajectories[i], trajectories[j]) - similarities[j,i] = similarities[i,j] +similarities = -np.ones((nTrajectories, nTrajectories)) +# for i in xrange(nTrajectories): +# for j in xrange(i): +# similarities[i,j] = lcss.computeNormalized(trajectories[i], trajectories[j]) +# similarities[j,i] = similarities[i,j] -prototypeIndices, labels = ml.prototypeCluster(trajectories, similarities, args.minSimilarity, args.minClusterSize) +prototypeIndices, labels = ml.prototypeCluster(trajectories, similarities, args.minSimilarity, lambda x,y : lcss.computeNormalized(x, y), args.minClusterSize) # this line can be called again without reinitializing similarities if args.display: + from matplotlib.pyplot import figure + figure() for i,o in enumerate(objects): if i not in prototypeIndices: - o.plot(utils.colors[labels[i]]) + if labels[i] < 0: + o.plot('kx') + else: + o.plot(utils.colors[labels[i]]) for i in prototypeIndices: objects[i].plot(utils.colors[i]+'o')