3

로그 레코드를 저장할 때 여러 카테고리의 이동 평균을 합산하여 정리하고 싶습니다. 웹 서버 로그를 한 번에 한 항목 씩 저장하는 서비스를 상상해보십시오. 더 이상 상상해 봅시다. 기록 된 기록에 액세스 할 수 없습니다. 그래서 우리는 그것들을 한 번 보았지만 나중에 그들에게 접근 할 수는 없습니다. 다른 페이지에 대한가중 이동 평균을 효율적으로 저장하기위한 데이터 구조/알고리즘

, 나는

  • 는 "장기

    • (그래서 같은 한 달) (쉬운)
    • 는"최근 "평균 조회수의 총 수를 알고 싶습니다 "평균 (1 년 이상)

    엄청난 양의 데이터를 합산하여 재 계산하지 않고 이동 평균을 저장할 수있는 영리한 알고리즘/데이터 모델이 있습니까?

    정확한 평균 (정확히 30 일 정도)이 아니라 추세 지표 만 필요합니다. 따라서 어떤 모호함은 전혀 문제가되지 않습니다. 새로운 항목이 오래된 항목보다 더 높은 가중치를 가졌는지 확인해야합니다.

    한 가지 해결책은 매월 통계 레코드를 자동으로 만드는 것입니다. 그러나 지난 달의 통계조차 필요하지 않기 때문에 과도한 것처럼 보입니다. 그리고 그것은 나에게 움직이는 평균을주지는 않지만 매월 새로운 가치로 바꾸어 놓을 것입니다.

  • 답변

    7

    쉬운 해결책은 기하 급수적으로 감소하는 총계를 유지하는 것입니다.

    그것은 다음 식을 사용하여 계산 될 수

    :

    oldX가 전체의 이전 값
    newX = oldX * (p^(newT - oldT)) + delta 
    

    (시간 oldT에서) newX은 (시간 newT AT) 총의 새로운 값이다; delta은 새 이벤트가 전체에 미치는 영향입니다 (예 : 오늘 조회수). p은 1보다 작거나 같으며 감쇠 계수입니다. p = 1이라면 총 조회수가 있습니다. p을 줄이면 총계가 설명하는 간격이 효과적으로 줄어 듭니다.

    +0

    감사합니다. 'newT'와'oldT'에 유닉스 타임 스탬프를 사용하고, 델타를 1로 설정하는 것이 합리적일까요? (새로운 기록 된 레코드 각각에 대해 수식을 새로 평가하기 위해서)? –

    +0

    오트 윈 (Ortwin)은 공식을 적용하는 좋은 방법입니다. – Rotsor

    +0

    잘 작동하는 것 같습니다. 'p = 0.9'처럼 보이는 것은 10 시간 평균이고'p = 0.99'는 100 시간 평균입니다. –

    1

    당신이 정말로 원하는 모든 경우 다음 쉬운 일이 하나의 극 순환 IIR 필터를 사용하는 것입니다 일정하게 주어진 시간과 부드럽게 값 (일명 AR 또는 자동 회귀 필터 시계열 분석) . 이 형태 취 X_old 이전의 평활화 된 값이

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

    , X_new 새로운 평활화 값을, x는 현재의 데이터 지점이며, k는 시간 상수 (보통 작은 값 <을 결정하는 요인 0.1). 샘플 속도에 따라 경험적으로 두 개의 k 값 ("최근"에 대한 값 하나와 "장기에 대한 더 작은 값")을 결정해야 할 수도 있습니다.이 값은 이상적으로 합리적으로 일정해야합니다. 하루에 하나의 업데이트.

    +0

    시간대 (예 : 하루 기록 합계)에 중간 값을 저장하지 않으려 고하기 때문에 일정한 샘플 속도는 나와 있지 않습니다. 그래서 새로운 로그 레코드를받을 때 새로운 값을 바로 평가하고 싶습니다. –

    0

    귀하를위한 해결책 일 수 있습니다.

    시간 또는 날짜별로 그룹화 된 중간 저장 장치에 데이터를 집계 할 수 있습니다. 그룹화 기능은 매우 빠르게 작동합니다. 소량의 레코드를 그룹화해야하고 삽입도 빠르기 때문입니다. 당신까지의 정확한 결정.

    더 쉽게 계산할 수 있고 각 단계마다 수학을 필요로하지 않으므로 자동 상관 지수 알고리즘보다 우수 할 수 있습니다.

    마지막 기간 데이터의 경우 제한된 양의 레코드로 제한 량이있는 콜렉션을 사용할 수 있습니다. 이들은 MongoDB와 같은 일부 DB에서 기본적으로 지원합니다.

    관련 문제