Я строю систему в Clojure, которая потребляет события в режиме реального времени и действует на них в соответствии с тем, сколько похожих сообщений было получено за последнее время.Я хотел бы реализовать это, используя показатель недавности, основанный на ньютоновском охлаждении.
Другими словами, когда приходит событие, я хочу иметь возможность присвоить ему оценку от 1,0 (никогда раньше не было или «температура окружающей среды» в уравнении Ньютона) до 10,0 (горячее горячее горячее, произошлонесколько раз за последнюю минуту).
У меня есть смутное представление о том, как выглядит эта структура данных - каждый «тип события» является ключом карты, и каждое значение карты должно содержать некоторый набор временных меток для предыдущих событий.и, возможно, скользящее среднее значение текущей «высокой температуры» для этого типа события, но я не могу понять, как начать реализовывать дальше.В частности, мне трудно понять, как перейти от фактического уравнения Ньютона, которое является очень общим, и применить его к этому конкретному сценарию.
Есть ли у кого-нибудь указатели?Может ли кто-нибудь предложить более простой «алгоритм оценки недавности», чтобы начать меня, который можно было бы заменить ньютоновским охлаждением на дороге?
РЕДАКТИРОВАТЬ : Вот некоторый код clojure!Он ссылается на события как на буквы, но, очевидно, может быть перенаправлен на любой другой объект.
(ns heater.core
(:require [clojure.contrib.generic.math-functions :as math]))
(def letter-recency-map (ref {}))
(def MIN-TEMP 1.0)
(def MAX-TEMP 10.0)
;; Cooling time is 15 seconds
(def COOLING-TIME 15000)
;; Events required to reach max heat
(def EVENTS-TO-HEAT 5.0)
(defn temp-since [t since now]
(+
MIN-TEMP
(*
(math/exp (/
(- (- now since))
COOLING-TIME))
(- t MIN-TEMP))))
(defn temp-post-event [temp-pre-event]
(+ temp-pre-event
(/
(- MAX-TEMP temp-pre-event)
EVENTS-TO-HEAT)))
(defn get-letter-heat [letter]
(dosync
(let [heat-record (get (ensure letter-recency-map) letter)]
(if (= heat-record nil)
(do
(alter letter-recency-map conj {letter {:time (System/currentTimeMillis) :heat 1.0}})
MIN-TEMP)
(let [now (System/currentTimeMillis)
new-temp-cooled (temp-since (:heat heat-record) (:time heat-record) now)
new-temp-event (temp-post-event new-temp-cooled)]
(alter letter-recency-map conj {letter {:time now :heat new-temp-event}})
new-temp-event)))))