2013-03-12 3 views
0

Я нормализуя набор данных с помощью командыMATLAB - bsxfun для отрицательных значений

X=bsxfun(@times,bsxfun(@minus,X,min(X,[],1)),1./max(X,[],1)) 

Я попробовал эту функцию на двух разных наборов данных. У одного были отрицательные значения. Другие - нет. Набор данных без отрицательных значений отлично нормализовался между 0 и 1. И тот, у кого отрицательные значения, нормализовался неправильно. Можно ли это исправить? есть ли другой способ, я могу нормализовать набор данных с отрицательными значениями?

ответ

3

Преступник находится в вашей нормализации. Вы вычитаете min(X) из X, а затем разделите его на max(X), вместо того чтобы делить на max(X - min(X)).

То, что вы должны делать это нарушение это в два этапа:

Y = bsxfun(@minus, X, min(X)); 
X_normalized = bsxfun(@rdivide, Y, max(Y)); 

Обратите внимание, что это не работало должным образом во всяком случае, ни для положительного, ни для отрицательных значений.

Еще несколько нот:

  1. min(X, [], 1) может быть сокращен до min(X). То же самое касается max.
  2. Вместо использования times в bsxfun умножить на 1 ./ max(Y), вы можете использовать rdivide.

Надеюсь, это поможет!

0

Хорошо, это сообщение действительно меня беспокоило.

Я никогда не слышал о bsxfun. Я использовал arrayfun, cellfun, structfun. Поэтому я бродил, зачем использовать его, и я подумал, что со скоростью я найду свой ответ. Так что я сделал глупый тест:

X = magic(3); 
tic 
Y = bsxfun(@minus, X, min(X(:))); 
X_normalized = bsxfun(@rdivide, Y, max(Y(:))); 
toc 

tic 
arrayfun(@(x) x-min(X(:))./(max(X(:))-min(X(:))),X); 
toc 

И я получил ответ:

Elapsed time is 0.004130 seconds. 
Elapsed time is 0.002468 seconds. 

, который сделал мне вещь, что arrayfun был путем. Но может случиться так, что arrayfun только быстрее из-за того, что X - это небольшие данные, поэтому я попытался с большим X (X = magic(100);). И, конечно же, bsxfun намного быстрее, что означает, что мне нужно будет перекодировать некоторые вещи.

Elapsed time is 0.003342 seconds. 
Elapsed time is 0.395347 seconds. 

Однако, не достаточно доволен результатами я решил запустить тест несколько раз просто чтобы убедиться, что он не был причинности. И вот когда он начинает беспокоиться.

test= repmat({zeros(2,10)},2,1); 
Xsizes = [3 100]; 
for ii=1:2,for jj=1:10 
X = magic(Xsizes(ii)); 
tic 
Y = bsxfun(@minus, X, min(X(:))); 
X_normalized = bsxfun(@rdivide, Y, max(Y(:))); 
test{ii}(1,jj)=toc; 


tic 
arrayfun(@(x) x-min(X(:))./(max(X(:))-min(X(:))),X); 
test{ii}(2,jj)=toc; 

end;end 

display('small Size data') 
test{1} 
display('Big Size data') 
test{2} 

И ответ ожидая, чтобы быть быстрее arrayfun ВСЕГДА для небольших данных и быстрее bsxfun для больших объемов данных. Однако в обоих случаях он быстрее bsxfun и занимает больше времени для вычисления первого времени набора.

small Size data 

ans = 

    1.0e-03 * 

    0.4900 0.0470 0.0430 0.0410 0.0410 0.0420 0.0420 0.0410 0.0420 0.0410 
    0.6600 0.4200 0.4040 0.3890 0.3920 0.3900 0.3920 0.3890 0.3960 0.3900 

Big Size data 

ans = 

    0.0003 0.0001 0.0001 0.0001 0.0001 0.0001 0.0002 0.0001 0.0001 0.0001 
    0.3853 0.3871 0.3846 0.3855 0.3874 0.3844 0.3863 0.3840 0.3860 0.3853 

Это меня озадачивает. Еще больше, если вы снова вычисляете X=magic(3) вне цикла for, а bsxfun всегда занимает больше, чем arrayfun.

Elapsed time is 0.004891 seconds. 
Elapsed time is 0.002008 seconds. 



Elapsed time is 0.003181 seconds. 
Elapsed time is 0.001994 seconds. 



Elapsed time is 0.003109 seconds. 
Elapsed time is 0.002008 seconds. 

Какие-либо намеки?