%MEANCOV Estimation of the means and covariances from multiclass data % % [U,G] = meancov_new(A,N) % % INPUT % A Dataset % N Normalization to use for calculating covariances: by M, the number % of samples in A (N = 1) or by M-1 (default, unbiased, N = 0). % % OUTPUT % U Mean vectors % G Covariance matrices % % DESCRIPTION % Computation of a set of mean vectors U and a set of covariance matrices G % of the C classes in the dataset A. The covariance matrices are stored as a % 3-dimensional matrix G of the size K x K x C, the class mean vectors as a % labeled dataset U of the size C x K. % % The use of soft labels or target labels is supported. % % SEE ALSO % DATASETS, GAUSS, NBAYESC, DISTMAHA % Copyright: R.P.W. Duin, duin@ph.tn.tudelft.nl % Faculty of Applied Sciences, Delft University of Technology % P.O. Box 5046, 2600 GA Delft, The Netherlands % $Id: meancov.m,v 1.17 2005/10/19 08:32:11 duin Exp $ function [U,G] = meancov_new(a,n) prtrace(mfilename); % N determines whether the covariances are normalized by M (N = 1) or by % M-1 (unbiased, N = 0), where M is the number of objects. if (nargin < 2) prwarning(4,'normalisation not specified, assuming by M-1'); n = 0; end if (n ~= 1) && (n ~= 0) error('Second parameter should be either 0 or 1.') end if (~isa(a,'prdataset')) % A is a matrix: compute mean and covariances DirectionalFeatures = []; if( isempty(DirectionalFeatures) ) U = nanmean(a); G = nancov(a,n); else iCantFeatures = size(a,2); U = nan(1, iCantFeatures); NotDirectionalFeatures = setdiff(1:iCantFeatures, DirectionalFeatures); if( ~isempty(NotDirectionalFeatures) ) U(NotDirectionalFeatures) = nanmean(a(:,NotDirectionalFeatures)); % in the usual way. end U(DirectionalFeatures) = angle(nanmean(exp(1i*a(:,DirectionalFeatures)))); bNotNaN = ~any(isnan( a(:, DirectionalFeatures ) ),2); iCantElementos = sum(bNotNaN); if(iCantElementos < 2) G = zeros(iCantFeatures); else iAux = nan(iCantElementos, iCantFeatures); if( ~isempty(NotDirectionalFeatures) ) iAux(:,NotDirectionalFeatures) = a(bNotNaN,NotDirectionalFeatures) - repmat(U(NotDirectionalFeatures), iCantElementos,1); end for jj = DirectionalFeatures iAux1 = a(bNotNaN, jj ); iAux2 = repmat(U(jj), iCantElementos,1); iAux3 = [ iAux1 - iAux2, 2*pi + iAux1 - iAux2, iAux1 - 2*pi - iAux2 ]; [dummy, iMinIndex] = min(abs(iAux3), [], 2); iMinIndex = sub2ind(size(iAux3),1:size(iAux3,1),iMinIndex'); iAux(:,jj) = iAux3(iMinIndex); end if(n == 1) G = 1/iCantElementos*(iAux'*iAux); else G = 1/(iCantElementos-1)*(iAux'*iAux); end end end else [m,k,c] = getsize(a); cFeaturesDomain = getfeatdom(a); DirectionalFeatures = []; for jj = 1:length(cFeaturesDomain) if(~isempty(cFeaturesDomain{jj})) DirectionalFeatures = [DirectionalFeatures jj]; end end if (islabtype(a,'crisp')) if (c==0) aa = +a; if( isempty(DirectionalFeatures) ) U = nanmean(aa); G = nancov(aa,n); else iCantFeatures = k; U = nan(1, iCantFeatures); NotDirectionalFeatures = setdiff(1:iCantFeatures, DirectionalFeatures); if( ~isempty(NotDirectionalFeatures) ) U(NotDirectionalFeatures) = nanmean(aa(:,NotDirectionalFeatures)); % in the usual way. end U(DirectionalFeatures) = angle(nanmean(exp(1i*aa(:,DirectionalFeatures)))); bNotNaN = ~any(isnan( aa(:, DirectionalFeatures ) ),2); iCantElementos = sum(bNotNaN); iAux = nan(iCantElementos, iCantFeatures); if( ~isempty(NotDirectionalFeatures) ) iAux(:,NotDirectionalFeatures) = aa(bNotNaN,NotDirectionalFeatures) - repmat(U(NotDirectionalFeatures), iCantElementos,1); end for jj = DirectionalFeatures iAux1 = aa(bNotNaN, jj ); iAux2 = repmat(U(jj), iCantElementos,1); iAux3 = [ iAux1 - iAux2, 2*pi + iAux1 - iAux2, iAux1 - 2*pi - iAux2 ]; [dummy, iMinIndex] = min(abs(iAux3), [], 2); iMinIndex = sub2ind(size(iAux3),1:size(iAux3,1),iMinIndex'); iAux(:,jj) = iAux3(iMinIndex); end % iAux1 = aa(:,DirectionalFeatures) - repmat(U(DirectionalFeatures), iCantElementos,1); % boolAbs = abs( iAux1 ) > pi; % SignX = sign( iAux1 ); % % bAux = boolAbs & SignX < 0; % % aa( bAux, DirectionalFeatures ) = aa( bAux, DirectionalFeatures ) + 2*pi; % aa( bAux, DirectionalFeatures ) = aa( bAux, DirectionalFeatures ) - 2*pi; % % iAux(:,DirectionalFeatures) = rem( aa(:, DirectionalFeatures ) - repmat(U(DirectionalFeatures), iCantElementos,1) , 2*pi); if(n == 1) G = 1/iCantElementos*(iAux'*iAux); else G = 1/(iCantElementos-1)*(iAux'*iAux); end end else U = nan(c,k); G = nan(k,k,c); if( isempty(DirectionalFeatures) ) for ii = 1:c J = findnlab(a,ii); if( ~isempty(J) ) aa = a(J,:); bNotNaN = ~any(isnan( aa ),2); U(ii,:) = nanmean( aa(bNotNaN,:) ,1); if (nargout > 1 && sum(bNotNaN) > 1 ) G(:,:,ii) = covm(aa(bNotNaN,:),n); else G(:,:,ii) = 0; end end end else NotDirectionalFeatures = setdiff(1:k, DirectionalFeatures); aa = +a; U = nan(c, k); for ii = 1:c J = findnlab(a,ii); if( ~isempty(J) ) if( ~isempty(NotDirectionalFeatures) ) U(ii,NotDirectionalFeatures) = nanmean(aa(J,NotDirectionalFeatures)); % in the usual way. end U(ii,DirectionalFeatures) = angle(nanmean(exp(1i*aa(J,DirectionalFeatures)))); bNotNaN = ~any(isnan( aa(J,:) ),2); iCantElementos = sum(bNotNaN); if(iCantElementos < 2) G(:,:,ii) = zeros(k); else if (nargout > 1) iAux = nan(iCantElementos, k); if( ~isempty(NotDirectionalFeatures) ) iAux(:,NotDirectionalFeatures) = aa(J(bNotNaN),NotDirectionalFeatures) - repmat(U(ii,NotDirectionalFeatures,:), iCantElementos,1); end for jj = DirectionalFeatures iAux1 = aa(J(bNotNaN), jj ); iAux2 = repmat(U(ii,jj), iCantElementos,1); iAux3 = [ iAux1 - iAux2, 2*pi + iAux1 - iAux2, iAux1 - 2*pi - iAux2 ]; [dummy, iMinIndex] = min(abs(iAux3), [], 2); iMinIndex = sub2ind(size(iAux3),1:size(iAux3,1),iMinIndex'); iAux(:,jj) = iAux3(iMinIndex); end if(n == 1) G(:,:,ii) = 1/iCantElementos*(iAux'*iAux); else G(:,:,ii) = 1/(iCantElementos-1)*(iAux'*iAux); end end end end end end end labu = getlablist(a); elseif (islabtype(a,'soft')) problab = gettargets(a); % Here we also have to be careful for unlabeled data if (c==0) prwarning(2,'The dataset has soft labels but no targets defined: using targets 1'); U = nanmean(+a); G = nancov(+a,n); else U = zeros(c,k); for ii = 1:c % Calculate relative weights for the means. g = problab(:,ii); nn = sum(g); g = g/mean(g); U(ii,:) = mean(a.*repmat(g,1,k)); % Weighted mean vectors if (nargout > 1) u = mean(a.*repmat(sqrt(g),1,k)); % this appears to be needed to weight cov terms properly G(:,:,ii) = covm(a.*repmat(sqrt(g),1,k),1) - U(ii,:)'*U(ii,:) + u'*u; % Re-normalise by M-1 if requested. if (n == 0) G(:,:,ii) = m*G(:,:,ii)/(m-1); end end end end labu = getlablist(a); else % Default action. U = mean(a); G = covm(a,n); labu = []; end % Add attributes of A to U. U = prdataset(U,labu,'featlab',getfeatlab(a), ... 'featsize',getfeatsize(a)); if (~islabtype(a,'targets')) p = getprior(a); U = setprior(U,p); end end; return