考虑以下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]
另请参阅
经过一点搜索,我发现了一个类似的问题:
- 随机排序有偏差的列表