如何根据列表元素的属性对列表进行概率排序



考虑以下User对象示例:

import numpy as np

class User:
def __init__(self, name, rating, actual_rating):
self.name: str = name
self.rating: int = rating
# Actual States
self.actual_rating: int = actual_rating
users = []
for actual_rating in np.random.binomial(10000, 0.157, 1000):
users.append(
User(str(random()), 1500, actual_rating)
)

# Sorting Users Randomly
sorted_users = []

如何对该users列表进行排序,使得对象在sorted_users中的索引较低的可能性取决于actual_rating是否较高。例如,随机User("0.5465454", 1500, 1678)将具有比User("0.7689989", 1500, 1400)更高的被排序为处于sorted_users列表的索引0的可能性。

如果可能的话,有没有一种简洁易读的方法可以做到这一点?

为每个用户生成一个随机值,然后根据该值进行排序

第一次为每个用户生成一个来自高斯分布的随机数,平均值为actual_rading,怎么样?然后根据这个随机数进行排序,而不是直接根据actual_rading进行排序。

stddev = 1.0   # the larger this number, the more shuffled the list - the smaller, the more sorted the list
sorted_users = sorted(users, key=lambda u:np.random.normal(u.actual_rating, stddev))

注意参数stddev,您可以根据需要进行调整。此参数越高,列表最终的混乱程度就越高。

对列表进行排序,然后轻轻地洗牌

灵感来自如何在python中轻松洗牌列表?

根据actual_rating对列表进行排序,然后轻轻地洗牌。

sorted_users = sorted(users, key=lambda u:u.actual_rating)
nb_passes = 3
proba_swap = 0.25
for k in range(nb_passes):
for i in range(k%2, len(sorted_users) - 1, 2):
if random() < proba_swap:
sorted_users[i], sorted_users[i+1] = sorted_users[i+1], sorted_users[i]

注意两个参数nb_passes(正整数(和proba_swap(介于0.0和1.0之间(,您可以调整它们以更好地满足您的需求。

不使用固定参数proba_swap,您可以根据两个用户的实际评级的接近程度来制定交换概率的公式,例如,对于某些正参数a,使用def proba_swap(r1,r2): return math.exp(-a*(r1-r2)**2)/2.0

或者:

sorted_users = sorted(users, key=lambda u:u.actual_rating)
nb_swaps = int(1.5 * len(sorted_users))  # parameter to experiment with
for i in random.choices(range(len(sorted_users)-1), k=nb_swaps):
sorted_users[i], sorted_users[i+1] = sorted_users[i+1], sorted_users[i]

另请参阅

经过一点搜索,我发现了一个类似的问题:

  • 随机排序有偏差的列表

最新更新