3

我想在存儲日誌記錄時總結移動多個不同類別的平均值。想象一下,一次保存Web服務器記錄一個條目的服務。讓我們進一步想象,我們無法訪問記錄的記錄。所以我們看到他們有一次,但以後沒有訪問它們。有效保存加權移動平均數的數據結構/算法

對於不同的網頁,我想知道

  • 命中總數(容易)
  • 一個「最近的」平均(如一個月或左右)
  • 一個「長期「平均(一年以上)

是否有任何聰明的算法/數據模型可以保存這樣的移動平均數,而不必通過求和大量數據來重新計算它們?

我不需要精確的平均值(正好30天左右),而只需要趨勢指標。所以有些模糊不是問題。它應該確保新條目的權重高於舊條目。

一個解決方案可能是爲每個月自動創建統計記錄。但是,我甚至不需要過去一個月的統計數據,所以這看起來好像過度。它不會給我一個移動平均值,而是每個月都會換成新的值。

回答

7

一個簡單的解決方案是保持指數衰減的總數。

它可以用下面的公式來計算:

newX = oldX * (p^(newT - oldT)) + delta 

其中oldX是總的舊值(在時間oldT),newX是你的總的(在時間newT)的新值; delta是新事件對總數的貢獻(例如今天的點擊次數); p小於或等於1並且是衰減因子。如果我們採取p = 1,那麼我們有總點擊數。通過減少p,我們有效地減少了我們總的描述的時間間隔。

+0

謝謝。對於'newT'和'oldT'使用UNIX時間戳,將'delta'設置爲1(以便爲每個新記錄的記錄新評估公式)是否合理? –

+0

Ortwin,當然,這是應用公式的好方法。 – Rotsor

+0

似乎很好。看起來像「p = 0.9」給了我10個時間單位的平均值,「p = 0.99」是100個時間單位的平均值。 –

1

如果你真正想要的是一個平滑值與給定時間常數那麼最簡單的就是用一個單極遞歸IIR濾波器(又名AR自迴歸濾波器在時間序列分析) 。此採取以下形式:

Xnew = k * X_old + (1 - k) * x 

其中X_old是先前的平滑值,X_new是新的平滑值,x是當前數據點並且k是確定的時間常數(通常是一個小的值,<的因子0.1)。根據您的採樣率,您可能需要根據經驗確定兩個k值(「近期」的一個值和「長期」的較小值),理想情況下應該是合理恆定的。每天更新一次。

+0

由於我希望避免在時間範圍內保存中間值(例如,每天的記錄總和),因此不會在我的情況下提供恆定採樣率。所以我想在收到新的日誌記錄時評估新的值。 –

0

這可能是您的解決方案。

您可以將數據聚合到按小時或天分組的中間存儲中。比分組功能將工作得非常快,因爲您需要將少量記錄分組並且插入速度也會很快。精確的決定取決於你。

它可以比自動相關的指數算法更好,因爲你可以更容易理解你計算的內容,而且它不需要每一步的數學計算。

對於上一期數據,您可以使用記錄數量有限的上限集合。他們本地支持一些數據庫,例如MongoDB。