Mercurial > hg > camir-aes2014
comparison core/magnatagatune/MTTMixedFeatureGenreBasicSmPCA.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 MTTMixedFeatureGenreBasicSmPCA < MTTAudioFeature & handle | |
6 | |
7 properties(Constant = true) | |
8 | |
9 my_revision = str2double(substr('$Rev$', 5, -1)); | |
10 end | |
11 | |
12 properties | |
13 | |
14 % --- | |
15 % Set default parameters | |
16 % --- | |
17 my_basetype = 'MTTMixedFeatureGenreBasicSm'; | |
18 | |
19 my_params = MTTAudioFeature.inherited_params(... | |
20 'MTTMixedFeatureGenreBasicSm', ... | |
21 'min_pca_var', 0, ... % % fraction of variance to keep | |
22 'max_pca_coeffs', 0, ...% max. number of final coefficients | |
23 'norm_pre_pca', 1, ...% normalise pca coefficients after transformation | |
24 'norm_post_pca', 1 ... | |
25 ); | |
26 end | |
27 % --- | |
28 % member functions | |
29 % --- | |
30 methods | |
31 | |
32 % --- | |
33 % constructor: pointer to feature in database | |
34 % --- | |
35 function feature = MTTMixedFeatureGenreBasicSmPCA(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 = 'MTTMixedFeatureGenreBasicSmPCA'; | |
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 basef.finalise(); | |
93 X = basef.vector(); | |
94 | |
95 % check dataset dimension | |
96 if numel(features) < basef.dim; | |
97 | |
98 error ('Not enough feature vectors for PCA calculation. need %d samples', ... | |
99 basef.dim); | |
100 end | |
101 | |
102 % --- | |
103 % NOTE: should the data be normalised and scaled to -1:1 | |
104 % instead of being in a range of 0-1 AND max-min = 1 | |
105 % --- | |
106 if features(1).my_params.norm_pre_pca == 1 | |
107 | |
108 [X, pstd] = mapminmax(X,-1,1); | |
109 common.pca.pre_norm = pstd; | |
110 elseif features(1).my_params.norm_pre_pca == 2 | |
111 | |
112 [X, pstd] = mapstd(X,0,1); | |
113 common.pca.pre_norm = pstd; | |
114 end | |
115 | |
116 | |
117 % --- | |
118 % get and apply the principal component analysis | |
119 % NOTE: the variance percentile is applied here, too. | |
120 % --- | |
121 | |
122 [Y, ps] = processpca(X, 0); | |
123 common.pca.transform = ps; | |
124 | |
125 % --- | |
126 % get cumulative sum of variance, and decide on cutoff | |
127 % point | |
128 % --- | |
129 v = cumsum(var(Y')); | |
130 v = v / max(v); | |
131 common.pca.transform.varpart = v; | |
132 | |
133 if features(1).my_params.min_pca_var > 0 | |
134 | |
135 min_pca_idx = find(v >= features(1).my_params.min_pca_var,1, 'first'); | |
136 | |
137 % save into pca structure | |
138 common.pca.transform.yrows = min_pca_idx; | |
139 | |
140 end | |
141 | |
142 % normalise pca values after processing | |
143 if features(1).my_params.norm_post_pca | |
144 | |
145 [Y,pmm] = mapminmax(Y,0,1); | |
146 common.pca.post_norm = pmm; | |
147 | |
148 end | |
149 | |
150 % --- | |
151 % set common feature values for mixed features | |
152 % --- | |
153 features(1).my_db.set_common(common); | |
154 | |
155 % save the transformed features straight away! | |
156 features.finalise(Y); | |
157 end | |
158 | |
159 function finalise(feature, final) | |
160 % applies a final transformation and | |
161 % collects the information of this feature within a single vector | |
162 % see info for types in specific dimensions | |
163 | |
164 % determine size | |
165 if feature(1).my_params.max_pca_coeffs > 0 | |
166 | |
167 max_size = min(feature(1).common.pca.transform.yrows, ... | |
168 feature(1).my_params.max_pca_coeffs); | |
169 else | |
170 | |
171 max_size = feature(1).common.pca.transform.yrows; | |
172 end | |
173 | |
174 | |
175 % prepare information | |
176 info = {'PCA'}; | |
177 if isfield(feature(1).common.pca.transform, 'varpart') | |
178 info(2:max_size) = num2cell(feature(1).common.pca.transform.varpart(2:max_size)); | |
179 else | |
180 info(2:max_size) = num2cell(2:max_size); | |
181 end | |
182 | |
183 | |
184 % check if features have been finalised already | |
185 if nargin == 2 && isempty(final) | |
186 | |
187 % the final vector etc already are set to zero; | |
188 return; | |
189 | |
190 elseif nargin == 2 && (numel(feature) == size(final, 2)) | |
191 | |
192 for i = 1:numel(feature) | |
193 | |
194 % save final vector and description | |
195 feature(i).data.final.vector = final(1:max_size,i); | |
196 feature(i).data.final.dim = max_size; | |
197 feature(i).data.final.vector_info.labels = info; | |
198 end | |
199 | |
200 else | |
201 % features have to be transformed first | |
202 % --- | |
203 % TODO: this code remains untested | |
204 % --- | |
205 | |
206 % check for neccesary parameters | |
207 if isempty(feature(1).my_db.commondb) | |
208 | |
209 error('Define the global transformation first') | |
210 return; | |
211 end | |
212 | |
213 | |
214 for i = 1:numel(feature) | |
215 | |
216 % check for neccesary parameters | |
217 if isempty(feature(i).my_db.commondb) | |
218 | |
219 error('Define the global transformation first') | |
220 end | |
221 | |
222 % --- | |
223 % get feature vector and apply transformation | |
224 % --- | |
225 X = feature(i).data.basefeat.vector(); | |
226 | |
227 % --- | |
228 % apply normalisation used for removing mean | |
229 % in training data | |
230 % --- | |
231 if feature(1).my_params.norm_pre_pca == 1 | |
232 | |
233 X = mapminmax('apply', X, feature(1).common.pca.pre_norm); | |
234 elseif feature(1).my_params.norm_pre_pca == 2 | |
235 | |
236 X = mapstd('apply', X, feature(1).common.pca.pre_norm); | |
237 end | |
238 | |
239 % apply PCA transform | |
240 vec = processpca('apply', X, feature(1).common.pca.transform); | |
241 | |
242 % normalise pca values after transformation | |
243 if feature(1).my_params.norm_post_pca | |
244 | |
245 vec = mapminmax('apply', vec,... | |
246 feature(1).common.pca.post_norm); | |
247 end | |
248 | |
249 % --- | |
250 % cut vector to final size. | |
251 % NOTE: this should be done before | |
252 % transformation to reduce computation time | |
253 % --- | |
254 vec = vec(1:max_size); | |
255 | |
256 % save final vector and description | |
257 feature(i).data.final.vector = vec; | |
258 feature(i).data.final.dim = numel(vec); | |
259 feature(i).data.final.vector_info.labels = info; | |
260 end | |
261 end | |
262 end | |
263 | |
264 end | |
265 end |