Mercurial > hg > camir-aes2014
comparison core/magnatagatune/MTTMixedFeatureStober11GenrePCA.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:e9a9cd732c1e |
---|---|
1 % -- | |
2 % This class loads and hanles the aufdio features included with the MTT | |
3 % Library | |
4 % --- | |
5 classdef MTTMixedFeatureStober11GenrePCA < MTTAudioFeature & handle | |
6 | |
7 properties(Constant = true) | |
8 | |
9 my_revision = str2double(substr('$Rev: 457 $', 5, -1)); | |
10 end | |
11 | |
12 properties | |
13 | |
14 % --- | |
15 % Set default parameters | |
16 % --- | |
17 my_basetype = 'MTTMixedFeatureStober11Genre'; | |
18 | |
19 my_params = MTTAudioFeature.inherited_params(... | |
20 'MTTMixedFeatureStober11Genre', ... | |
21 'min_pca_var', 0, ... % [0-1], def. 0 fraction of variance to keep | |
22 'max_pca_coeffs', 0, ...% max. number of final coefficients | |
23 'norm_pre_pca', 1, ... | |
24 'norm_post_pca', 1 ...% normalise pca coefficients after transformation | |
25 ); | |
26 end | |
27 % --- | |
28 % member functions | |
29 % --- | |
30 methods | |
31 | |
32 % --- | |
33 % constructor: pointer to feature in database | |
34 % --- | |
35 function feature = MTTMixedFeatureStober11GenrePCA(varargin) | |
36 | |
37 feature = feature@MTTAudioFeature(varargin{:}); | |
38 end | |
39 | |
40 % --- | |
41 % load feature data from xml file | |
42 % --- | |
43 function data = extract(feature, clip) | |
44 % load feature data by parsing xml | |
45 | |
46 global globalvars; | |
47 | |
48 % --- | |
49 % we extract the base features, and save | |
50 % the pointers to these. | |
51 % the main work is then done in the define_global_transf | |
52 % and finalise functions. | |
53 % --- | |
54 data.basefeat = clip.features(feature.my_basetype,... | |
55 feature.my_params); | |
56 | |
57 % save info data | |
58 data.info.type = class(feature); | |
59 data.info.owner_id = clip.id; | |
60 data.info.creatorrev = feature.my_revision; | |
61 | |
62 % save param data | |
63 data.info.params = feature.my_params; | |
64 | |
65 % prepare field for final features | |
66 data.final.vector = []; | |
67 data.final.dim = 0; | |
68 data.final.vector_info.labels = {}; | |
69 end | |
70 | |
71 function define_global_transform(features) | |
72 | |
73 if numel(features) == 1 | |
74 error ('Insert feature array for this method'); | |
75 end | |
76 | |
77 % --- | |
78 % We collect all the relevant genretag | |
79 % features and get the transform on this basis. | |
80 % --- | |
81 for i = 1:numel(features) | |
82 basef(i) = features(i).data.basefeat; | |
83 end | |
84 | |
85 % call the features own transsform function | |
86 basef.define_global_transform(); | |
87 | |
88 % --- | |
89 % finalise the basic features, and | |
90 % get the feature vectors; | |
91 % --- | |
92 X = basef.vector(); | |
93 | |
94 % check dataset dimension | |
95 if numel(features) < basef.dim; | |
96 | |
97 error ('Not enough feature vectors for PCA calculation. need %d samples', ... | |
98 basef.dim); | |
99 end | |
100 | |
101 % --- | |
102 % NOTE: should the data be normalised and scaled to -1:1 | |
103 % instead of being in a range of 0-1 AND max-min = 1 | |
104 % --- | |
105 if features(1).my_params.norm_pre_pca == 1 | |
106 | |
107 [X, pstd] = mapminmax(X,-1,1); | |
108 common.pca.pre_norm = pstd; | |
109 elseif features(1).my_params.norm_pre_pca == 2 | |
110 | |
111 [X, pstd] = mapstd(X,0,1); | |
112 common.pca.pre_norm = pstd; | |
113 end | |
114 | |
115 | |
116 % --- | |
117 % get and apply the principal component analysis | |
118 % NOTE: the variance percentile is applied here, too. | |
119 % --- | |
120 | |
121 [Y, ps] = processpca(X, 0); | |
122 common.pca.transform = ps; | |
123 | |
124 % --- | |
125 % get cumulative sum of variance, and decide on cutoff | |
126 % point | |
127 % --- | |
128 v = cumsum(var(Y')); | |
129 v = v / max(v); | |
130 common.pca.transform.varpart = v; | |
131 | |
132 if features(1).my_params.min_pca_var > 0 | |
133 | |
134 min_pca_idx = find(v >= features(1).my_params.min_pca_var,1, 'first'); | |
135 | |
136 % save into pca structure | |
137 common.pca.transform.yrows = min_pca_idx; | |
138 | |
139 end | |
140 | |
141 % normalise pca values after processing | |
142 if features(1).my_params.norm_post_pca | |
143 | |
144 [Y,pmm] = mapminmax(Y,0,1); | |
145 common.pca.post_norm = pmm; | |
146 | |
147 end | |
148 | |
149 % --- | |
150 % set common feature values for mixed features | |
151 % --- | |
152 features(1).my_db.set_common(common); | |
153 | |
154 % save the transformed features straight away! | |
155 features.finalise(Y); | |
156 end | |
157 | |
158 function finalise(feature, final) | |
159 % applies a final transformation and | |
160 % collects the information of this feature within a single vector | |
161 % see info for types in specific dimensions | |
162 | |
163 % determine size | |
164 if feature(1).my_params.max_pca_coeffs > 0 | |
165 | |
166 max_size = min(feature(1).common.pca.transform.yrows, ... | |
167 feature(1).my_params.max_pca_coeffs); | |
168 else | |
169 | |
170 max_size = feature(1).common.pca.transform.yrows; | |
171 end | |
172 | |
173 | |
174 % prepare information | |
175 info = {'PCA'}; | |
176 if isfield(feature(1).common.pca.transform, 'varpart') | |
177 info(2:max_size) = num2cell(feature(1).common.pca.transform.varpart(2:max_size)); | |
178 else | |
179 info(2:max_size) = num2cell(2:max_size); | |
180 end | |
181 | |
182 | |
183 % check if features have been finalised already | |
184 if nargin == 2 && isempty(final) | |
185 | |
186 % the final vector etc already are set to zero; | |
187 return; | |
188 | |
189 elseif nargin == 2 && (numel(feature) == size(final, 2)) | |
190 | |
191 for i = 1:numel(feature) | |
192 | |
193 % save final vector and description | |
194 feature(i).data.final.vector = final(1:max_size,i); | |
195 feature(i).data.final.dim = max_size; | |
196 feature(i).data.final.vector_info.labels = info; | |
197 end | |
198 | |
199 else | |
200 % features have to be transformed first | |
201 % --- | |
202 % TODO: this code remains untested | |
203 % --- | |
204 | |
205 % check for neccesary parameters | |
206 if isempty(feature(1).my_db.commondb) | |
207 | |
208 error('Define the global transformation first') | |
209 return; | |
210 end | |
211 | |
212 | |
213 for i = 1:numel(feature) | |
214 | |
215 % check for neccesary parameters | |
216 if isempty(feature(i).my_db.commondb) | |
217 | |
218 error('Define the global transformation first') | |
219 end | |
220 | |
221 % --- | |
222 % get feature vector and apply transformation | |
223 % --- | |
224 X = feature(i).data.basefeat.vector(); | |
225 | |
226 % --- | |
227 % apply normalisation used for removing mean | |
228 % in training data | |
229 % --- | |
230 if feature(1).my_params.norm_pre_pca == 1 | |
231 | |
232 X = mapminmax('apply', X, feature(1).common.pca.pre_norm); | |
233 elseif feature(1).my_params.norm_pre_pca == 2 | |
234 | |
235 X = mapstd('apply', X, feature(1).common.pca.pre_norm); | |
236 end | |
237 | |
238 % apply PCA transform | |
239 vec = processpca('apply', X, feature(1).common.pca.transform); | |
240 | |
241 % normalise pca values after transformation | |
242 if feature(1).my_params.norm_post_pca | |
243 | |
244 vec = mapminmax('apply', vec,... | |
245 feature(1).common.pca.post_norm); | |
246 end | |
247 | |
248 % --- | |
249 % cut vector to final size. | |
250 % NOTE: this should be done before | |
251 % transformation to reduce computation time | |
252 % --- | |
253 vec = vec(1:max_size); | |
254 | |
255 % save final vector and description | |
256 feature(i).data.final.vector = vec; | |
257 feature(i).data.final.dim = numel(vec); | |
258 feature(i).data.final.vector_info.labels = info; | |
259 end | |
260 end | |
261 end | |
262 | |
263 end | |
264 end |