我目前正在尝试编写一个函数,使用直方图计数将概率分配给一组向量。这基本上是一项计算练习,但需要一些技巧才能有效地实现。我将举例说明:
假设我有一个带有X = [x1, x2....xM]
行和N
列的矩阵M
。这里,X
代表M
,N
维向量的集合。换句话说,X
的每列都是N
维向量。
例如,我们可以使用以下内容为X
向量和M = 10000
维度生成N = 5
这样的内容:
X = randint(5,10000)
这将生成一个0 x 10000和0s的矩阵,其中每列代表一个1和0的5维向量。
我想通过基本直方图计数为每个这些向量分配概率。步骤很简单:首先找到X
的唯一列;第二,计算每个唯一列出现的次数。特定事件发生的概率是此列在X中的次数/ X
中的总列数。
回到上面的例子,我可以使用MATLAB中的unique
函数执行第一步,如下所示:
UniqueXs = unique(X','rows')'
上面的代码将返回UniqueXs
,这是一个N
行的矩阵,只包含X的唯一列。请注意,转置是由于奇怪的MATLAB输入要求。
但是,我无法找到一个很好的方法来计算UniqueX中的每个列在X中的次数。所以我想知道是否有人有任何建议?
从广义上讲,我可以想到两种实现计数步骤的方法。第一种方法是使用find
函数,但我认为这可能很慢,因为find
是元素操作。第二种方法是递归调用unique
,因为它还可以提供X
中唯一列的一个的索引。这应该允许我们从结果X
上的unique
和重做X
中删除该列并继续计数。
理想情况下,我认为unique
可能已经在进行一些计数,因此最有效的方法可能是在没有内置函数的情况下工作。
答案 0 :(得分:1)
这里有两个解决方案,一个假设所有值都是0或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);
%# 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,我不会感到惊讶...