Matlabの行列の各列を正規化したい。私は2つの実装を試しました:
オプションA:
mx=max(x);
mn=min(x);
mmd=mx-mn;
for i=1:size(x,1)
xn(i,:)=((x(i,:)-mn+(mmd==0))./(mmd+(mmd==0)*2))*2-1;
end
オプションB:
mn=mean(x);
sdx=std(x);
for i=1:size(x,1)
xn(i,:)=(x(i,:)-mn)./(sdx+(sdx==0));
end
ただし、これらのオプションは私のデータには時間がかかりすぎます。 5000x53マトリックスで3〜4秒。したがって、より良い解決策はありますか?
MATLABでは、ベクトル化=速度であることを忘れないでください。
A
がMx N行列の場合、
A = Rand(m,n);
minA = repmat(min(A), [size(A, 1), 1]);
normA = max(A) - min(A); % this is a vector
normA = repmat(normA, [length(normA) 1]); % this makes it a matrix
% of the same size as A
normalizedA = (A - minA)./normA; % your normalized matrix
ループの代わりに bsxfun を使用します。これは少し速いかもしれません。ただし、より多くのメモリを使用する場合もあります(これは、あなたの場合に問題になる可能性があります。ページングしている場合、すべてが非常に遅くなります)。
平均値と標準値で正規化するには、次のように記述します。
mn = mean(x);
sd = std(x);
sd(sd==0) = 1;
xn = bsxfun(@minus,x,mn);
xn = bsxfun(@rdivide,xn,sd);
注:このコードは、OctaveおよびMATLABバージョンR2016b以降で機能します。
function X_norm = normalizeMatrix(X)
mu = mean(X); %mean
sigma = std(X); %standard deviation
X_norm = (X - mu)./sigma;
end
X
をm x n
行列とし、列ごとに正規化します。
次のmatlabコードはそれを行います
XMean = repmat(mean(X),m,1);
XStd = repmat(std(X),m,1);
X_norm = (X - XMean)./(XStd);
要素ごとの./演算子についてここで説明します: http://www.mathworks.in/help/matlab/ref/arithmeticoperators.html
注:前述のように、これは単により高速なソリューションであり、マトリックスをループするのと同じタスクを実行します。この組み込み関数の基礎となる実装により、機能が高速化されます
注:私は新たに新しい回答を提供していませんが、提案された回答を比較しています。
オプションA:bsxfun()
を使用する
function xn = normalizeBsxfun(x)
mn = mean(x);
sd = std(x);
sd(sd==0) = eps;
xn = bsxfun(@minus,x,mn);
xn = bsxfun(@rdivide,xn,sd);
end
オプションB:forループの使用
function xn = normalizeLoop(x)
xn = zeros(size(x));
for ii=1:size(x,2)
xaux = x(:,ii);
xn(:,ii) = (xaux - mean(xaux))./mean(xaux);
end
end
異なるマトリックスサイズの両方の実装を比較します。
expList = 2:0.5:5;
for ii=1:numel(expList)
expNum = round(10^expList(ii));
x = Rand(expNum,expNum);
tic;
xn = normalizeBsxfun(x);
ts(ii) = toc;
tic;
xn = normalizeLoop(x);
tl(ii) = toc;
end
figure;
hold on;
plot(round(10.^expList),ts,'b');
plot(round(10.^expList),tl,'r');
legend('bsxfun','loop');
set(gca,'YScale','log')
結果は、小さな行列の場合、bsxfun
が高速であることを示しています。ただし、他の post でも見つかったため、高次元では違いは無視できます。
X軸は行列要素の平方根数であり、y軸は秒単位の計算時間です。
使ってみませんか
normc(X)
これにより、行列Xが列方向に正規化されます。ただし、インストールにニューラルネットワークツールボックスを含める必要があります。