2017-03-22 41 views
1

我有一个输入二维直方图,我想用2进行交叉验证。问题是我不知道如何从直方图中提取两个互斥的数据随机样本。如果它是几个每个数据点的位置信息列表,那很容易 - 以相同的方式对列表中的数据进行混洗,并将列表平分。随机选择直方图数据MATLAB

所以对于一个列表我这样做:

list1 = [1,2,3,3,5,6,1]; 
list2 = [1,3,6,6,5,2,1]; 

idx = randperm(length(list1)); % ie. idx = [4 3 1 5 6 2 7] 
shlist1 = list1(idx); % shlist1 = [3,3,1,5,6,2,1] 
shlist2 = list2(idx); % shlist2 = [6,6,1,5,2,3,1] 

slist1 = shlist1(1:3); % slist1 = [3,3,1] 
elist1 = shlist1(4:6); % elist1 = [5,6,2,1] 
slist2 = shlist2(1:3); % slist2 = [6,6,1] 
elist2 = shlist2(4:6); % elist2 = [5,2,3,1] 

但是如果这个相同的数据被提交给我的直方图

hist = [2 0 0 0 0 0] 
     [0 0 0 0 0 1] 
     [0 1 0 0 0 0] 
     [0 0 0 0 0 0] 
     [0 0 0 0 1 0] 
     [0 0 2 0 0 0] 

我想要的结果是这样的

hist1 = [0 0 0 0 0 0] 
     [0 0 0 0 0 1] 
     [0 1 0 0 0 0] 
     [0 0 0 0 0 0] 
     [0 0 0 0 0 0] 
     [0 0 1 0 0 0] 

hist2 = [2 0 0 0 0 0] 
     [0 0 0 0 0 0] 
     [0 0 0 0 0 0] 
     [0 0 0 0 0 0] 
     [0 0 0 0 1 0] 
     [0 0 1 0 0 0] 

这样数据的不同半数是随机的,并且同样分配给两个新的直方图。

这是否相当于取每个bin hist(i,j)的随机整数高度,并将其添加到hist1(i,j)中的等效bin中,并将其与hist2(i,j)的差值?

% hist as shown above 
hist1 = zeros(6); 
hist2 = zeros(6); 
for i = 1:length(hist(:,1))*length(hist(1,:)) 
    randNum = rand; 
    hist1(i) = round(hist(i)*randNum); 
    hist2(i) = hist(i) - hist1(i); 
end 

如果这是等价的,有没有更好的方法/内置的方式呢?

我的实际直方图是300x300个分档,包含大约6,000,000个数据点,并且它需要很快。

感谢所有帮助:)

编辑: 我做的代码的建议有点不等同于从列表中取位置点的随机样本,因为它不维护的全概率密度函数数据。 将直方图减半应该对我的6,000,000点是正确的,但我希望有一种方法可以在几个点上仍然有效。

回答

0

您可以使用randrandi生成两个直方图。第一种方法更高效,但第二种方法更随机。

h = [[2 0 0 0 0 0] 
     [0 0 0 0 0 1] 
     [0 1 0 0 0 0] 
     [0 0 0 0 0 0] 
     [0 0 0 0 1 0] 
     [0 0 2 0 0 0]]; 

%using rand  
h1 = round(rand(size(h)).*h); 
h2 = h - h1; 

%using randi 
h1 = zeros(size(h)); 
for k = 1:numel(h) 
    h1(k) = randi([0 h(k)]); 
end 
h2 = h - h1; 
+0

非常感谢 - 它和我提出的方法一样,只是更优雅,可能更高效。 尽管我最初提出的方法存在的问题是直方图表示概率密度函数,因此如果我从列表中随机抽取位置信息,则需要保留一般形状。在上述方法中,我们很可能会从具有较高PDF的二进制文件中获取很少的数据,因为我们要获取大部分数据。 – user1153070

+0

对于趋于无穷的数据集,该方法应将每个直方图分成两半,并将每一半存储在两个不同的直方图中。虽然我认为直接将直方图减半可能并不准确。 – user1153070

+0

@ user1153070我想你应该指定你想要的。如果拆分方法(减半)基于批准的纸张/书本,那么您就是对的,并按照您的要求做。不过,我回答了你的问题,你想要一个有效的方法来随机分裂数组。 – rahnema1

0

假设H是你的二维直方图。下面的代码提取一个概率与该索引的计数成正比的随机索引 - 我认为这是你想要的。

cc = cumsum(H(:)); 
if cc(1) ~= 0 
    cc = [0; cc]; 
end 
m = cc(end); 
ix = find(cc > m*rand, 1); 

要提取多个样本,你需要编写中提取一个调用样本的一些n个你自己的查找功能(最好的效率二进制搜索)。这会给你一个指数矢量(称为ix_vec),其概率与每个指数的柱状图计数成正比。

然后,如果我们用X表示对应于直方图中的每个位置的数值,您的随机样本是:

R1 = X(ix_vec); 

重复用于第二随机样本集合。