在我的数据库中,我具有乐队列表以及“流行度”列,当用户在网页上分别按下“喜欢”或“不喜欢”按钮时,该列会递增或递减。我想根据此人气栏选择乐队。选择频段的可能性取决于此受欢迎程度列,该列是整数值,而不是像0.3、0.1这样的十进制值,如果有人以概率工作,这应该是有道理的,但就我而言,我认为这是可能的。我的桌子的例子:

Bands        probability
Led Zeppelin    79
Megadeth         4
Queen           37
Aerosmith       20
Guns N Roses   103


基于此,Guns N'Roses应该有最高的入选机会,而Megadeth的入选机会则最低,而其他乐队也都有各自的入选机会。我将从2000个列表中选择10个波段。

最佳答案

首先,为每个频段计算cumulative probability(排序顺序是任意的;您也可以使用一些ID):



SELECT Band,
       CAST((SELECT sum(probability)
             FROM Bands AS b2
             WHERE b2.Band <= Bands.Band
            ) AS FLOAT) /
       (SELECT sum(probability) FROM Bands)
       AS CumProb
FROM Bands
ORDER BY Band;




Band             CumProb
---------------  ---------------
Aerosmith        0.0823045267489
Guns N Roses     0.5061728395061
Led Zeppelin     0.8312757201646
Megadeth         0.8477366255144
Queen            1.0


(只要SQLite还没有窗口函数,用Python进行求和将更有效。但是对于2000行,这并不重要。)

然后使用介于0和1之间的随机数来查找其中的一行(第一个等于或更大的行):

WITH CPBands(Band, CumProb) AS (
  SELECT Band,
         CAST((SELECT sum(probability)
               FROM Bands AS b2
               WHERE b2.Band <= Bands.Band
              ) AS FLOAT) /
         (SELECT sum(probability) FROM Bands)
  FROM Bands
)
SELECT Band
FROM CPBands
WHERE CumProb >= ?
ORDER BY CumProb ASC
LIMIT 1;


根据需要重复执行,忽略重复项。

09-04 21:46
查看更多