簡體   English   中英

Python的Numpy np.random.choice的scala等效項是什么?(scala中的隨機加權選擇)

[英]What is the scala equivalent of Python's Numpy np.random.choice?(Random weighted selection in scala)

我在尋找Scala的等效代碼或python np.random.choice(Numpy為np)的基礎理論。 我有一個類似的實現,它使用Python的np.random.choice方法從概率分布中選擇隨機移動。

Python的代碼

輸入列表:['pooh','rabbit','piglet','Christopher']和概率:[0.5、0.1、0.1、0.3]

考慮到每個輸入元素的相關概率,我想從輸入列表中選擇一個值。

Scala標准庫沒有np.random.choice等效項,但是構建您自己的庫應該不難,具體取決於您要模擬的選項/功能。

例如,這里是一種獲取提交項目的無限Stream的方法,其中任一項目相對於其他項目加權的可能性。

def weightedSelect[T](input :(T,Int)*): Stream[T] = {
  val items  :Seq[T]    = input.flatMap{x => Seq.fill(x._2)(x._1)}
  def output :Stream[T] = util.Random.shuffle(items).toStream #::: output
  output
}

這樣,每個輸入項都有一個乘數。 因此,要獲得字符cv的無限偽隨機選擇,其中c占時間的3/5,而v占時間的2/5:

val cvs = weightedSelect(('c',3),('v',2))

因此, np.random.choice(aa_milne_arr,5,p=[0.5,0.1,0.1,0.3])示例的大致等效為:

weightedSelect("pooh"-> 5
              ,"rabbit" -> 1
              ,"piglet" -> 1
              ,"Christopher" -> 3).take(5).toArray

或者,也許您想要一個更好的(較少的偽)隨機分布,該分布可能會嚴重偏離。

def weightedSelect[T](items :Seq[T], distribution :Seq[Double]) :Stream[T] = {
  assert(items.length == distribution.length)
  assert(math.abs(1.0 - distribution.sum) < 0.001) // must be at least close

  val dsums  :Seq[Double] = distribution.scanLeft(0.0)(_+_).tail
  val distro :Seq[Double] = dsums.init :+ 1.1 // close a possible gap
  Stream.continually(items(distro.indexWhere(_ > util.Random.nextDouble())))
}

結果仍然是指定元素的無限Stream ,但是傳入的參數有些不同。

val choices :Stream[String] = weightedSelect( List("this"     , "that")
                                           , Array(4998/5000.0, 2/5000.0))

// let's test the distribution
val (choiceA, choiceB) = choices.take(10000).partition(_ == "this")

choiceA.length  //res0: Int = 9995
choiceB.length  //res1: Int = 5  (not bad)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM