Алгоритм ранжирования предметов - PullRequest
9 голосов
/ 05 января 2011

У меня есть список из 6500 предметов, в которые я хотел бы обменять или вложить деньги. (Не на реальные деньги, а для определенной игры.) Каждый предмет имеет 5 номеров, которые будут использоваться для ранжирования его среди других.

Общее количество предметов, проданных за день: Чем выше это число, тем лучше.

Канал Дончиана предмета за последние 5 дней: Чем выше это число, тем лучше.

Медианный спред цены: Чем меньше это число, тем лучше.

Спред 20-дневной скользящей средней для элемента: Чем меньше это число, тем лучше.

Спред 5-дневной скользящей средней для элемента: Чем выше это число, тем лучше.

Все 5 чисел имеют одинаковый «вес», или, другими словами, все они должны влиять на конечное число в одинаковой стоимости или значении.

В данный момент я просто умножаю все 5 чисел для каждого предмета, но это не ранжирует предметы так, как я бы их оценил. Я просто хочу объединить все 5 чисел в взвешенное число, которое я могу использовать для ранжирования всех 6500 предметов, но я не уверен, как это сделать правильно или математически.

Примечание. Общее количество предмета, торгуемого за день, и канал Дончиана - это числа, которые намного выше, чем спреды, которые являются более числами процентного типа. Это, вероятно, причина, почему умножение их всех вместе не работало для меня; количество сделок за день и канал Дончиана сыграли гораздо большую роль в финальном числе.

Ответы [ 5 ]

14 голосов
/ 05 января 2011

Причина, по которой людям трудно ответить на этот вопрос, заключается в том, что у нас нет возможности сравнивать два разных «атрибута».Если бы было только два атрибута, скажем, количество сделок и средний разброс цен, было бы (20 миллионов, 50%) хуже или лучше, чем (100,1%)?Только вы можете решить это.

Преобразование всего в числа одинакового размера может помочь, это то, что называется "нормализацией".Хороший способ сделать это - z-счет, который упоминает Прасад.Это статистическая концепция, показывающая, как меняется количество.Вам нужно сделать некоторые предположения о статистическом распределении ваших чисел, чтобы использовать это.

Такие вещи, как спреды, вероятно, обычно распределены - в форме нормального распределения .Для них, как говорит Прасад, возьмите z(spread) = (spread-mean(spreads))/standardDeviation(spreads).

Такие вещи, как количество, которое можно обменять, могут быть Степенное распределение .Для этого вы можете взять log() до вычисления среднего и SD.То есть оценка z равна z(qty) = (log(qty)-mean(log(quantities)))/sd(log(quantities)).

Затем просто сложите оценку z для каждого атрибута.

Чтобы сделать это для каждого атрибута, вам необходимо иметь представление о его распределении.,Вы можете догадаться, но лучший способ - это построить график и посмотреть.Вы также можете построить графики в логарифмическом масштабе.См. википедию для длинного списка .

5 голосов
/ 05 января 2011

Вы можете заменить каждый атрибут-вектор x (длиной N = 6500) на z-счет вектора Z(x), где

Z(x) = (x - mean(x))/sd(x).

Это будетпреобразовать их в ту же «шкалу», а затем вы можете сложить Z-баллы (с равными весами), чтобы получить окончательный балл, и ранжировать элементы N=6500 по этому общему баллу.Если вы можете найти в своей задаче какой-либо другой атрибут-вектор, который был бы индикатором «благости» (скажем, 10-дневный возврат ценной бумаги?), То вы могли бы сопоставить регрессионную модель этого прогнозируемого атрибута с этими z-балламипеременные, чтобы выяснить лучшие неоднородные веса.

3 голосов
/ 05 января 2011

Начните каждый элемент с оценки 0. Для каждого из 5 чисел отсортируйте список по этому числу и добавьте рейтинг каждого элемента в этой сортировке к его оценке.Затем просто отсортируйте элементы по комбинированному баллу.

2 голосов
/ 05 января 2011

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

Для каждого дня получать все записи для данного типа, получите самый высокий и самый низкий из них, определите разницу между ними.Пусть Bottom = значение самого низкого, Range = разница между самым высоким и самым низким.Затем вы рассчитываете для каждой записи (значение - снизу) / диапазон, что приведет к что-то между 0,0 и 1,0.Это числа, с которыми вы можете продолжать работать, затем.

Псевдокод (скобки заменены на отступы для облегчения чтения):

double maxvalues[5]; 
double minvalues[5];
// init arrays with any item
for(i=0; i<5; i++)
   maxvalues[i] = items[0][i]; 
   minvalues[i] = items[0][i]; 
// find minimum and maximum values
foreach (items as item)
   for(i=0; i<5; i++)
       if (minvalues[i] > item[i])
           minvalues[i] = item[i];
       if (maxvalues[i] < item[i])
           maxvalues[i] = item[i];

// now scale them - in this case, to the range of 0 to 1.
double scaledItems[sizeof(items)][5]; 
double t;
foreach(i=0; i<5; i++)
   double delta = maxvalues[i] - minvalues[i];
   foreach(j=sizeof(items)-1; j>=0; --j)
      scaledItems[j][i] = (items[j][i] - minvalues[i]) / delta; 
      // linear normalization

что-то в этом роде.Я буду более элегантным с хорошей библиотекой (STL, boost, все, что у вас есть на платформе реализации), и нормализация должна быть в отдельной функции, так что вы можете заменить ее другими вариациями, такими как log (), когда возникнет такая необходимость.

0 голосов
/ 29 июля 2016

Общее количество предметов, проданных за день: чем выше это число, тем лучше. (А)

Канал Дончиана предмета за последние 5 дней: чем выше это число, тем лучше. (Б)

Медианный спред цены: чем меньше это число, тем лучше. (С)

Спред 20-дневной скользящей средней для элемента: чем меньше это число, тем лучше. (Г)

Спред 5-дневной скользящей средней для элемента: чем выше это число, тем лучше. (Е)

a + b -c -d + e = "оценка" (более высокая оценка = лучшая оценка)

...