如何在Matlab中将向量归一化,使其总和为1?

10
我需要规范化一个包含N个整数的向量,使得:
  • 每个值都与其原始值成比例(该值将在0到1之间)
  • 所有值的总和为1
例如:
如果我有一个向量
V = [2,2,1,0]

归一化后的向量应该是:

V_norm = [0.4,0.4,0.2,0]  % 0.4+0.4+0.2 = 1

我尝试了社区和网络中许多解决方案,最终我用了这段代码:

part = norm(V);
if part > 0
  V_norm = V/part;
else % part = 0 --> avoid "divide by 0" 
  V_norm = part;
end

如果满足以下条件,该问题将会起作用:

  • 数组的所有元素都是"0"-->结果数组不会改变
  • 只有一个数组元素>0,而其他所有元素均为0-->结果数组:元素>0为1,其余为0

但如果我有另一种情况,尽管结果成比例,总和不为0。例如:

   V = [1,0,1]
   V_norm = [0.74,0,0.74]

   V = [1,1,1]
   V_norm = [0.54,0.54,0.54]

(我不确定数字是否正确,因为现在无法使用Matlab,但我确信总和>1)

有什么提示吗?

提前谢谢。

4个回答

10
你需要做的是,我相信,使用1-范数(出租车范数)进行归一化处理:
v = [2, 2, 1, 0];
v_normed = v / norm(v, 1); % using the 1-norm

变量v_normed现在应该是[0.4, 0.4, 0.2, 0.0]v_normed的1-范数将等于1。您还可以对向量求和(类似于1-范数,但不会对每个值应用绝对函数),但在一般情况下(如果v中有任何值低于0),该总和的范围将在-1到1之间。 您可以对结果求绝对值,但从数学上讲,它将不再符合范数的定义。

就像我在答案中所述,它仍然不能满足OP对于所有向量的两个要求,但至少在数学上可以被认为是一种范数。 - Eitan T

9

...规范化向量应该为:

v_norm = [0.4, 0.4, 0.2, 0]; % 0.4+0.4+0.2 = 1

这取决于你使用的norm函数是什么。

MATLAB中的norm(x)返回标准范数,意思是一个已经规范化的向量x元素的平方和为1。

在你的例子中:

v = [1, 1, 1];         %# norm(v) = sqrt(1^2+1^2+1^2) = ~1.7321
v_norm = v / norm(v);  %# v_norm = [0.5574, 0.5574, 0.5574]

sum(v_norm .^ 2) 的确得到了1,但是sum(v_norm)并没有,这是预料中的结果。


我需要将一个由N个整数组成的向量归一化,使得每个值都与其原始值成比例(该值将在0和1之间),并且所有值的总和为1。
“normalize”是什么意思?这是否意味着按照norm definition中有效的数学规范函数进行除法?
“proportional”是什么意思?这是否意味着所有元素都乘以相同的数字?如果是这样,并且它是有效的数学规范,则不能保证元素的总和始终为1。 例如,考虑v = [1, -2]。那么sum(v) = -1
或者也许sum是您要查找的函数,但它在数学上不符合规范,因为“规范是将正长度或大小分配给向量空间中的所有向量的函数”。 在上面的示例中,sum(v)是负数。

有什么提示吗?

你可以选择以下两种方式:

  1. sum(x),这个方法满足要求但不符合范数函数的定义,因为它可能会产生负值。
  2. norm(x, 1),正如OleThomsenBuus所建议的那样,它实际上计算的是sum(abs(x(:)))
    除非你将向量空间限制为非负向量,否则它不能同时满足你的两个要求。

6
如果您在归一化方面没有给出比问题开头提供的更多条件,可能的解决方案是:
V = [3 4 -2];
S = sum(V);
if (S == 0)
    % no solution
else
    V_norm = V ./ S;
end
sum(V_norm)

顺便提一下,sum(v)在数学上不能被称为范数,因为它可能会产生负值。 - Eitan T
不满足所有值都在0和1之间的要求(考虑负元素)。 - Tobias
我同意。我不应该像原帖作者一样使用“normalization”而不是“norm”。我会相应地编辑我的答案。 - Deve
在编程中,./ 中不需要加点。 - Serg
2
@Serg 没错。但我认为,在将标量运算符应用于向量时,使用 . 是一个好的习惯,因为它使代码不含糊。 - Deve

0

我将在这里留下我的解决方案,用于“归一化”具有正条目的矩阵的行,其中归一化意味着在过程之后行总和为1。

摘要

normmat = normr(sqrt(mat)).^2

最简示例

mat 是您具有正条目的矩阵

mat = [1 2 3; 2 3 4]

mat =

     1     2     3
     2     3     4

现在我们来写一行代码:

normmat = normr(sqrt(mat)).^2

normmat =

    0.1667    0.3333    0.5000
    0.2222    0.3333    0.4444

每行的总和为1。
sum(normmat, 2)

ans =

    1.0000
    1.0000

一行内的比例是恒定的

normmat ./ mat

ans =

    0.1667    0.1667    0.1667
    0.1111    0.1111    0.1111

不一定是最有效率的,但它只有一行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接