Home > other >  Best optimal way to rank items according to user choices
Best optimal way to rank items according to user choices

Time:05-22

I have received lists that shows user prefrences, now trying to find an optimal solutiont to sort them by considering all the users prefrences:

for example:

L1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
L2 = ['a', 'c', 'e', 'f', 'g', 'b', 'd']
L3 = ['g', 'f', 'e', 'd', 'a', 'c', 'b']

I was about to define a weight vector such as :

weight = [0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3]

Then converting lists to numerical values an multiply each list with this vector elementwise and then sorting them.

is this a good approach? any suggestion ?

CodePudding user response:

Assuming that the values in your L1, L2, L3 lists are all single characters then:

L1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
L2 = ['a', 'c', 'e', 'f', 'g', 'b', 'd']
L3 = ['g', 'f', 'e', 'd', 'a', 'c', 'b']

weights = [0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3]

for list_ in L1, L2, L3:
    nl = [c for _, c in sorted((ord(a[0]) * b, a) for a, b in zip(list_, weights))]
    print(nl)

ord() gives the Unicode value of a character as an integer. Take that value and multiply by the relevant weight.

Create a list of 2-tuples where (weighted_value, character).

Sort that list.

Print the characters from the newly sorted list.

Output:

['g', 'f', 'e', 'd', 'c', 'b', 'a']
['d', 'b', 'g', 'f', 'e', 'c', 'a']
['b', 'c', 'a', 'd', 'e', 'f', 'g']

Note:

As the lists only contain combinations of the letters a->g and because the weights are descending, this merely reverses the lists. However, try putting e.g., 'x' into one of the Ln lists and see what happens

CodePudding user response:

If I understood correctly you want to get the items ranking by looking at the overall votes of the users?

E.g., here a was ranked first by two users out of three and the other one ranked it third, so it should be considered the best one.

If yes, you can simply sort by the sum of the indices where each item appears in the lists:

d = dict((e, 0) for e in L1)

for l in [L1, L2, L3]:
    for i, el in enumerate(l):
        d[el]  = i
 
# Sorts in ascending order. Items ranked earlier will be positioned earlier.
sorted_votes = [v[0] for v in sorted(d.items(), key=lambda x: x[1])]

print(sorted_votes)
['a', 'c', 'e', 'f', 'g', 'b', 'd']

This way you don't need weights to convert votes to numbers to sort them. Their indices in the users rankings are the "weights" you need (smaller is better).

  • Related