changeset 285:5957aa1d69e1

Integrating Mohamed's changes Changed the indicator interface to access values, so that the generic LCSS implementation can be used
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Sat, 26 Jan 2013 19:02:25 -0500
parents f2cf16ad798f
children fa95796a76b3
files python/indicators.py python/ml.py python/tests/indicators.txt python/tests/utils.txt python/utils.py
diffstat 5 files changed, 70 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/python/indicators.py	Fri Dec 21 18:33:36 2012 -0500
+++ b/python/indicators.py	Sat Jan 26 19:02:25 2013 -0500
@@ -38,11 +38,22 @@
         return len(self.values) == 0
 
     def __getitem__(self, i):
+        'Returns ith value'
+        sortedKeys = sorted(self.values.keys())
+        if 0<=i<len(sortedKeys):
+            return self.values[sortedKeys[i]]
+        else:
+            return None
+
+    def valueAtInstant(self, i):
         if i in self.values.keys():
             return self.values[i]
         else:
             return None
 
+    def __len__(self):
+        return len(self.values)
+
     def __iter__(self):
         self.iterInstantNum = 0 # index in the interval or keys of the dict
         return self
@@ -53,7 +64,7 @@
             raise StopIteration
         else:
             self.iterInstantNum += 1
-            return self.values[self.values.keys()[self.iterInstantNum-1]]
+            return self.__getitem__(self.iterInstantNum-1)
 
     def getTimeInterval(self):
         return self.timeInterval
@@ -83,6 +94,20 @@
         if self.maxValue:
             ylim(ymax = self.maxValue)
 
+    @staticmethod
+    def computeDLCSS(indicator1, indicator2, threshold, delta = float('inf'), method= 'min'):
+	''' compute the distance between two indicators using LCSS
+	two common methods are used: min or mean of the indicators length'''
+        # l1= TemporalIndicator1.valueSorted
+	# 	l2= TemporalIndicator2.valueSorted
+	# 	if method = 'min':
+	# 		DLCSS= 1- (LCSS(l1,l2, threshold, delta, distance))/min(len(l1),len(l2)))
+	# 	if method = 'mean':
+	# 		average= len(l1)+len(l2))/2
+	# 		DLCSS= 1- ((LCSS(l1,l2, threshold, delta, distance))/average)
+	# 	return DLCSS
+        return 0
+
 class SeverityIndicator(TemporalIndicator):
     '''Class for severity indicators 
     field mostSevereIsMax is True 
@@ -93,7 +118,7 @@
         self.mostSevereIsMax = mostSevereIsMax
         self.ignoredValue = ignoredValue
 
-    def getMostSevereValue(self, minNInstants=1):
+    def getMostSevereValue(self, minNInstants=1): # TODO use scoreatpercentile
         from matplotlib.mlab import find
         from numpy.core.multiarray import array
         from numpy.core.fromnumeric import mean
--- a/python/ml.py	Fri Dec 21 18:33:36 2012 -0500
+++ b/python/ml.py	Sat Jan 26 19:02:25 2013 -0500
@@ -1,6 +1,8 @@
 #! /usr/bin/env python
 '''Libraries for machine learning algorithms'''
 
+import numpy as np
+
 __metaclass__ = type
 
 class Centroid:
@@ -55,3 +57,23 @@
             centroids[i].add(instance)
 
     return centroids
+
+def spectralClustering(similarityMatrix,k):	
+	'''Spectral Clustering algorithm'''
+	n = len(similarityMatrix)
+	# create Laplacian matrix
+	rowsum = np.sum(similarityMatrix,axis=0)
+	D = np.diag(1 / np.sqrt(rowsum))
+	I = np.identity(n)
+	L = I - np.dot(D,np.dot(similarityMatrix,D))
+	# compute eigenvectors of L
+	U,sigma,V = np.linalg.svd(L)
+	# create feature vector from k first eigenvectors
+	# by stacking eigenvectors as columns
+	features = np.array(V[:k]).T
+	# k-means
+	from scipy.cluster.vq import kmeans, whiten, vq
+	features = whiten(features)
+	centroids,distortion = kmeans(features,k,iter=20) # default iter = 20
+	code,distance = vq(features,centroids) # code starting from 0 (represent first cluster) to k-1 (last cluster)
+	return code,sigma	
--- a/python/tests/indicators.txt	Fri Dec 21 18:33:36 2012 -0500
+++ b/python/tests/indicators.txt	Sat Jan 26 19:02:25 2013 -0500
@@ -4,17 +4,20 @@
 >>> indic1 = TemporalIndicator('bla', [0,3,-4], TimeInterval(4,6))
 >>> indic1.empty()
 False
->>> indic1[5]
+>>> indic1.valueAtInstant(5)
 3
->>> indic1[3]
+>>> indic1.valueAtInstant(3)
+>>> indic1[1]
+3
+>>> indic1[5]
 >>> [v for v in indic1]
 [0, 3, -4]
 >>> indic1 = TemporalIndicator('bla', {2:0,4:3,5:-5})
->>> indic1[4]
+>>> indic1.valueAtInstant(4)
 3
->>> indic1[3]
->>> [v for v in indic1]
-[0, 3, -5]
+>>> indic1.valueAtInstant(3)
+>>> indic1[2]
+-5
 
 >>> t1 = Trajectory([[0.5,1.5,2.5],[0.5,3.5,6.5]])
 >>> indicatorMap([1,2,3], t1, 1)
--- a/python/tests/utils.txt	Fri Dec 21 18:33:36 2012 -0500
+++ b/python/tests/utils.txt	Sat Jan 26 19:02:25 2013 -0500
@@ -40,3 +40,11 @@
 71.5...
 >>> values[-1]
 6.0
+
+>>> LCSS(range(5), range(5), 0.1, lambda x,y:abs(x-y))
+5
+>>> LCSS(range(1,5), range(5), 0.1, lambda x,y:abs(x-y))
+4
+>>> LCSS(range(5,10), range(5), 0.1, lambda x,y:abs(x-y))
+0
+
--- a/python/utils.py	Fri Dec 21 18:33:36 2012 -0500
+++ b/python/utils.py	Sat Jan 26 19:02:25 2013 -0500
@@ -165,15 +165,16 @@
 # maths section
 #########################
 
-def LCSS(l1, l2, threshold, distance):
+def LCSS(l1, l2, threshold, distance, delta = float('inf')):
     '''returns the longest common subsequence similarity
-    based on the threshold on distance between two elements of lists l1, l2'''
+    based on the threshold on distance between two elements of lists l1, l2
+    '''
     from numpy import zeros, int as npint
     m = len(l1)
     n = len(l2)
     similarity = zeros((m+1,n+1), dtype = npint)
     for i in xrange(1,m+1):
-        for j in xrange(1,n+1):
+        for j in xrange(max(1,i-delta),min(n+1,i+delta)):
             if distance(l1[i-1], l2[j-1])<threshold:
                 similarity[i][j] = similarity[i-1][j-1]+1
             else: