通过在-1和1之间压缩/拉伸数据来标准化

时间:2017-03-09 16:19:05

标签: matlab

下面的代码会将具有正值和负值的矢量标准化为[-1,1]范围。但是,如果您查看绘图,您会注意到由于标准化的类型,绘图向下移动。

问题:

有没有办法改变方法以在-1和1之间规范化数据而不移动数据?

%# generate some vector
vec = [0,0.5,0.8660254040,.8,0.866025404,0.5,1.22E-16,-0.1,-0.4,-0.3, ...
-0.6,-0.5,-2.45E-16,0.5,0.866025404,1.3,0.866025404,0.5,3.67E-16, ...
-0.5,-0.4,-0.7,-0.7,-0.5,-4.90E-16];

%# get max and min
maxVec = max(vec);
minVec = min(vec);

%# normalize to -1...1
vecN = ((vec-minVec)./(maxVec-minVec) - 0.5 ) *2;

% plot results
plot(vec,'k'); hold on;
plot(vecN,'--r'); hold off;

原始矢量(黑色)与标准化矢量(红色虚线)的图

此行为标准化了矢量,但移动了不需要的图。

Plot of original vector (black) vs normalized vector (red dashed)

2 个答案:

答案 0 :(得分:4)

如果您将数据标准化为介于-1和1之间,那么数据肯定会发生变化,即均值。如果你"正常化"你无法避免这种情况。

相反,将数据缩放到您想要的范围内:

vecN=vec*1/max(abs(max(vec)),abs(min(vec)));

无论何时更改数据,平均 都会发生变化。这种方式更容易检索(mean(vec)==mean(vecN)*max(abs(max(vec)),abs(min(vec)))

答案 1 :(得分:1)

Ander的上述答案让我想到要执行我想要的动作,最好分别对待正值和负值,然后将"标准化"的结果合并。压扁/拉伸结果。

下面的函数根据需要在-1和1之间搜索或拉伸输入向量,从而创建一种"标准化"。

<强>代码

function [vecN] = normSquish(vec)
% Returns a "squished" normalized vector (vecN).
% The function squishes/stretches the positive/negative relative to the
% max/min of vec.

%% Normalize input vector
% get max and min
maxVec = max(vec);
minVec = min(vec);

vecPos = vec;
vecNeg = vec;
vecPos(vecPos<0) = 0;
vecNeg(vecNeg>0) = 0;

vecPosN = vecPos./abs(maxVec);
vecNegN = vecNeg./abs(minVec);

vecN = vecPosN;
zs = find(vecPos==0);
for i = 1:size(zs,2)
    index = zs(i);
    vecN(index)=vecNegN(index);
end

比较原始方法和建议的解决方案 Comparison of methods