【问题标题】:questions on random selection based on given weight vector基于给定权重向量的随机选择问题
【发布时间】:2012-11-25 02:14:00
【问题描述】:

我正在阅读基于给定权重向量对数组进行重新采样的 weka 实现。通读代码后,我不确定这个实现的底层算法是什么。另外,这两行代码的用法让我很困惑:

  Utils.normalize(probabilities, sumProbs / sumOfWeights);

// Make sure that rounding errors don't mess things up
probabilities[numInstances() - 1] = sumOfWeights;

我不知道它们是做什么用的。以下是从Weka复制的代码

Instances weka::core::Instances::resampleWithWeights(Random random,double[] weights )       
{

if (weights.length != numInstances()) {
  throw new IllegalArgumentException("weights.length != numInstances.");
}
Instances newData = new Instances(this, numInstances());
if (numInstances() == 0) {
  return newData;
}
double[] probabilities = new double[numInstances()];
double sumProbs = 0, sumOfWeights = Utils.sum(weights);
for (int i = 0; i < numInstances(); i++) {
  sumProbs += random.nextDouble();
  probabilities[i] = sumProbs;
}
Utils.normalize(probabilities, sumProbs / sumOfWeights);

// Make sure that rounding errors don't mess things up
probabilities[numInstances() - 1] = sumOfWeights;
int k = 0; int l = 0;
sumProbs = 0;
while ((k < numInstances() && (l < numInstances()))) {
  if (weights[l] < 0) {
  throw new IllegalArgumentException("Weights have to be positive.");
  }
  sumProbs += weights[l];
  while ((k < numInstances()) &&
       (probabilities[k] <= sumProbs)) { 
  newData.add(instance(l));
  newData.instance(k).setWeight(1);
  k++;
  }
  l++;
}
return newData;

}

【问题讨论】:

  • 看起来有些 C++ 已经泄漏到你的 Java 中了。 weka::core::Instances::resampleWithWeights不应该是weka.core.Instances.resampleWithWeights吗?
  • 什么是 Weka?您能否将我们链接到相关文章?
  • @BlueRaja-DannyPflughoeft - 看看tag wiki for Weka

标签: java algorithm random weka sample


【解决方案1】:

第一个代码片段:

Utils.normalize(probabilities, sumProbs / sumOfWeights);

只需将probabilities 的每个元素除以第二个参数。这会将probabilities 从最大元素为sumProbs 的数组转换为最大元素为sumOfWeights 的数组。第二段代码:

probabilities[numInstances() - 1] = sumOfWeights;

只是确保最后一个(最大)元素实际上是 sumOfWeights 并且没有被某种舍入错误丢弃。

编辑这是关于整个方法如何工作的理论。前半部分(直到 kl 的声明)生成 probabilities 作为(非独立)随机数的向量,这些随机数正在增加,最后一个是权重的总和。这是区间 [0, sumOfWeights] 的随机分区。现在权重本身是同一区间的一个分区。隐式地,每个现有实例都分配给基于权重的分区的每个元素。

该方法的后半部分简单地沿着权重分区(使用索引l)。它对lth 实例的采样次数与随机分区落在指定权重分区中的次数一样多。我意识到这个解释的措辞有点尴尬。也许正在发生的事情的图片会有所帮助:

0                                                   sumOfWeights
↓                                                       ↓

|     *   *         *       *               * *     *   * ← Random partition
|    ^      ^           ^      ^     ^     ^         ^  ^ ← Weights partition

   0     2        1        1       0     0       3     1  ← # of samples

该方法的后半部分仅计算每个权重区间(以^ 为界)中有多少随机分区边界(以* 表示)。稍加考虑就会使您相信这是根据给定权重随机抽样并替换的有效方法。

【讨论】:

  • 你能详细说明这个实现的底层算法是什么吗?我想这应该是一些既定的算法。但我不知道是哪个。
  • @user288609 - 我在回答中添加了解释。
  • Ted,感谢您帮助解释这一点。这个算法/​​启发式有名称吗?谢谢
  • @user288609 - 可能有一个名字,但我不知道它叫什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-29
  • 1970-01-01
  • 2012-05-20
  • 1970-01-01
  • 2015-07-05
相关资源
最近更新 更多