如何从向量中随机选取N个数字,a
并为每个数字分配权重?
让我们说:
a = 1:3; % possible numbers
weight = [0.3 0.1 0.2]; % corresponding weights
Run Code Online (Sandbox Code Playgroud)
在这种情况下,拾取1的概率应该比拾取2的概率高3倍.
所有权重的总和可以是任何东西.
Amr*_*mro 39
R = randsample([1 2 3], N, true, [0.3 0.1 0.2])
Run Code Online (Sandbox Code Playgroud)
randsample包含在统计工具箱中
否则你可以使用某种轮盘选择过程.看到这个类似的问题(虽然不是MATLAB特定的).这是我的一行实现:
a = 1:3; %# possible numbers
w = [0.3 0.1 0.2]; %# corresponding weights
N = 10; %# how many numbers to generate
R = a( sum( bsxfun(@ge, rand(N,1), cumsum(w./sum(w))), 2) + 1 )
Run Code Online (Sandbox Code Playgroud)
说明:
考虑区间[0,1].我们为list(1:3
)中的每个元素分配一个长度与每个元素的权重成比例的子区间; 因此,1
获取和长度的区间0.3/(0.3+0.1+0.2)
,同为别人.
现在,如果我们生成一个均匀分布超过[0,1]的随机数,那么[0,1]中的任何数字都有相同的被选概率,因此子区间的长度决定了随机数落入的概率.每个间隔.
这符合我上面所做的:选择一个数字X~U [0,1](更像是N
数字),然后找到它以矢量化方式落入的间隔.
您可以通过生成足够大的序列来检查上述两种技术的结果N=1000
:
>> tabulate( R )
Value Count Percent
1 511 51.10%
2 160 16.00%
3 329 32.90%
Run Code Online (Sandbox Code Playgroud)
它或多或少与标准化权重相匹配 w./sum(w)
[0.5 0.16667 0.33333]
小智 16
amro给出了一个很好的答案(我对其进行了评分),但如果您希望从大型集合中生成许多数字,那么它将非常密集.这是因为bsxfun操作可以生成一个巨大的数组,然后将其求和.例如,假设我有一组10000个值来取样,所有都有不同的权重?现在,从该样本生成1000000个数字.
这将需要做一些工作,因为它将在内部生成10000x1000000数组,其中包含10 ^ 10个元素.它将是一个逻辑阵列,但即便如此,必须分配10千兆字节的内存.
更好的解决方案是使用histc.从而...
a = 1:3
w = [.3 .1 .2];
N = 10;
[~,R] = histc(rand(1,N),cumsum([0;w(:)./sum(w)]));
R = a(R)
R =
1 1 1 2 2 1 3 1 1 1
Run Code Online (Sandbox Code Playgroud)
但是,对于我上面建议的大型问题,它很快.
a = 1:10000;
w = rand(1,10000);
N = 1000000;
tic
[~,R] = histc(rand(1,N),cumsum([0;w(:)./sum(w)]));
R = a(R);
toc
Elapsed time is 0.120879 seconds.
Run Code Online (Sandbox Code Playgroud)
不可否认,我的版本需要2行才能编写.索引操作必须在第二行上进行,因为它使用histc的第二个输出.另请注意,我使用了新matlab版本的功能,使用波浪号(〜)运算符作为histc的第一个参数.这会导致第一个参数立即转储到位桶中.
归档时间: |
|
查看次数: |
23676 次 |
最近记录: |