如何将向量规范化/非规范化到范围 [-1;1]
Posted
技术标签:
【中文标题】如何将向量规范化/非规范化到范围 [-1;1]【英文标题】:How to normalize / denormalize a vector to range [-1;1] 【发布时间】:2011-06-08 17:59:40 【问题描述】:我如何规范化一个向量到[-1;1]
范围内
我想使用函数norm
,因为它会更快。
还请告诉我如何在规范化之后去规范化那个向量?
【问题讨论】:
【参考方案1】:一个简单的解决方案是使用现成的 MATLAB 函数:
mapminmax
通过将行最小值和最大值映射到 [-1 1] 来处理矩阵
例子:
x1 = [1 2 4; 1 1 1; 3 2 2; 0 0 0]
[y1,PS] = mapminmax(x1)
在归一化后对该向量进行反归一化
x1_again = mapminmax('reverse',y1,PS)
【讨论】:
【参考方案2】:最新的答案是使用 Matlab R2017b 中引入的 rescale
函数。要将向量 A
标准化为范围 -1:1
,您可以运行:
A = rescale(A, -1, 1);
您可以通过预先保存最小值和最大值然后再次运行重新调整来撤消此操作:
maxA = max(A(:));
minA = min(A(:));
A = rescale(A, -1, 1);
% use the normalised A
A = rescale(A, minA, maxA);
【讨论】:
【参考方案3】:基于 Jonas 的答案的扩展答案如下。它允许根据向量中是否存在负数和正数进行自动归一化,或者手动选择所需的归一化类型。函数下方是一个测试脚本。
归一化函数
function [vecN, vecD] = normVec(vec,varargin)
% Returns a normalize vector (vecN) and "de-nomralized" vector (vecD). The
% function detects if both positive and negative values are present or not
% and automatically normalizes between the appropriate range (i.e., [0,1],
% [-1,0], or [-1,-1].
% Optional argument allows control of normalization range:
% normVec(vec,0) => sets range based on positive/negative value detection
% normVec(vec,1) => sets range to [0,1]
% normVec(vec,2) => sets range to [-1,0]
% normVec(vec,3) => sets range to [-1,1]
%% Default Input Values
% Check for proper length of input arguments
numvarargs = length(varargin);
if numvarargs > 1
error('Requires at most 1 optional input');
end
% Set defaults for optional inputs
optargs = 0;
% Overwrite default values if new values provided
optargs(1:numvarargs) = varargin;
% Set input to variable names
[setNorm] = optargs:;
%% Normalize input vector
% get max and min
maxVec = max(vec);
minVec = min(vec);
if setNorm == 0
% Automated normalization
if minVec >= 0
% Normalize between 0 and 1
vecN = (vec - minVec)./( maxVec - minVec );
vecD = minVec + vecN.*(maxVec - minVec);
elseif maxVec <= 0
% Normalize between -1 and 0
vecN = (vec - maxVec)./( maxVec - minVec );
vecD = maxVec + vecN.*(maxVec - minVec);
else
% Normalize between -1 and 1
vecN = ((vec-minVec)./(maxVec-minVec) - 0.5 ) *2;
vecD = (vecN./2+0.5) * (maxVec-minVec) + minVec;
end
elseif setNorm == 1
% Normalize between 0 and 1
vecN = (vec - minVec)./( maxVec - minVec );
vecD = minVec + vecN.*(maxVec - minVec);
elseif setNorm == 2
% Normalize between -1 and 0
vecN = (vec - maxVec)./( maxVec - minVec );
vecD = maxVec + vecN.*(maxVec - minVec);
elseif setNorm == 3
% Normalize between -1 and 1
vecN = ((vec-minVec)./(maxVec-minVec) - 0.5 ) *2;
vecD = (vecN./2+0.5) * (maxVec-minVec) + minVec;
else
error('Unrecognized input argument varargin. Options are 0,1,2,3');
end
测试函数的脚本
% Define vector
x=linspace(0,4*pi,25);
y = sin(x);
ya=sin(x); yb=y+10; yc=y-10;
% Normalize vector
ya0=normVec(ya); yb0=normVec(yb); yc0=normVec(yc);
ya1=normVec(ya,1); yb1=normVec(yb,1); yc1=normVec(yc,1);
ya2=normVec(ya,2); yb2=normVec(yb,2); yc2=normVec(yc,2);
ya3=normVec(ya,3); yb3=normVec(yb,3); yc3=normVec(yc,3);
% Plot results
figure(1)
subplot(2,2,1)
plot(x,ya0,'k',x,yb0,'ro',x,yc0,'b^')
title('Auto Norm-Range')
subplot(2,2,2)
plot(x,ya1,'k',x,yb1,'ro',x,yc1,'b^')
title('Manual Norm-Range: [0,1]')
subplot(2,2,3)
plot(x,ya2,'k',x,yb2,'ro',x,yc2,'b^')
title('Manual Norm-Range: [-1,0]')
subplot(2,2,4)
plot(x,ya3,'k',x,yb3,'ro',x,yc3,'b^')
title('Manual Norm-Range: [-1,1]')
【讨论】:
【参考方案4】:norm
对向量进行归一化,使其平方和为 1。
如果要对向量进行归一化,使其所有元素都介于 0 和 1 之间,则需要使用最小值和最大值,然后可以使用它们再次进行反规范化。
%# generate some vector
vec = randn(10,1);
%# get max and min
maxVec = max(vec);
minVec = min(vec);
%# normalize to -1...1
vecN = ((vec-minVec)./(maxVec-minVec) - 0.5 ) *2;
%# to "de-normalize", apply the calculations in reverse
vecD = (vecN./2+0.5) * (maxVec-minVec) + minVec
【讨论】:
如何使用相同的代码在 0 和 1 之间进行规范化? @Shyamkkhadka:使用下方ScottG提供的代码,或使用((vec-minVec)./(maxVec-minVec))
以上是关于如何将向量规范化/非规范化到范围 [-1;1]的主要内容,如果未能解决你的问题,请参考以下文章
如果给定的数据在使用 R 或 Python 的范围(-1 到 1)内,如何以 (-3 ,-2,-1,0,1,2,3) 格式规范化数据?