我在向量p
中有一个w
个索引和相应的权重。我想从此群体中获取k
样本而无需替换,其中选择与随机的权重成比例。
我知道randsample
可以通过说
J = randsample(p,k,true,w)
但是当我使用参数false
而不是true
来调用它时,我得到了
??? Error using ==> randsample at 184
Weighted sampling without replacement is not supported.
我将自己的函数编写为discussed in here:
p = 1:n;
J = zeros(1,k);
for i = 1:k
J(i) = randsample(p,1,true,w);
w(p == J(i)) = 0;
end
但是由于它在循环中有k
次迭代,我寻求更短/更快的方法来做到这一点。你有什么建议吗?
编辑:我想随机选择与某些加权条件成比例的矩阵的k
个唯一列。这就是为什么我在没有替换的情况下使用采样。
答案 0 :(得分:1)
我认为你应该继续使用for,但我建议将相应的重量减少一个。
w(p == J(i)) = w(p == J(i)) -1;
答案 1 :(得分:1)
这仍显示在搜索结果中,因此我想添加datasample函数作为选项。以下代码将根据相应的向量fromVector
提供来自myWeights
的5个单位的加权样本。
mySample = datasample(fromVector, 5, 'Replace', false, 'Weights', myWeights)
答案 2 :(得分:0)
如果样本数远小于元素数,那么petrichor for循环方法的替代方法表现良好,可以计算带有替换的加权随机样本,然后删除重复项。当然,如果样本数k
接近元素数n
,这是一个非常糟糕的想法,因为这需要多次迭代,但是通过避免循环,挂钟性能通常是更好。您的里程可能会有所不同。
function I=randsample_noreplace(n,k,w)
I = sort(randsample(n, k, true, w));
while 1
Idup = find( I(2:end)-I(1:end-1) ==0);
if length(Idup) == 0
break
else
I(Idup)=randsample(n, length(Idup), true, w);
I = sort(I);
end
end
答案 3 :(得分:0)
如果你想选择很大一部分列(即k不小于n),或者权重非常偏斜,你可以使用Jeff的解决方案的这种改进,这可以确保每次调用randsample产生的样本与以前的样本不同。
此外,它按照顺序返回样本,其中没有替换的真实采样将返回它们,而不是排序。
function I=randsample_noreplace(n,k,w)
I = randsample(n, k, true, w);
while 1
[II, idx] = sort(I);
Idup = [false, diff(II)==0];
if ~any(Idup)
break
else
w(I) = 0; %% Don't replace samples
Idup (idx) = Idup; %% find duplicates in original list
I = [I(~Idup), (randsample(n, sum(Idup), true, w))];
end
end
当选择具有均匀权重的30个值中的29个(给出最少利益的情况)时,需要3或4次迭代,而没有附加线的则为26次。如果均匀地选择权重,则仍需要3到5次迭代,而没有额外的行则为80左右。
此外,迭代次数以k为界,但分布是偏斜的。