2011-08-12 105 views
4

對於我的工作,我需要一些具有以下輸入和輸出的算法:如何決定權重?

輸入:一組日期(來自過去)。輸出:一組權重 - 每個給定日期一個權重(所有權重的總和= 1)。

的基本思想是,最接近的日期爲今天的日期應該得到最高的權重,第二個最接近的日期將得到第二高的權重,等等...

任何想法?

在此先感謝!

+0

爲什麼不只是用他們的排序順序「加權」呢?權重不會等於1,但您可以通過將每個值除以總和來輕鬆修復該權重。或者,每個重量可能是日期和今天之間的天數差異。不知道如何使用重量,沒有正確或錯誤的答案。 – mbeckish

+0

感謝您的回覆。這些權重將用於加權平均計算。 – Sash

+0

是的,但是你想計算什麼「加權平均」?例如,從2天前開始計算的數量是6天前的3倍?或者權重下降了(1/2)^ N?根據您的具體情況,您需要知道這一點。 – mbeckish

回答

5

首先,對於輸入集中的每個日期,分配日期和今天之間的時間量。

例如:以下日期集{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]導致除以零。一種避免被零除的方法叫做smoothing。 「平滑」數據的最簡單的方法是使用添加一個平滑處理,您只需爲每個值添加一個(所以今天變爲1,明天變爲2,下週變爲8等)。

現在最簡單的部分是規範化值,以便它們總計爲1。

sum = val[1] + val[2] + ... + val[n] 
weight[i] = val[i]/sum for each i 
+0

非常感謝!我想我會用1/val [i]的倒數值,因爲我希望兩個遙遠的日期之間有明顯的差異,而今天非常接近的日期有一個非常大的權重。 – Sash

+0

@Sash:1/val [i]可能會。如果你得到糟糕的結果,只需使用公式,直到你找到一個更好的公式。祝你好運。 – snakile

+0

非常感謝! – Sash

2
  • 排序日期並刪除DUP的
  • 分配值(也許從最遠日起在10或任何你需要的步驟 - 這些數值可以是任意的,他們只是反映了訂單和距離)
  • 規格化權重添加多達1級

可執行的僞代碼(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)] 
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。

昨天是1/2 3天前將1/4 等

+0

這實際上與第2點相同。在我的答案中,但是指數不同:-) – TMS

0

是是第i個日期索引。 指定等於Ni/D的權重。 D0是第一個日期。 Ni是第i個日期和第一個日期D0之間的天數差。 d是歸一化因子

1

如何重:剛纔計算的所有日期的差異和當前日期

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

(請注意,指數func被一直使用在生存統計人員分析)

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