Как мне нормализовать вектор в Matlab, где сумма равна 1?

Мне нужно нормализовать вектор из 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)

Ах намек?

заранее спасибо


person dragonmnl    schedule 27.06.2012    source источник


Ответы (4)


... нормализованный вектор должен быть:

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

Это зависит. Какова ваша норма функция?

norm(x) в MATLAB возвращает стандартную норму, означающую, что сумма квадратов элементов нормализованного вектора 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.

Что вы подразумеваете под нормализовать? Означает ли это деление на значение, которое является допустимой функцией математической нормы в соответствии с определением нормы ?

Что вы подразумеваете под пропорционально? Означает ли это, что все элементы умножаются на это одно и то же число? Если это так, и это допустимая математическая норма, вы не можете гарантировать, что сумма элементов всегда будет равна 1.
Например, рассмотрим v = [1, -2]. Затем sum(v) = -1.

Или, может быть, sum — это функция, которую вы ищете, но она математически не может считаться нормой, потому что норма — это функция, которая присваивает строго положительную длину или размер всем векторам в векторном пространстве.
В приведенном выше примере sum(v) отрицательное значение.


А подсказка?

Вы можете выбрать:

  1. sum(x), которая удовлетворяет обоим требованиям, но не может считаться нормальной функцией, поскольку может давать отрицательные значения.
  2. norm(x, 1), как предложил OleThomsenBuus, который фактически вычисляет sum(abs(x(:))).
    Он не будет удовлетворять обоим вашим требованиям, если вы не ограничите свое векторное пространство неотрицательными векторами.
person Eitan T    schedule 27.06.2012

Я считаю, что вам нужно нормализовать, используя 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]. 1-норма v_normed будет равна 1. Вы также можете суммировать вектор (аналогично 1-норме, но без применения абсолютной функции к каждому значению), но диапазон этой суммы будет от -1 до 1 в общий случай (если какие-либо значения в v меньше 0). Вы можете использовать abs для полученной суммы, но математически это уже не будет считаться нормой.

person Ole Thomsen Buus    schedule 27.06.2012
comment
Как я уже говорил в своем ответе, он по-прежнему не соответствует двум требованиям OP для всех векторов, но, по крайней мере, математически считается нормой. - person Eitan T; 27.06.2012

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

V = [3 4 -2];
S = sum(V);
if (S == 0)
    % no solution
else
    V_norm = V ./ S;
end
sum(V_norm)
person Deve    schedule 27.06.2012
comment
В качестве примечания: sum(v) не может математически квалифицироваться как норма, поскольку может давать отрицательные значения. . - person Eitan T; 27.06.2012
comment
Не соответствует требованию, чтобы все значения находились в диапазоне от 0 до 1 (с учетом отрицательных элементов). - person Tobold; 27.06.2012
comment
Я согласен. Я не должен был использовать нормализацию вместо нормы, как это делал ОП. Я отредактирую свой ответ соответственно. - person Deve; 27.06.2012
comment
точка в ./ не нужна - person Serg; 27.06.2012
comment
@Серг Это правильно. Тем не менее, я считаю хорошей практикой использовать . при применении скалярных операторов к вектору, потому что это делает код однозначным. - person Deve; 28.06.2012

Я оставлю здесь свое решение для нормализации строк матрицы с положительными элементами, где нормализация означает, что суммы строк равны 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

Не обязательно самый эффективный, но это одна линия.

person Darjus Hosszejni    schedule 01.04.2021