2013-11-18 2 views
4

У меня есть список «продуктов», где у каждого есть две функции, например: цена и рейтинг для книг, или время и цена билетов и т. Д.
Книги (10, 15), где 10 это цена в долларах (дешевле лучше), а 15 - рейтинг от 0 до 100 (лучше - лучше).Сортировка по лучшим комбинациям из двух

L = [(150, 100), (50, 15), (20, 70), (10, 40), (76, 30)] 

Список следует сортировать по лучшей цене.
У меня есть 2 решения до сих пор, лучше всего найти «вес» для каждой пары, умножив price*(1/rating) и отсортировав по этому «весу», тем лучше.

res1 = {} 
for i in L: 
    res1[i] = i[0]*(1./i[1]) 
# {(10, 40): 0.25, (20, 70): 0.2857, (50, 15): 3.3333, (76, 30): 2.5333, (150, 100): 1.5} 
sorted(res1, key=lambda x: res1[x]) 
# [(10, 40), (20, 70), (150, 100), (76, 30), (50, 15)] 

Второе решение является более сложным и менее представительным. Для этого нужно сортировать два раза - по цене и по рейтингу (рейтинг - вспять) и пытаться найти матчи. «Вес» будет индексом в первом отсортированном списке, умноженным (или суммированным) на индекс во втором отсортированном списке.

L1 = sorted(L, key=lambda x: x[0]) 
L2 = sorted(L, key=lambda x: x[1], reverse=True) 
res = {} 
for i in L: 
    res[i] = (L1.index(i)+1) * (L2.index(i)+1) 
res 
# {(10, 40): 3, (20, 70): 4, (50, 15): 15, (76, 30): 16, (150, 100): 5} 
sorted(res, key=lambda x: res[x]) 
# [(10, 40), (20, 70), (150, 100), (50, 15), (76, 30)] 

При использовании второго варианта с большим количеством данных он показывает менее репрезентативные результаты.
Но я устал изобретать колесо, поэтому какие математические и алгоритмические решения вы можете предложить? Интересно, если у этого вопроса есть решение, когда есть 3 и более функций: цена, время доставки, вес, рейтинг и т. Д.

Обновление: Благодаря @georgesl для указания этого. Как я мог справиться с выбросами, например очень плохой книгой, но это очень дешево? Я думаю, что к ним нужно относиться как-то иначе.

+1

Я думаю, что первый из них уже хорош. Почему именно вам нужен новый алгоритм? – aIKid

+0

первого метода вполне достаточно. Однако вам нужно иметь дело с выбросами: например. книги, которые являются полным дерьмом, но действительно дешевым (поэтому с высоким соотношением цены за единицу стоимости) и книгами настолько хороши, что редакторы могут позволить себе поставить на него высокую цену. – lucasg

+0

Это не та же «цена» (1/оценка) '=' цена/рейтинг'? – itdxer

ответ

1

Почему вы не объедините ваши ответы, как этот

L = [(150, 100), (50, 15), (20, 70), (10, 40), (76, 30)] 
sorted(L, key=lambda x: x[0]/(x[1] * 1.0)) 
# [(10, 40), (20, 70), (150, 100), (76, 30), (50, 15)] 

P.S. Если вы хотите получить float ответ наилучшим образом, умножьте его на номер 1.0. Он работает быстрее, чем делят или запускает ваш номер в float

+0

Спасибо, ты прав :) – DominiCane

1

Ваша цель - заказать вашу продукцию в соответствии с «лучшей комбинацией» цены и рейтинга. Вы рассмотрели два алгоритма, и вы сообщаете, что первый, похоже, работает лучше. То, что вы нам не говорите, и вы, вероятно, не имеете, - это способ меры, какие заказы являются лучшими. Поэтому никто не может предложить лучший метод, потому что мы не знаем, что вам понравится. Насколько важно качество (рейтинг) для вас? Вы можете заботиться об этом больше или меньше, чем я. Короче: вам нужна либо независимая метрика доброты порядка (например, на основе количества людей, которые фактически покупают продукт), либо набор для обучения, который вы вручную заказали так, как хотите их видеть.

Предположим, у вас есть тренировочный набор, вы можете попробовать различный рейтинг и меру, насколько они близки к заказу, который вам нравится (по крайней мере, по данным обучения, но вы надеетесь, что алгоритм обобщается на другие данные). Один из способов измерения - статистика rank correlation.

Существует целое семейство решений, которые являются линейными комбинациями ваших возможностей: a * price + b * rating, где a, вероятно, отрицательный, поскольку низкая цена хорошая. Чем больше значение b, тем важнее рейтинг качества. Вы можете установить a и b, чтобы получить оптимальный рейтинг. Или вы можете «подгонять» более сложную модель, например. включая квадраты или отношения. Все, что вам нужно, - это способ оценить доброту результирующего заказа.

+0

Ваши вопросы о том, «что лучше», вполне уместны, я тоже подумал об этом, но у меня нет ответов. :) Только с здравым смыслом и практическим использованием я могу решить. Это очень хорошая идея с коэффициентами, я думал просто играть с метриками, такими как цена/рейтинг N *, но ваше решение с суммой лучше. – DominiCane

+0

Спасибо, но «только с здравым смыслом и практическим использованием» не совсем правильно: вы можете сделать себе оценочный набор, как я и предложил. Если вам это нравится, хорошо; но вы можете попробовать ** намного больше ** вариантов, если вам не нужно оценивать каждый результат вручную. – alexis

Смежные вопросы