【问题标题】:Rate (probability) based selection基于速率(概率)的选择
【发布时间】:2014-07-26 12:48:41
【问题描述】:

假设我有一个这样的结构化数组:

[
  'A' => 2,
  'B' => 0,
  'C' => 0,
  'D' => 1,
  'E' => 1,
  'F' => 0
]

我将这个结构称为“类别”,因此,我在这个数组中有六个类别。 我的目标是根据一个类别随机选择一个产品。

我想做一个基于速率的类别选择,据我所知,我必须计算这个类别在数组中代表的百分比,例如:

<?php

// ...

$total = array_sum($a);

array_map(function ($hits) use ($total) {
  return $hits / $total;
}, ...);

这会给我类似的东西:

(
    [A] => 0.5  (50%)
    [B] => 0
    [C] => 0
    [D] => 0.25 (25%)
    [E] => 0.25 (25%)
    [F] => 0
)

好的,现在我必须做一个简单的算法来根据这些费率获取类别;我想我现在需要在(0, 1) 范围内选择一个随机数,并制作一些“切片”,例如:

0    .. 0.50   => A
0.50 .. 0.25   => D
0.75 .. 1      => E

如果随机数在00.50之间,我会选择类别A,如果在0.500.75之间,那么D,如果在0.751之间,那么E,当然是我现在正在做的事情。

问题

如果我这样做,我完全从数学和逻辑上说,我永远不会得到BCF,因为这些类别没有命中(那时没有切片。)

如何避免这种情况?我必须给这些类别一些机会,但很少(这意味着并非不可能)。

【问题讨论】:

  • 嗯,你可以 f.e.将1 的值添加 到您的第一个数组中的每个类别值……这意味着A 之后将具有3 的值,b 将具有1,等等……这将阻止您的空类别在以后产生空的“切片”。
  • 如果您认为过于强调空类别,那么选择不同的“算法” – f.e. 每个值乘以2510之前加上1;这将更加强调那些一开始就不是空的类别。我建议你进行一些不同变化的测试运行,假设每个 10.000 次“平局”——然后你查看结果并找出哪个版本给出了你“最喜欢”的结果……
  • 扩展@CBroe 所说的内容,您可以使用公式(coefficient) = 1.0 / ( (sum of categories) * (minimal probability) ) 来选择特定的最小概率。尽管可能仍需要进行实验。

标签: php math probability rate


【解决方案1】:

您可以使用将每个类别重复hits 次的分布数组。然后您可以简单地从该数组中获取一个随机元素。

有点像这样:

$distr = array();
array_walk($a, function ($hits, $cate) use ($distr) {
  $distr = array_merge($distr, array_fill(0, $hits, $cate));
});

$index = mt_rand(0, count($distr) - 1);
$random_cate = $distr[$index];

【讨论】:

  • 这不是“随机元素”,有一些费率,我不能简单地“随机获取”。
  • @Andrey Knupp Vital 假设每个类别在 $distr 数组中重复的次数与原始数组中给出的次数相同,它可以给你想要的结果
  • 你是对的,对不起。我现在明白了你的想法。我修改了你的代码,见:gist.github.com/andreyknupp/c36cf9ef42747879f9d6 结果是出现次数,能不能提高性能?你有什么建议吗?
  • @Andrey Knupp Vital 我认为您可以将$distr 数组创建的代码与categ 函数分开。所以它只会被填充一次。
【解决方案2】:

您所拥有的是一个随机变量 X,它将采用 S = {A, B, C, D, E, F} 中的值之一。

P(X = A) = 1/2
P(X = B) = 0
等等

定义一个新的均匀随机变量 Y,其中 P(Y = A) = P(Y = B) = ... = P(Y = F) = 1 / |S|如果 T = 0,则随机变量 Z = X,如果 T = 1,则 Z = Y,其中 T 是伯努利随机变量,P(T = 1) = t 且 P(T = 0) = 1 - t。

那么对于S中的所有s,

P(Z = s) = P(Z = s | T = 0) P(T = 0) + P(Z = s | T = 1) P(T = 1) = (1 - t) P (X = s) + t / |S|

使用这个模型,你只需要选择[0,1]中的参数t,其中t表示从S中均匀随机选择的概率。t = 0是你当前的模型,其中B,C,而 F 永远不会发生。

【讨论】:

    猜你喜欢
    • 2021-10-10
    • 2013-12-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-20
    相关资源
    最近更新 更多