1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 import logging
35 import pyvision as pv
36 import numpy
37 from numpy.linalg import svd
38
41
42
43
45 ''' Performs principal components analysis on a set of images, features, or vectors. '''
46
47
48
49 - def __init__(self, center_points=True, one_std=True ):
50 ''' Create a PCA object '''
51 self.logger = logging.getLogger("pyvis")
52 self.features = []
53 self.center_points = center_points
54
55
56
58
59 for key,value in state.iteritems():
60 if key == 'basis':
61
62
63 self.basis = numpy.array(value)
64 continue
65
66 self.__dict__[key] = value
67
68
69
71 ''' Add a feature vector to the analysis. '''
72 feat = self.toVector(feature)
73
74 self.features.append(feat)
75
76
77
79 if isinstance(feature,pv.Image):
80 feat = feature.asMatrix2D().flatten()
81 return feat
82 if isinstance(feature,numpy.ndarray):
83 feat = feature.flatten()
84 return feat
85 raise TypeError("Could not create feature from type: %s"%type(feature))
86
87
88
89 - def train(self, drop_front=None, number=None, energy=None):
90 ''' Compute the PCA basis vectors using the SVD '''
91 self.logger.info("Computing PCA basis vectors.")
92
93
94 features = numpy.array(self.features)
95
96 if self.center_points:
97 self.center = features.mean(axis=0)
98 for i in range(features.shape[0]):
99 features[i,:] -= self.center
100
101
102 features = features.transpose()
103
104 u,d,_ = svd(features,full_matrices=0)
105 if drop_front:
106 u = u[:,drop_front:]
107 d = d[drop_front:]
108
109 if number:
110 u = u[:,:number]
111 d = d[:number]
112 if energy:
113
114 s = 0.0
115 for each in d:
116 s += each*each
117 cutoff = energy * s
118
119
120 s = 0.0
121 for i in range(len(d)):
122 each = d[i]
123 s += each*each
124 if s > cutoff:
125 break
126
127 u = u[:,:i]
128 d = d[:i]
129
130 self.basis = u.transpose()
131 self.values = d
132
133
134
135 del self.features
136
137
138
139 - def project(self, feature, whiten=False):
140 ''' Transform a feature into its low dimentional representation '''
141 feat = self.toVector(feature)
142
143 if self.center_points:
144 feat = feat - self.center
145
146 vec = numpy.dot(self.basis,feat)
147
148 if whiten:
149 vec = vec/numpy.sqrt(self.values)
150
151 return vec
152
153
154
156 ''' return the eigen values for this computation '''
157 feat = numpy.dot(self.basis.transpose(),feat)
158 if self.center_points:
159 feat += self.center
160 return feat
161
162
163
165 ''' return the eigen vectors returned by the computation '''
166 return self.basis
167
168
169
171 ''' return the bases used for transforming features '''
172 return self.values
173
174
175
176