对于我的工作,我需要一些具有以下输入和输出的算法:
输入:一组日期(来自过去)。输出:一组权重 - 每个给定日期一个权重(所有权重的总和= 1)。
基本的想法是,到今天的日期最近的日期应该得到最高的权重,第二个最接近的日期将获得第二高的权重,依此类推......
有什么想法吗?
提前致谢!
答案 0 :(得分:7)
首先,对于输入集中的每个日期,指定日期和今天之间的时间量。
例如:以下日期设置{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])
最难和最重要的部分是决定如何反转这些值。想想,权重的本质应该是什么? (你想要两个遥远日期之间的明显差异,或者两个遥远的日期应该具有相同的权重吗?你想要一个非常接近今天的日期具有更大的重量或相当大的重量?)。/ p>
请注意,您应该提出一个不能除以零的反转程序。在上面的示例中,除以val[i]
会导致除以零。避免被零除的一种方法称为smoothing。 “平滑”数据的最简单方法是使用添加一个平滑,您只需为每个值添加一个(因此今天变为1,明天变为2,下周变为8等)。
现在最简单的部分是规范化这些值,使它们总和为一个。
sum = val[1] + val[2] + ... + val[n]
weight[i] = val[i]/sum for each i
答案 1 :(得分:2)
可执行伪代码(tweakable):
#!/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)]
答案 2 :(得分:1)
如何加权:只计算所有日期和当前日期的差异
x(i) = abs(date(i) - current_date)
然后您可以使用不同的表达式来指定权重:
w(i) = 1/x(i)
w(i) = exp(-x(i))
w(i) = exp(-x(i)^2))
然后使用标准化权重:w(i)/sum(w(i))
以使总和为1.
(请注意,生存分析中统计学家总是使用指数函数)
答案 3 :(得分:0)
我首先考虑使用几何系列:
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 等等
答案 4 :(得分:0)
是第i个日期的索引。 分配权重等于Ni / D. D0是第一次约会。 Ni是第i个日期和第一个日期D0之间的天数差异。 D是归一化因子
答案 5 :(得分:0)
将日期转换为yyyymmddhhmiss格式(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