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