-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
27 changed files
with
3,492 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
Installation | ||
------------------------------------------ | ||
|
||
First build with | ||
$ python setup.py build | ||
then install with | ||
$ python setup.py install | ||
|
||
|
||
|
||
Deps | ||
----------------------------------------- | ||
|
||
* Python 2.6 or above | ||
* Numpy > 1.1.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
yeps-clustering-libs are some libs for yeps tools. | ||
See INSTALL for installation |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from iodata import * | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
__all__ = ['load_csv', 'LoadCSVError', 'save_csv', 'SaveCSVError'] | ||
|
||
import csv | ||
import numpy as np | ||
|
||
class LoadCSVError(Exception): | ||
""" | ||
CSV reading error | ||
""" | ||
pass | ||
|
||
|
||
class SaveCSVError(Exception): | ||
""" | ||
CSV saving error | ||
""" | ||
pass | ||
|
||
|
||
def load_csv(fn, delim='|'): | ||
""" | ||
Function that loads a csv file | ||
Input: fn, [delim] | ||
Output: x: np.array with the time data | ||
y: np.array with the time series data | ||
header: header of the csv file | ||
title: the column 0,0 of the csv file | ||
""" | ||
f = open(fn, 'r') | ||
csvr = csv.reader(f, delimiter=delim) | ||
try: | ||
content = [row for row in csvr] | ||
nc = len(content[0]) | ||
title = content[0][0] | ||
headerv = [content[i][0] for i in range(1, len(content))] | ||
headerh = content[0][1::] | ||
y = np.array([content[i][1::] for i in range(1, len(headerv) + 1)], dtype=np.float) | ||
except: | ||
raise LoadCSVError | ||
else: | ||
return headerh, y, headerv, title | ||
|
||
def save_csv(fn, x, y, header, title="", delim='|'): | ||
""" | ||
Creates a CSV file | ||
""" | ||
rows = [[]] | ||
rows[0].append(title) | ||
rows[0] += [elem for elem in x] | ||
for i, elem in enumerate(header): | ||
rows.append([elem] + [serie for serie in y[i]]) | ||
try: | ||
csvwriter = csv.writer(file(fn, "w"), delimiter=delim) | ||
csvwriter.writerows(rows) | ||
except: | ||
raise SaveCSVErrror | ||
|
||
if __name__ == "__main__": | ||
x, y, header, title = load_csv("/home/fox/svn/trunk/data-management/time-series/huglin.csv") | ||
print y[0][5] | ||
#print header, title | ||
#save_csv("/tmp/prova.csv", x,y,header, title) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
#!/usr/bin/env python | ||
|
||
from numpy import inf | ||
|
||
class DTW: | ||
''' | ||
Implementation of the DTW algorithm, using a recursive function to calculate the minimum path. | ||
The recursive function starts from the left bottom edge of the matrix and calculates recursively the min path for adiacent cells. In each cell it stores the minimum path returned by adiacent cells. The calculation stops when the top right edge is reached by all of the recoursion launched. | ||
Takes two time series as input and returns the minimum path and it's lenght as output (the path is returned only if the pathflag is set to 1) | ||
''' | ||
|
||
def __init__(self, s1, s2): | ||
''' Initilalizing time series ''' | ||
self.s1 = s1 | ||
self.s2 = s2 | ||
|
||
def deriv_calc(self, series): | ||
t = series[0] | ||
for i in range(1,len(series)-1): | ||
t1 = series[i] | ||
series[i] = ((series[i] - t) + ((series[i+1] -t )/2))/2 | ||
t = t1 | ||
series[0] = series[1] - (series[2] - series[1]) | ||
series[-1] = series[-2] - (series[-3] - series[-2]) | ||
return series | ||
|
||
def dist_calc(self, deriv): | ||
''' Calculates the distance between every point of the two time series and stores it into the distance matrix ''' | ||
if deriv == 1: | ||
self.s1 = self.deriv_calc(self.s1) | ||
self.s2 = self.deriv_calc(self.s2) | ||
|
||
self.dist = [] #allocation of the matrix | ||
for i in range(self.s1.__len__()): | ||
self.dist.append([j for j in range(self.s2.__len__())]) | ||
for i in enumerate(self.s1): #filling the matrix with distances | ||
for j in enumerate(self.s2): | ||
self.dist[i[0]][j[0]] = ((i[0] - j[0])**2 + (i[1] - j[1])**2) | ||
def short_path(self, pathflag): | ||
''' Calculates the minimum path in the distance matrix, recursively with memorizization. ''' | ||
self.mem = [] # list for storing already-calculated paths | ||
for i in range(self.s1.__len__()): | ||
self.mem.append([-1 for j in range(self.s2.__len__())]) #initializing it to -1 (-1 means not calculated yet) | ||
def next(x,y): #recursive function | ||
if x == self.s1.__len__() -1 and y == self.s2.__len__()-1: #if we've reached the end, return. | ||
return self.dist[x][y] | ||
try: | ||
if self.mem[x][y] != -1: #if the value has been already calculated for this cell return it without recomputing it | ||
return self.mem[x][y] | ||
except IndexError: # if x or y exceed the matrix bounds return inf | ||
return inf | ||
a = next(x+1,y); #calculate min path for near cells | ||
b = next(x+1, y+1); | ||
c = next(x, y+1); | ||
self.mem[x][y] = min(a,b,c) + self.dist[x][y] #sum the value of this cell and the minimum value of near cells, store and return it | ||
return self.mem[x][y] | ||
|
||
a = next(0,0) | ||
if pathflag != 1: return a | ||
|
||
pathlist = [] | ||
x = 0 | ||
y = 0 | ||
while 1: | ||
pathlist.append([x,y]) | ||
if (x == self.s1.__len__()-1) and (y == self.s2.__len__()-1): break | ||
if x == self.s1.__len__()-1: | ||
y += 1 | ||
continue | ||
if y == self.s2.__len__()-1: | ||
x +=1 | ||
continue | ||
if (self.mem[x+1][y+1] < self.mem[x][y+1]) and (self.mem[x+1][y+1] < self.mem[x+1][y]): | ||
x += 1 | ||
y += 1 | ||
continue | ||
if (self.mem[x+1][y] < self.mem[x][y+1]) and (self.mem[x+1][y] < self.mem[x+1][y+1]): | ||
x += 1 | ||
continue | ||
y += 1; | ||
|
||
return [a, pathlist]; | ||
|
||
def run(self, deriv = 0, pathflag = 0): | ||
''' Runs the algorithm and returns results | ||
If pathflag is 1 it returns a list containing the min distance an a list of point representing the path, else it returns only the distance ''' | ||
self.dist_calc(deriv) | ||
return self.short_path(pathflag) | ||
|
||
|
||
|
||
if __name__ == "__main__": | ||
a = DTW([1.,2,1,-4,7,3,2,9],[8,5.,7,9,9,1,2,3]) | ||
b = a.run(1,1) | ||
print b[0] | ||
print b[1] | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
from kmedoid import Medoid | ||
|
||
__all__ = [] | ||
__all__ += kmedoid.__all__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import numpy | ||
import dtw_cpu | ||
class Dist: | ||
try: | ||
import dtw_gpu | ||
pu="GPU" | ||
except ImportError: | ||
pu="CPU" | ||
def __init__(self, matrix, mode="dtw", fast=False, radius=20): | ||
''' __init__(self, matrix, mode="dtw", fast=False, radius=20) | ||
<calls others modules for the actual calculation, checks if CUDA is present an organize | ||
computations> | ||
Input Parameters: | ||
matrix: a matrix containing time series, each row is a timeseries and each | ||
column a point of the time series. | ||
mode: method by which the distance between series is calculated | ||
"dtw" for normal DTW, | ||
"ddtw" for the derivative DTW, | ||
"euclidean" for euclidean distance, | ||
"pearson", for pearson distance | ||
fast: specifies whether to run the FastDTW or not, radius parameter | ||
indicates the accuracy of the calculation, the higher the value, | ||
the more accurate the result. It applies only to the DTW algorithms. | ||
FastDTWs are not implemented on GPU. | ||
radius: see 'fast'. It is suggested to not use more than 100 for this value | ||
ignored if fast is flase. | ||
Returns: | ||
Nothing. | ||
''' | ||
self.matrix=matrix | ||
self.mode=mode | ||
self.fast=fast | ||
self.radius=radius | ||
self.derivative=False | ||
self.euclidean=False | ||
if self.mode=="ddtw": | ||
self.derivative=True | ||
elif self.mode=="euclidean": | ||
self.euclidean=True | ||
else: | ||
pass | ||
if self.pu=="GPU": | ||
self.gpu = self.dtw_gpu._DTW_(self.matrix) | ||
def compute(self, li): | ||
''' compute (self, li): | ||
<Does the actual calculations.> | ||
Input Parameters: | ||
li: list of tuples containg indices of couples of time series between which | ||
distace has to be calculated. Indices refears to matrix passed at the init | ||
func. | ||
Returns: | ||
returns a numpy array containing distance values for each couple passed. Result | ||
are in the order of input. | ||
''' | ||
if self.pu=="GPU": | ||
res=self.gpu.compute_dtw(li) | ||
else: | ||
res=numpy.array([]) | ||
for qui in li: | ||
tmp=dtw_cpu.compute_dtw(self.matrix[qui[0]], self.matrix[qui[1]], self.euclidean, False, self.derivative, self.fast, self.radius) | ||
res = numpy.append(res, numpy.array([tmp])) | ||
return res |
Oops, something went wrong.