N-мерная гистограмма - PullRequest
1 голос
/ 29 июля 2011

В настоящее время я пытаюсь закодировать функцию, чтобы назначить вероятности для набора векторов, используя количество гистограмм. По сути, это упражнение по подсчету, но для того, чтобы эффективно его достичь, требуется некоторая утонченность. Я проиллюстрирую на примере:

Скажите, что у меня есть матрица X = [x1, x2....xM] с N строками и M столбцами. Здесь X представляет коллекцию M, N -мерных векторов. Другими словами, каждый из столбцов X является N -мерным вектором.

В качестве примера, мы можем сгенерировать такие X для M = 10000 векторов и N = 5 измерений, используя:

X = randint(5,10000)

В результате будет получена матрица 5 x 10000, состоящая из 0 и 1, где каждый столбец представляет 5-мерный вектор из 1 и 0.

Я хотел бы назначить вероятность каждому из этих векторов с помощью основного числа гистограмм. Шаги просты: сначала найдите уникальные столбцы X; во-вторых, подсчитайте, сколько раз встречается каждый уникальный столбец. Вероятность того или иного события равна # разу того, что этот столбец был в X / общее количество столбцов в X.

Возвращаясь к примеру выше, я могу сделать первый шаг, используя функцию unique в MATLAB следующим образом:

UniqueXs = unique(X','rows')' 

Приведенный выше код вернет UniqueXs, матрицу с N строками, которая содержит только уникальные столбцы X. Обратите внимание, что транспонирование происходит из-за странных входных требований MATLAB.

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

В общем, я могу думать о двух способах достижения шага счета. Первый способ - использовать функцию find, хотя я думаю, что это может быть медленно, поскольку find является поэлементной операцией. Второй способ - это рекурсивный вызов unique, поскольку он также может предоставить индекс один уникальных столбцов в X. Это должно позволить нам удалить этот столбец из X и повторить unique в полученном X и продолжать считать.

В идеале, я думаю, что unique, возможно, уже делает какой-то подсчет, поэтому наиболее эффективным способом, вероятно, будет работа без встроенных функций.

1 Ответ

1 голос
/ 30 июля 2011

Вот два решения: одно предполагает, что все значения равны 0 или 1 (как в примере в вашем описании), другое - нет. Оба кода должны быть очень быстрыми (особенно код с двоичными значениями) даже для больших данных.

1) только нули и единицы

%# random vectors of 0's and 1's
x = randi([0 1], [5 10000]);    %# RANDINT is deprecated, use RANDI instead

%# convert each column to a binary string
str = num2str(x', repmat('%d',[1 size(x,1)])); %'

%# convert binary representation to decimal number
num = (str-'0') * (2.^(size(s,2)-1:-1:0))';    %'# num = bin2dec(str);

%# count frequency of how many each number occurs
count = accumarray(num+1,1);                   %# num+1 since it starts at zero

%# assign probability based on count
prob = count(num+1)./sum(count);

2) любое положительное целое число

%# random vectors with values 0:MAX_NUM
x = randi([0 999], [5 10000]);

%# format vectors as strings (zero-filled to a constant length)
nDigits = ceil(log10( max(x(:)) ));
frmt = repmat(['%0' num2str(nDigits) 'd'], [1 size(x,1)]);
str = cellstr(num2str(x',frmt));               %'

%# find unique strings, and convert them to group indices
[G,GN] = grp2idx(str);

%# count frequency of occurrence
count = accumarray(G,1);

%# assign probability based on count
prob = count(G)./sum(count);

Теперь мы можем видеть, например, сколько раз встречался каждый «уникальный вектор»:

>> table = sortrows([GN num2cell(count)])
table = 
    '000064850843749'    [1]       # original vector is: [0 64 850 843 749]
    '000130170550598'    [1]       # and so on..
    '000181606710020'    [1]
    '000220492735249'    [1]
    '000275871573376'    [1]
    '000525617682120'    [1]
    '000572482660558'    [1]
    '000601910301952'    [1]
    ...

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...