Как определиться с весами? - PullRequest
       35

Как определиться с весами?

4 голосов
/ 12 августа 2011

Для моей работы мне нужен какой-то алгоритм со следующим вводом и выводом:

Ввод: набор дат (из прошлого).Вывод: набор весов - один вес на одну заданную дату (сумма всех весов = 1).

Основная идея состоит в том, что ближайшая к сегодняшней дате дата должна получить наибольший вес, вторая ближайшая датаполучит второе место по весу и так далее ...

Есть идеи?

Заранее спасибо!

Ответы [ 6 ]

7 голосов
/ 12 августа 2011

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

Например: следующая установленная дата {today, tomorrow, yesterday, a week from today} становится {0, 1, 1, 7}.Формально: val[i] = abs(today - date[i]).

Во-вторых, инвертируйте значения таким образом, чтобы их относительные веса были обращены.Самый простой способ сделать это: val[i] = 1/val[i].

Другие предложения:

  • val[i] = 1/val[i]^2
  • val[i] = 1/sqrt(val[i])
  • val[i] = 1/log(val[i])

Самая сложная и важная часть - решить, как инвертировать значения.Подумайте, какой должна быть природа гирь?(Вы хотите заметных различий между двумя отдаленными датами, или, может быть, две отдаленные даты должны иметь довольно равные веса? Хотите, чтобы даты, которые очень близки к сегодняшнему дню, имели чрезвычайно больший вес или разумно больший вес?).

Обратите внимание, что вы должны придумать процедуру инвертирования, где вы не можете делить на ноль.В приведенном выше примере деление на val[i] приводит к делению на ноль.Один метод, позволяющий избежать деления на ноль, называется сглаживанием .Самый простой способ «сгладить» ваши данные - это использовать сглаживание add-one, где вы просто добавляете единицу к каждому значению (таким образом, сегодня становится 1, завтра становится 2, следующая неделя становится 8 и т. Д.).

Теперь самое простое - нормализовать значения так, чтобы они суммировались до одного.

sum = val[1] + val[2] + ... + val[n]
weight[i] = val[i]/sum for each i
2 голосов
/ 12 августа 2011
  • Сортировка дат и удаление дубликатов
  • Назначение значений (возможно, начиная с самой последней даты с шагом 10 или чего угодно - эти значения могут быть произвольными, они просто отражают порядок и расстояние)
  • Нормализовать вес, чтобы добавить до 1

Исполняемый псевдокод (настраиваемый):

#!/usr/bin/env python

import random, pprint
from operator import itemgetter

# for simplicity's sake dates are integers here ...
pivot_date = 1000
past_dates = set(random.sample(range(1, pivot_date), 5))

weights, stepping = [], 10

for date in sorted(past_dates):
    weights.append( (date, stepping) )
    stepping += 10

sum_of_steppings = sum([ itemgetter(1)(x) for x in weights ])
normalized = [ (d, (w / float(sum_of_steppings)) ) for d, w in weights ]

pprint.pprint(normalized)

# Example output
# The 'date' closest to 1000 (here: 889) has the highest weight, 
# 703 the second highest, and so forth ...
# [(151, 0.06666666666666667),
#  (425, 0.13333333333333333),
#  (571, 0.2),
#  (703, 0.26666666666666666),
#  (889, 0.3333333333333333)]
1 голос
/ 12 августа 2011

Как взвесить: просто вычислите разницу между всеми датами и текущей датой

x(i) = abs(date(i) - current_date)

Затем вы можете использовать другое выражение для присвоения весов:

  1. w(i) = 1/x(i)
  2. w(i) = exp(-x(i))
  3. w(i) = exp(-x(i)^2))
  4. использование гауссовского распределения - более сложное, не рекомендуется

Затем используйтенормализованные веса: w(i)/sum(w(i)), так что сумма равна 1.

(обратите внимание, что экспоненциальная функция всегда используется статистиками при анализе выживаемости)

0 голосов
/ 12 августа 2011

преобразует даты в формат ггггммдччхмисс (24 часа), добавляет все эти значения и сумму, делит на общее время и сортирует по этому значению.

declare @data table
(
    Date bigint,
    Weight float
)
declare @sumTotal decimal(18,2)

insert into @Data (Date)
select top 100 
replace(replace(replace(convert(varchar,Datetime,20),'-',''),':',''),' ','')
from Dates

select @sumTotal=sum(Date)
from @Data

update @Data set
Weight=Date/@sumTotal

select * from @Data order by 2 desc
0 голосов
/ 12 августа 2011

Is - индекс для i-й даты. Назначьте веса, равные Ni / D. D0 это первое свидание. Ni - это разница в днях между i-й датой и первой датой D0. D - коэффициент нормализации

0 голосов
/ 12 августа 2011

Первое, что приходит мне в голову - использовать геометрическую серию:

http://en.wikipedia.org/wiki/Geometric_series

(1/2) + (1/4) + (1/8) + (1/16) + (1/32) + (1/64) + (1/128) + (1/256) ..... суммы к одному.

Вчера было бы 1/2 2 дня назад будет 1/4 и так далее

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...