代码之家  ›  专栏  ›  技术社区  ›  alpaca

加权抽样,无需更换。

  •  4
  • alpaca  · 技术社区  · 7 年前

    我有一个大的项目数组和另一个相同大小的权重数组。我想根据第二个数组的权重,在不替换第一个数组的情况下进行采样。有没有办法用 gonum 是吗?

    1 回复  |  直到 7 年前
        1
  •  3
  •   Marco Bonelli    7 年前

    Weighted 及其相关方法 .Take() 看起来和你想要的一模一样。

    从文件:

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

    NewWeighted 返回 加权 对于重量 w .如果 src nil ,请 rand.Rand 用作随机源。请注意,从具有高方差或整体低绝对值和的权重中抽样可能会导致数值稳定性问题。

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

    Take 返回加权后的索引,其概率与项的权重成比例。 然后将该项的权重设置为零 . 采取 退货 false 如果没有剩余项目。

    因此 采取 确实是不需要更换的采样所需要的。

    你可以用 NewWeighted 创建 加权 用给定的重量,然后使用 采取 要根据先前设置的权重用概率提取一个索引,然后从样本数组中选择提取索引处的项。


    工作示例:

    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])
    }