annotate toolboxes/MIRtoolbox1.3.2/MIRToolbox/mirmap.m @ 0:cc4b1211e677 tip

initial commit to HG from Changeset: 646 (e263d8a21543) added further path and more save "camirversion.m"
author Daniel Wolff
date Fri, 19 Aug 2016 13:07:06 +0200
parents
children
rev   line source
Daniel@0 1 function res = mirmap(predics_ref,ratings_ref,dist,alpha,delta)
Daniel@0 2 % mirmap(predictors_file, ratings_file) performs a statistical mapping
Daniel@0 3 % between ratings associated to a set of audio recordings, and a set of
Daniel@0 4 % variables computed for the same set of audio recordings. It might be
Daniel@0 5 % useful in particular when the set of predictors is large and diverse.
Daniel@0 6
Daniel@0 7 if nargin<3
Daniel@0 8 dist = 'lse';
Daniel@0 9 end
Daniel@0 10 if nargin<4
Daniel@0 11 alpha = 1;
Daniel@0 12 end
Daniel@0 13 if nargin<5
Daniel@0 14 delta = .00001;
Daniel@0 15 end
Daniel@0 16
Daniel@0 17 crosscor_thres = .6;
Daniel@0 18
Daniel@0 19 dist = str2func(dist);
Daniel@0 20
Daniel@0 21 predics = import(predics_ref);
Daniel@0 22 ratings = import(ratings_ref);
Daniel@0 23
Daniel@0 24 predics = normalize(predics,dist,alpha,delta,'predictions',predics_ref);
Daniel@0 25 if isempty(predics.data)
Daniel@0 26 res = [];
Daniel@0 27 return
Daniel@0 28 end
Daniel@0 29
Daniel@0 30 ratings = normalize(ratings,dist,alpha,delta,'ratings',ratings_ref);
Daniel@0 31
Daniel@0 32 res = map(predics,ratings,crosscor_thres);
Daniel@0 33
Daniel@0 34
Daniel@0 35 %%
Daniel@0 36 function output = import(ref)
Daniel@0 37 output.data = [];
Daniel@0 38 output.fields = {};
Daniel@0 39 output.normal = [];
Daniel@0 40 if not(iscell(ref))
Daniel@0 41 ref = {ref};
Daniel@0 42 end
Daniel@0 43 for i = 1:length(ref)
Daniel@0 44 if not(iscell(ref{i}))
Daniel@0 45 ref{i} = {ref{i}};
Daniel@0 46 end
Daniel@0 47 if ischar(ref{i}{1})
Daniel@0 48 for j = 1:length(ref{i})
Daniel@0 49 importj = importdata(ref{i}{j});
Daniel@0 50 if not(isstruct(importj))
Daniel@0 51 imp = importj;
Daniel@0 52 importj = struct;
Daniel@0 53 importj.data = imp;
Daniel@0 54 for k = 1:size(imp,2)
Daniel@0 55 importj.textdata{k} = [ref{i}{j},'_',num2str(k)];
Daniel@0 56 end
Daniel@0 57 end
Daniel@0 58 if j == 1
Daniel@0 59 import = importj;
Daniel@0 60 else
Daniel@0 61 [c ia ib] = intersect(import.textdata(1,2:end),...
Daniel@0 62 importj.textdata(1,2:end));
Daniel@0 63 import.textdata = [import.textdata(:,[1 ia+1]);...
Daniel@0 64 importj.textdata(2:end,[1 ib+1])];
Daniel@0 65 import.data = [import.data(:,ia);importj.data(:,[1 ib+1])];
Daniel@0 66 end
Daniel@0 67 end
Daniel@0 68 output.data = [output.data import.data];
Daniel@0 69 nbfields = size(import.data,2);
Daniel@0 70 field = import.textdata(1,:);
Daniel@0 71 field = field(end-nbfields+1 : end);
Daniel@0 72 output.fields = [output.fields field];
Daniel@0 73 else
Daniel@0 74 output.data = [output.data ref{i}{1}];
Daniel@0 75 for j = 1:size(ref{i},2)
Daniel@0 76 output.fields = [output.fields num2str(j)];
Daniel@0 77 end
Daniel@0 78 end
Daniel@0 79 end
Daniel@0 80 ndata = size(output.data,2);
Daniel@0 81 output.normal = NaN(1,ndata);
Daniel@0 82 warning('off','stats:lillietest:OutOfRangeP');
Daniel@0 83 for i = 1:ndata
Daniel@0 84 data = output.data(:,i);
Daniel@0 85 data = data(~isnan(data));
Daniel@0 86 if length(data) < 4
Daniel@0 87 output.normal(i) = 0;
Daniel@0 88 else
Daniel@0 89 output.normal(i) = ~lillietest(data);
Daniel@0 90 end
Daniel@0 91 end
Daniel@0 92
Daniel@0 93
Daniel@0 94 %%
Daniel@0 95 function res = map(predics,ratings,crosscor_thres)
Daniel@0 96 nbrates = size(ratings.data,2);
Daniel@0 97 nbpreds = size(predics.data,2);
Daniel@0 98 res.normal.cor = NaN(nbpreds,nbrates);
Daniel@0 99 res.normal.pval = NaN(nbpreds,nbrates);
Daniel@0 100
Daniel@0 101 res.significant = cell(nbrates,1);
Daniel@0 102 for j = 1:nbrates
Daniel@0 103 figure
Daniel@0 104 set(gca,'YDir','reverse')
Daniel@0 105 hold on
Daniel@0 106 select = []; % list of selected features
Daniel@0 107 for i = 1:nbpreds
Daniel@0 108 if ~predics.normal(i)
Daniel@0 109 res.normal.cor(i,j) = NaN;
Daniel@0 110 continue
Daniel@0 111 end
Daniel@0 112 [R P] = corrcoef(predics.data(:,i),ratings.data(:,j),...
Daniel@0 113 'rows','pairwise');
Daniel@0 114 res.normal.pval(i,j) = P(2);
Daniel@0 115 if P(2)<.05 % statistically significant
Daniel@0 116 select(end+1) = i; % included into the list of selected features
Daniel@0 117 res.normal.cor(i,j) = R(2);
Daniel@0 118 else
Daniel@0 119 res.normal.cor(i,j) = NaN;
Daniel@0 120 end
Daniel@0 121 end
Daniel@0 122 %res.inter(:,:,j) = corrcoef(predics.data,'rows','pairwise');
Daniel@0 123
Daniel@0 124 [unused index] = sort(abs(res.normal.cor(select,j)),'descend');
Daniel@0 125 index = select(index);
Daniel@0 126 res.significant{j}.cor = res.normal.cor(index,j);
Daniel@0 127 res.significant{j}.pval = res.normal.pval(index,j);
Daniel@0 128 res.significant{j}.inter = corrcoef(predics.data(:,index),'rows','pairwise');
Daniel@0 129 %res.inter(index,index,j);
Daniel@0 130 res.significant{j}.fields = {predics.fields{index}};
Daniel@0 131 res.significant{j}.alpha = predics.alpha(index);
Daniel@0 132 res.significant{j}.lambda = predics.lambda(index);
Daniel@0 133 k = 0;
Daniel@0 134 corfields = {};
Daniel@0 135 corbest = [];
Daniel@0 136 for i = 1:length(select)
Daniel@0 137 inter = max(abs(res.significant{j}.inter(1:i-1,i)));
Daniel@0 138 if i == 1 || inter < crosscor_thres
Daniel@0 139 % Features sufficiently independent to the better scoring ones
Daniel@0 140 % are selected
Daniel@0 141 k = k+1;
Daniel@0 142 if i == 1
Daniel@0 143 own = 1;
Daniel@0 144 else
Daniel@0 145 own = 1-inter;
Daniel@0 146 end
Daniel@0 147 col = res.significant{j}.pval(i);
Daniel@0 148 x1 = min(0,res.significant{j}.cor(i));
Daniel@0 149 y1 = k-own/2;
Daniel@0 150 x2 = x1+abs(res.significant{j}.cor(i));
Daniel@0 151 y2 = k+own/2;
Daniel@0 152 pcolor([x1 x1;x2 x2],[y1 y2;y1 y2],[col col;col col])
Daniel@0 153 corbest = [corbest i];
Daniel@0 154 corfields = [corfields res.significant{j}.fields{i}];
Daniel@0 155 i
Daniel@0 156 res.significant{j}.fields{i}
Daniel@0 157 res.significant{j}.cor(i)
Daniel@0 158 inter
Daniel@0 159 end
Daniel@0 160 end
Daniel@0 161
Daniel@0 162 set(gca,'YTick',1:k,'YTickLabel',corfields)%,...
Daniel@0 163 % 'Position',[.4 .11 .5 .815])
Daniel@0 164 colorbar
Daniel@0 165 grid on
Daniel@0 166 title(['Correlation with rating ',ratings.fields{j}])
Daniel@0 167
Daniel@0 168 predata = standardize(predics.data(:,index(corbest))); %% to be put out of the loop
Daniel@0 169 res.best{j}.index = corbest;
Daniel@0 170 res.best{j}.fields = {res.significant{j}.fields{corbest}};
Daniel@0 171 res.best{j}.alpha = res.significant{j}.alpha(corbest);
Daniel@0 172 res.best{j}.lambda = res.significant{j}.lambda(corbest);
Daniel@0 173 if isempty(select)
Daniel@0 174 close
Daniel@0 175 elseif length(corbest)>1
Daniel@0 176 display('****************************************')
Daniel@0 177 display(['Regression for rating ',ratings.fields{j}])
Daniel@0 178 ratej = standardize(ratings.data(:,j));
Daniel@0 179 stepwisefit(predata,ratej,'maxiter',10);
Daniel@0 180 [b,se,pval,inmodel,stats,nextstep,history] ...
Daniel@0 181 = stepwisefit(predata,ratej,'maxiter',10,'scale','on');
Daniel@0 182 res.best{j}.fields{find(inmodel)}
Daniel@0 183 %stepwise(predata,ratej,[]);%,.001,.001);
Daniel@0 184 pause
Daniel@0 185 end
Daniel@0 186 end
Daniel@0 187
Daniel@0 188 function x = standardize(x)
Daniel@0 189 %mx = mean(x);
Daniel@0 190 %x = x-repmat(mx,[size(x,1) 1]);
Daniel@0 191 %sx = std(x);
Daniel@0 192 %sx(sx==0) = 1;
Daniel@0 193 %x = x./repmat(sx,[size(x,1) 1]);
Daniel@0 194
Daniel@0 195
Daniel@0 196 %%
Daniel@0 197 function output = normalize(input,dist,alpha,delta,txt,filename)
Daniel@0 198 fields = input.fields;
Daniel@0 199 nbfields = length(fields);
Daniel@0 200 output = input;
Daniel@0 201 h = waitbar(0,['Normalizing ',txt]);
Daniel@0 202 for i = 1:nbfields
Daniel@0 203 waitbar((i-1)/nbfields,h,['Normalizing ',txt,fields{i}]);
Daniel@0 204 d = input.data(:,i);
Daniel@0 205 if length(d(~isnan(d)))>3 && ~input.normal(i)
Daniel@0 206 %figure(1)
Daniel@0 207 %hist(d,round(7.5*log(size(d,1))));
Daniel@0 208 %figure(2)
Daniel@0 209 %normplot(d)
Daniel@0 210
Daniel@0 211 [output.data(:,i) output.alpha(i) output.lambda(i)] = ...
Daniel@0 212 boxcox_search(d,dist,alpha,delta);
Daniel@0 213 %figure(3)
Daniel@0 214 %hist(output.data(:,i),round(7.5*log(size(d,1))));
Daniel@0 215 output.normal(i) = ~lillietest(output.data(:,i),.01);
Daniel@0 216 %figure(4)
Daniel@0 217 %normplot(data(:,i))
Daniel@0 218 end
Daniel@0 219 end
Daniel@0 220 display('Excluded:')
Daniel@0 221 output.fields{~output.normal}
Daniel@0 222 display('..')
Daniel@0 223 output.data(:,~output.normal) = [];
Daniel@0 224 output.fields(~output.normal) = [];
Daniel@0 225 output.normal(~output.normal) = [];
Daniel@0 226 if max(~output.normal)
Daniel@0 227 output.alpha(~output.normal) = [];
Daniel@0 228 output.lambda(~output.normal) = [];
Daniel@0 229 end
Daniel@0 230 %if strcmpi(filename(end-3:end),'.txt')
Daniel@0 231 % filename = filename(1:end-4);
Daniel@0 232 %end
Daniel@0 233 %filename = [filename '.mir.txt'];
Daniel@0 234 %mirexport(filename,output);
Daniel@0 235 close(h);
Daniel@0 236
Daniel@0 237
Daniel@0 238 function [y resalpha lambda] = boxcox_search(x,dist,alpha,delta)
Daniel@0 239 if nargin<2
Daniel@0 240 dist = @lse;
Daniel@0 241 end
Daniel@0 242 if nargin<3
Daniel@0 243 alpha = 0;
Daniel@0 244 end
Daniel@0 245 lambda = -10:.01:10;
Daniel@0 246 if min(x)<0
Daniel@0 247 x = x-min(x);
Daniel@0 248 resalpha = -min(x);
Daniel@0 249 else
Daniel@0 250 resalpha = 0;
Daniel@0 251 end
Daniel@0 252 y = boxcox_transf(x,lambda);
Daniel@0 253 [y lambda d] = optimize(y,lambda,dist,x);
Daniel@0 254 %y = y(~isnan(y));
Daniel@0 255 while lillietest(y,.01) && alpha > delta
Daniel@0 256 yp = boxcox_transf(x+alpha,lambda);
Daniel@0 257 %plot(alpha,lse(yp,lambda,x))
Daniel@0 258 if dist(yp,lambda,x)<d
Daniel@0 259 x = x+alpha;
Daniel@0 260 resalpha = resalpha + alpha;
Daniel@0 261 y = yp;
Daniel@0 262 alpha = alpha*.999;
Daniel@0 263 d = dist(y,lambda,x);
Daniel@0 264 else
Daniel@0 265 minalpha = min(alpha,min(x)); % to avoid negative values
Daniel@0 266 yn = boxcox_transf(x - minalpha,lambda);
Daniel@0 267 %plot(alpha,lse(yn,lambda,x))
Daniel@0 268 if dist(yn,lambda,x)<d
Daniel@0 269 x = minalpha;
Daniel@0 270 resalpha = resalpha - minalpha;
Daniel@0 271 y = yn;
Daniel@0 272 alpha = alpha*.999;
Daniel@0 273 d = dist(y,lambda,x);
Daniel@0 274 else
Daniel@0 275 alpha = alpha/2;
Daniel@0 276 end
Daniel@0 277 end
Daniel@0 278 end
Daniel@0 279 %plot(lambda,dist(y,lambda,x),'.r')
Daniel@0 280
Daniel@0 281
Daniel@0 282 function y = boxcox_transf(x,lambda)
Daniel@0 283 lambda0 = find(~lambda);
Daniel@0 284 if min(x)<0
Daniel@0 285 x = x-min(x);
Daniel@0 286 end
Daniel@0 287 x = repmat(x,[1 length(lambda)]);
Daniel@0 288 lambda = repmat(lambda,[size(x,1) 1]);
Daniel@0 289 y = (x.^lambda-1)./lambda;
Daniel@0 290 y(:,lambda0) = log(x(:,lambda0));
Daniel@0 291
Daniel@0 292
Daniel@0 293 function [z,lambda,d] = optimize(y,lambda,dist,x)
Daniel@0 294 [d index] = min(dist(y,lambda,x));
Daniel@0 295 lambda = lambda(index);
Daniel@0 296 z = y(:,index);
Daniel@0 297
Daniel@0 298
Daniel@0 299 function d = lse(y,lambda,x)
Daniel@0 300 d = skewness(y).^2 + (kurtosis(y)-3).^2/4; % equation used in Jarque-Bera test
Daniel@0 301 %plot(lambda,d,'.')
Daniel@0 302
Daniel@0 303
Daniel@0 304 function d = mle(y,lambda,x)
Daniel@0 305 d = -size(y,1)/2*log(var(y))+(lambda-1)*sum(log(x));