2

我正在阅读基于给定权重向量对数组进行重新采样的 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;

}

4

1 回答 1

0

第一个代码片段:

Utils.normalize(probabilities, sumProbs / sumOfWeights);

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

probabilities[numInstances() - 1] = sumOfWeights;

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

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

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

0                                                   sumOfWeights
↓                                                       ↓

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

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

该方法的后半部分简单地计算*每个权重区间(由 表示)中有多少随机分区边界(由 表示^)。稍微考虑一下应该会让您相信这是根据给定权重随机抽样并替换的有效方法。

于 2012-12-06T23:00:40.447 回答