使用gonum无需更换的加权采样

时间:2018-06-14 21:58:02

标签: go sampling gonum

我有大量的项目和另一个相同大小的权重数组。我想根据第二个数组的权重从第一个数组中取代而不进行替换。有没有办法使用gonum

执行此操作

1 个答案:

答案 0 :(得分:3)

Weighted及其相对方法.Take()看起来与您想要的完全一样。

来自doc:

func NewWeighted(w []float64, src *rand.Rand) Weighted
     

NewWeighted为权重Weighted返回w。如果srcnilrand.Rand将用作随机来源。请注意,从具有高方差或总体低绝对值和的权重中抽样可能会导致数值稳定性问题。

func (s Weighted) Take() (idx int, ok bool)
     

Take从加权中返回一个索引,其概率与项目的权重成比例。 然后将项目的权重设置为零。如果没有剩余项目,则Take会返回false

因此,Take确实是您无需替换即可获得的。

您可以使用NewWeighted创建具有给定权重的Weighted,然后使用Take以基于先前设置的权重的概率提取一个索引,然后选择以下项目:从您的样本数组中提取的索引。

工作示例:

package main

import (
    "fmt"
    "time"

    "golang.org/x/exp/rand"

    "gonum.org/v1/gonum/stat/sampleuv"
)

func main() {
    samples := []string{"hello", "world", "what's", "going", "on?"}
    weights := []float64{1.0, 0.55, 1.23, 1, 0.002}

    w := sampleuv.NewWeighted(
        weights,
        rand.New(rand.NewSource(uint64(time.Now().UnixNano())))
    )

    i, _ := w.Take()

    fmt.Println(samples[i])
}