使用 gonum 进行无放回加权采样
Weighted sampling without replacement using gonum
我有一大堆物品和另一堆相同大小的重量。我想根据第二个数组的权重从第一个数组中进行不替换的采样。有没有办法使用 gonum
?
Weighted
and its relative method .Take()
看起来和你想要的一模一样。
来自文档:
func NewWeighted(w []float64, src *rand.Rand) Weighted
NewWeighted
returns a Weighted
for the weights w
. If src
is nil
, rand.Rand
is used as the random source. Note that sampling from weights with a high variance or overall low absolute value sum may result in problems with numerical stability.
func (s Weighted) Take() (idx int, ok bool)
Take
returns an index from the Weighted with probability proportional to the weight of the item. The weight of the item is then set to zero. Take
returns false
if there are no items remaining.
因此Take
确实是你需要的无放回抽样
可以使用NewWeighted
创建一个给定权重的Weighted
,然后使用Take
根据之前设置的权重抽取一个概率的索引,然后select 从样本数组中提取的索引处的项目。
工作示例:
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])
}
我有一大堆物品和另一堆相同大小的重量。我想根据第二个数组的权重从第一个数组中进行不替换的采样。有没有办法使用 gonum
?
Weighted
and its relative method .Take()
看起来和你想要的一模一样。
来自文档:
func NewWeighted(w []float64, src *rand.Rand) Weighted
NewWeighted
returns aWeighted
for the weightsw
. Ifsrc
isnil
,rand.Rand
is used as the random source. Note that sampling from weights with a high variance or overall low absolute value sum may result in problems with numerical stability.func (s Weighted) Take() (idx int, ok bool)
Take
returns an index from the Weighted with probability proportional to the weight of the item. The weight of the item is then set to zero.Take
returnsfalse
if there are no items remaining.
因此Take
确实是你需要的无放回抽样
可以使用NewWeighted
创建一个给定权重的Weighted
,然后使用Take
根据之前设置的权重抽取一个概率的索引,然后select 从样本数组中提取的索引处的项目。
工作示例:
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])
}