comparison scripts/learn-motion-patterns.py @ 952:a9b2beef0db4

loading and assigning motion patterns works
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Mon, 24 Jul 2017 21:22:18 -0400
parents 2a4f174879dd
children 989917b1ed85
comparison
equal deleted inserted replaced
951:2a4f174879dd 952:a9b2beef0db4
17 parser.add_argument('-n', dest = 'nTrajectories', help = 'number of the object or feature trajectories to load', type = int, default = None) 17 parser.add_argument('-n', dest = 'nTrajectories', help = 'number of the object or feature trajectories to load', type = int, default = None)
18 parser.add_argument('-e', dest = 'epsilon', help = 'distance for the similarity of trajectory points', type = float, required = True) 18 parser.add_argument('-e', dest = 'epsilon', help = 'distance for the similarity of trajectory points', type = float, required = True)
19 parser.add_argument('--metric', dest = 'metric', help = 'metric for the similarity of trajectory points', default = 'cityblock') # default is manhattan distance 19 parser.add_argument('--metric', dest = 'metric', help = 'metric for the similarity of trajectory points', default = 'cityblock') # default is manhattan distance
20 parser.add_argument('-s', dest = 'minSimilarity', help = 'minimum similarity to put a trajectory in a cluster', type = float, required = True) 20 parser.add_argument('-s', dest = 'minSimilarity', help = 'minimum similarity to put a trajectory in a cluster', type = float, required = True)
21 parser.add_argument('-c', dest = 'minClusterSize', help = 'minimum cluster size', type = int, default = None) 21 parser.add_argument('-c', dest = 'minClusterSize', help = 'minimum cluster size', type = int, default = None)
22 parser.add_argument('--learn', dest = 'learn', help = 'learn', action = 'store_true')
22 parser.add_argument('--optimize', dest = 'optimizeCentroid', help = 'recompute centroid at each assignment', action = 'store_true') 23 parser.add_argument('--optimize', dest = 'optimizeCentroid', help = 'recompute centroid at each assignment', action = 'store_true')
23 parser.add_argument('--random', dest = 'randomInitialization', help = 'random initialization of clustering algorithm', action = 'store_true') 24 parser.add_argument('--random', dest = 'randomInitialization', help = 'random initialization of clustering algorithm', action = 'store_true')
24 parser.add_argument('--subsample', dest = 'positionSubsamplingRate', help = 'rate of position subsampling (1 every n positions)', type = int) 25 parser.add_argument('--subsample', dest = 'positionSubsamplingRate', help = 'rate of position subsampling (1 every n positions)', type = int)
25 parser.add_argument('--display', dest = 'display', help = 'display trajectories', action = 'store_true') 26 parser.add_argument('--display', dest = 'display', help = 'display trajectories', action = 'store_true')
26 parser.add_argument('--save-similarities', dest = 'saveSimilarities', help = 'save computed similarities (in addition to prototypes)', action = 'store_true') 27 parser.add_argument('--save-similarities', dest = 'saveSimilarities', help = 'save computed similarities (in addition to prototypes)', action = 'store_true')
27 parser.add_argument('--save-matches', dest = 'saveMatches', help = 'saves the assignments of the objects (not for features) to the prototypes', action = 'store_true') 28 parser.add_argument('--save-matches', dest = 'saveMatches', help = 'saves the assignments of the objects (not for features) to the prototypes', action = 'store_true')
28 #parser.add_argument('--assign', dest = 'assign', help = 'saves the assignments of the objects (not for features) to the prototypes', action = 'store_true') # default is train, but one could want only to assign the objects to the loaded prototypes without learning 29 parser.add_argument('--assign', dest = 'assign', help = 'assigns the objects to the prototypes and saves them (do not use min cluster size as it will discard prototypes at the beginning if the initial cluster is too small)', action = 'store_true')
29 30
30 args = parser.parse_args() 31 args = parser.parse_args()
31 32
32 # use cases 33 # use cases
33 # 1. learn proto from one file, save in same or another (with traj) 34 # 1. learn proto from one file, save in same or another
34 # 2. load proto, load objects, update proto, save proto 35 # 2. load proto, load objects, update proto, save proto
35 # 3. assign objects from one db to proto 36 # 3. assign objects from one db to proto
36 # 4. load objects from several files, save in another -> see metadata: site with view and times 37 # 4. load objects from several files, save in another -> see metadata: site with view and times
37 # 5. keep prototypes, with positions/velocities, in separate db (keep link to original data through filename, type and index) 38 # 5. keep prototypes, with positions/velocities, in separate db (keep link to original data through filename, type and index)
38 39
39 # TODO add possibility to cluster with velocities 40 # TODO add possibility to cluster with velocities
40 # TODO add possibility to start with saved prototypes so that one can incrementally learn from several databases 41 # TODO add possibilite to load all trajectories and use minclustersize
41 # save the objects that match the prototypes 42 # save the objects that match the prototypes
42 # write an assignment function for objects 43 # write an assignment function for objects
43 44
44 trajectoryType = args.trajectoryType 45 trajectoryType = args.trajectoryType
45 prototypeType = args.trajectoryType 46 prototypeType = args.trajectoryType
59 60
60 trajectories = [o.getPositions().asArray().T for o in objects] 61 trajectories = [o.getPositions().asArray().T for o in objects]
61 if args.inputPrototypeDatabaseFilename is not None: 62 if args.inputPrototypeDatabaseFilename is not None:
62 initialPrototypes = storage.loadPrototypesFromSqlite(args.inputPrototypeDatabaseFilename, True) 63 initialPrototypes = storage.loadPrototypesFromSqlite(args.inputPrototypeDatabaseFilename, True)
63 trajectories = [p.getMovingObject().getPositions().asArray().T for p in initialPrototypes]+trajectories 64 trajectories = [p.getMovingObject().getPositions().asArray().T for p in initialPrototypes]+trajectories
64 initialPrototypeIndices = range(len(initialPrototypes)) 65 if len(initialPrototypes) > 0:
66 initialPrototypeIndices = range(len(initialPrototypes))
67 else:
68 initialPrototypeIndices = None
65 else: 69 else:
66 initialPrototypes = [] 70 initialPrototypes = []
67 initialPrototypeIndices = None 71 initialPrototypeIndices = None
68 72
69 lcss = utils.LCSS(metric = args.metric, epsilon = args.epsilon) 73 lcss = utils.LCSS(metric = args.metric, epsilon = args.epsilon)
70 nTrajectories = len(trajectories) 74 nTrajectories = len(trajectories)
71 75
72 similarities = -np.ones((nTrajectories, nTrajectories)) 76 similarities = -np.ones((nTrajectories, nTrajectories))
77 similarityFunc = lambda x,y : lcss.computeNormalized(x, y)
73 # the next line can be called again without reinitializing similarities 78 # the next line can be called again without reinitializing similarities
74 prototypeIndices, labels = ml.prototypeCluster(trajectories, similarities, args.minSimilarity, lambda x,y : lcss.computeNormalized(x, y), args.minClusterSize, args.optimizeCentroid, args.randomInitialization, args.inputPrototypeDatabaseFilename is not None, initialPrototypeIndices) # assignment is done only if working on the same database, otherwise the matchings will not compare and one has to to matchings on a large scale at once 79 if args.learn:
80 prototypeIndices = ml.prototypeCluster(trajectories, similarities, args.minSimilarity, similarityFunc, args.minClusterSize, args.optimizeCentroid, args.randomInitialization, initialPrototypeIndices)
81 # assignment is done if explicitly passed as argument or if working on the same database (starting prototypes from scratch and assigning the )
82 # (otherwise the matchings will not compare and one has to to matchings on a large scale at once)
75 83
76 clusterSizes = ml.computeClusterSizes(labels, prototypeIndices, -1) 84 if args.assign:
77 print(clusterSizes) 85 prototypeIndices, labels = ml.assignToPrototypeClusters(trajectories, prototypeIndices, similarities, args.minSimilarity, similarityFunc, args.minClusterSize)
86 clusterSizes = ml.computeClusterSizes(labels, prototypeIndices, -1)
87 print(clusterSizes)
78 88
79 prototypes = [] 89 if args.learn or args.assign:
80 for i in prototypeIndices: 90 prototypes = []
81 if i<len(initialPrototypes): 91 for i in prototypeIndices:
82 initialPrototypes[i].nMatchings = 0 92 if args.assign:
83 prototypes.append(initialPrototypes[i]) 93 nMatchings = clusterSizes[i]
94 else:
95 nMatchings = 0
96 if i<len(initialPrototypes):
97 initialPrototypes[i].nMatchings += nMatchings
98 prototypes.append(initialPrototypes[i])
99 else:
100 prototypes.append(moving.Prototype(args.databaseFilename, objects[i-len(initialPrototypes)].getNum(), prototypeType, nMatchings))
101
102 if args.outputPrototypeDatabaseFilename is None:
103 outputPrototypeDatabaseFilename = args.databaseFilename
84 else: 104 else:
85 if args.inputPrototypeDatabaseFilename is None: 105 outputPrototypeDatabaseFilename = args.outputPrototypeDatabaseFilename
86 nmatchings = clusterSizes[i] 106 if args.inputPrototypeDatabaseFilename == args.outputPrototypeDatabaseFilename:
87 else: 107 storage.deleteFromSqlite(args.outputPrototypeDatabaseFilename, 'prototype')
88 nmatchings = 0 108 storage.savePrototypesToSqlite(outputPrototypeDatabaseFilename, prototypes)
89 prototypes.append(moving.Prototype(args.databaseFilename, objects[i].getNum(), prototypeType, nmatchings))
90 109
91 if args.outputPrototypeDatabaseFilename is None: 110 if args.saveSimilarities:
92 outputPrototypeDatabaseFilename = args.databaseFilename 111 # todo save trajectories and prototypes
112 np.savetxt(utils.removeExtension(args.databaseFilename)+'-prototype-similarities.txt.gz', similarities, '%.4f')
113
114 labelsToProtoIndices = {protoId: i for i, protoId in enumerate(prototypeIndices)}
115 if args.assign and args.saveMatches: # or args.assign
116 # save in the db that contained originally the data
117 # retirer les assignations anterieures?
118 storage.savePrototypeAssignmentsToSqlite(args.databaseFilename, objects, [labelsToProtoIndices[l] for l in labels], prototypes)
119
120 if args.display and args.assign:
121 from matplotlib.pyplot import figure, show, axis
122 figure()
123 for i,o in enumerate(objects):
124 if i not in prototypeIndices:
125 if labels[i] < 0:
126 o.plot('kx')
127 else:
128 o.plot(utils.colors[labels[i]])
129 for i in prototypeIndices:
130 objects[i].plot(utils.colors[i]+'o')
131 axis('equal')
132 show()
93 else: 133 else:
94 outputPrototypeDatabaseFilename = args.outputPrototypeDatabaseFilename 134 print('Not learning nor assigning: doing nothing')
95 storage.savePrototypesToSqlite(outputPrototypeDatabaseFilename, prototypes)
96
97 if args.saveSimilarities:
98 np.savetxt(utils.removeExtension(args.databaseFilename)+'-prototype-similarities.txt.gz', similarities, '%.4f')
99
100 labelsToProtoIndices = {protoId: i for i, protoId in enumerate(prototypeIndices)}
101 if args.saveMatches: # or args.assign
102 # save in the db that contained originally the data
103 # retirer les assignations anterieures?
104 storage.savePrototypeAssignmentsToSqlite(args.databaseFilename, objects, [labelsToProtoIndices[l] for l in labels], prototypes)
105
106 if args.display:
107 from matplotlib.pyplot import figure, show, axis
108 figure()
109 for i,o in enumerate(objects):
110 if i not in prototypeIndices:
111 if labels[i] < 0:
112 o.plot('kx')
113 else:
114 o.plot(utils.colors[labels[i]])
115 for i in prototypeIndices:
116 objects[i].plot(utils.colors[i]+'o')
117 axis('equal')
118 show()