[algorithm] 통계적 중앙값, 모드, 왜도, 첨도를 추정하기위한 “온라인”(반복자) 알고리즘?

값 집합의 중앙값, 모드, 왜도 및 / 또는 첨도를 추정하는 알고리즘이 있지만 한 번에 모든 값을 메모리에 저장할 필요는 없습니까?

기본 통계를 계산하고 싶습니다.

  • 평균 : 산술 평균
  • 분산 : 평균에서 제곱 된 편차의 평균
  • 표준 편차 : 분산의 제곱근
  • 중앙값 : 숫자의 큰 절반과 작은 절반을 구분하는 값
  • 모드 : 세트에서 가장 자주 발견되는 값
  • 왜도 : tl; 박사
  • 첨도 : tl; 박사

이것들 중 하나를 계산하는 기본 공식은 초등학교 산술이며, 나는 그것들을 알고 있습니다. 이를 구현하는 많은 통계 라이브러리도 있습니다.

내 문제는 내가 처리하고있는 집합에있는 많은 수 (십억)의 값입니다. Python으로 작업하면 수십억 개의 요소로 목록이나 해시를 만들 수 없습니다. 내가 이것을 C로 썼더라도 10 억 요소 배열은 너무 실용적이지 않습니다.

데이터가 정렬되지 않습니다. 다른 프로세스에 의해 즉석에서 무작위로 생성됩니다. 각 세트의 크기는 매우 가변적이며 크기는 미리 알 수 없습니다.

나는 이미 평균과 분산을 꽤 잘 처리하는 방법을 알아 냈고, 어떤 순서로든 세트의 각 값을 반복합니다. (사실, 제 경우에는 생성 된 순서대로 가져옵니다.) 다음은 제가 사용하는 알고리즘입니다. http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#On-line_algorithm :

  • 세 가지 변수 초기화 : 개수, 합계 및 sum_of_squares
  • 각 값에 대해 :
    • 증가 카운트.
    • 합계에 값을 더합니다.
    • sum_of_squares에 값의 제곱을 더합니다.
  • 합계를 개수로 나누고 변수 평균으로 저장합니다.
  • sum_of_squares를 개수로 나누고 변수 mean_of_squares로 저장합니다.
  • 제곱 평균, square_of_mean으로 저장합니다.
  • mean_of_squares에서 square_of_mean을 빼서 분산으로 저장합니다.
  • 출력 평균 및 분산.

이 “온라인”알고리즘에는 약점이 있지만 (예 : sum_of_squares가 정수 범위 또는 부동 소수점 정밀도보다 빠르게 커짐에 따른 정확도 문제) 기본적으로 각 세트에 모든 값을 저장할 필요없이 필요한 것을 제공합니다.

하지만 추가 통계 (중앙값, 모드, 왜도, 첨도)를 추정하는 데 유사한 기법이 있는지 여부는 알 수 없습니다. N 값을 처리하는 데 필요한 메모리가 실질적으로 O (N)보다 작은 한 편향된 추정기 또는 정확도를 어느 정도 저하시키는 방법으로 살 수 있습니다.

라이브러리에 “온라인”작업 중 하나 이상을 계산하는 함수가있는 경우 기존 통계 라이브러리를 가리키는 것도 도움이됩니다.



답변

왜도 및 첨도

왜도 및 첨도에 대한 온라인 알고리즘 (분산 선을 따라)에 대해서는 동일한 위키 페이지 에서 더 높은 순간 통계에 대한 병렬 알고리즘을 참조 하십시오 .

중앙값

정렬 된 데이터가 없으면 중앙값이 어렵습니다. 알고 있다면, 이론적으로는 선택 알고리즘 을 사용하여 부분적으로 만 정렬하면됩니다 . 그러나 그것은 수십억 개의 가치에 그다지 도움이되지 않습니다. 주파수 카운트를 사용하는 것이 좋습니다. 다음 섹션을 참조하십시오.

주파수 카운트가있는 중앙값 및 모드

정수인 경우 주파수를 계산
하여 더 이상 관련이 없다고 확신하는 일부 값을 넘어 가장 높은 값과 가장 낮은 값을 잘라냅니다. 실수 (또는 너무 많은 정수)의 경우 아마도 버킷 / 간격을 만든 다음 정수와 동일한 접근 방식을 사용합니다. (근사치) 모드 및 중앙값 계산은 빈도 표를 기반으로보다 쉬워집니다.

일반적으로 분포 된 랜덤 변수

정규 분포를 따르는 경우 모집단 표본 평균 , 분산 , 왜도첨도 를 작은 부분 집합에 대한 최대 가능성 추정기로 사용합니다. 그것들을 계산하는 (온라인) 알고리즘, 당신은 이미 지금. 예를 들어, 추정 오류가 충분히 작아 질 때까지 수십만 또는 백만 개의 데이터 포인트를 읽습니다. 세트에서 무작위로 선택해야합니다 (예 : 처음 100’000 개의 값을 선택하여 편향을 도입하지 않음). 동일한 접근 방식을 추정 모드에 사용할 수도 있고 정상 사례에 대한 중앙값을 사용할 수도 있습니다 (두 표본 평균은 모두 추정치입니다).

추가 의견

도움이된다면 위의 모든 알고리즘을 병렬로 실행할 수 있습니다 (많은 정렬 및 선택 알고리즘 (예 : QuickSort 및 QuickSelect) 포함).

나는 항상 (정규 분포에 대한 섹션을 제외하고) 우리가 알려진 분포가 주어진 이론적 모멘트에 대한 추정자가 아니라 샘플 모멘트, 중앙값 및 모드에 대해 이야기한다고 가정했습니다.

일반적으로 모든 관측치가 동일한 무작위 변수 (동일한 분포를 가짐)와 모멘트, 모드 및 중앙값은 실제로이 분포에 존재합니다. 마지막 경고는 무해하지 않습니다. 예를 들어, 코시 분포에 대한 평균 (및 모든 더 높은 모멘트)은 존재하지 않습니다. 이 경우 “작은”하위 집합의 표본 평균은 전체 표본의 표본 평균과 크게 다를 수 있습니다.


답변

나는 다음과 같은 증분 / 재귀 평균 및 중앙 추정치를 사용하는데, 둘 다 상수 저장을 사용합니다.

mean += eta * (sample - mean)
median += eta * sgn(sample - median)

여기서 eta 는 작은 학습률 매개 변수 (예 : 0.001)이고 sgn ()은 {-1, 0, 1} 중 하나를 반환하는 signum 함수입니다. ( 데이터가 비정상이고 시간에 따른 변화를 추적 하려면 상수 eta를 사용하십시오 . 그렇지 않으면 고정 소스의 경우 평균 추정량에 eta = 1 / n 과 같은 것을 사용할 수 있습니다 . 여기서 n은 표시되는 샘플 수입니다. 지금까지 … 안타깝게도 이것은 중앙값 추정치에서는 작동하지 않는 것 같습니다.)

이러한 유형의 증분 평균 추정기는 감독되지 않은 신경망 학습 규칙에서와 같이 모든 곳에서 사용되는 것처럼 보이지만, 중앙값 버전은 이점 (이상치에 대한 견고성)에도 불구하고 훨씬 덜 일반적으로 보입니다. 중앙값은 많은 응용 프로그램에서 평균 추정치를 대체 할 수있는 것으로 보입니다.

비슷한 형태의 증분 모드 추정기를보고 싶습니다.

최신 정보

임의의 분위수를 추정하기 위해 증분 중앙값 추정기를 수정했습니다. 일반적으로 Quantile 함수 ( http://en.wikipedia.org/wiki/Quantile_function )는 데이터를 p와 1-p의 두 분수로 나누는 값을 알려줍니다. 다음은이 값을 점진적으로 추정합니다.

quantile += eta * (sgn(sample - quantile) + 2.0 * p - 1.0)

값 p는 [0,1] 내에 있어야합니다. 이것은 본질적으로 sgn () 함수의 대칭 출력 {-1,0,1}을 한쪽으로 기울여 데이터 샘플을 크기가 다른 두 개의 빈으로 분할합니다 (데이터의 분수 p와 1-p는 다음보다 작거나 큼). 분위수 추정치). p = 0.5의 경우 이는 중앙 추정량으로 감소합니다.


답변

나는 LiveStats 라는 깔끔한 Python 모듈에서 관측 값저장하지 않고 Quantiles 및 Histograms의 동적 계산을위한 P-Square Algorithm을 구현했습니다 . 문제를 아주 효과적으로 해결해야합니다. 라이브러리는 모드를 제외하고 언급 한 모든 통계를 지원합니다. 모드 추정에 대한 만족스러운 솔루션을 아직 찾지 못했습니다.


답변

라이언, 당신이 평균과 분산을 제대로하지 못하고있는 것 같네요 … 이것은 몇 주 전에 여기에서 나왔습니다 . 그리고 온라인 버전의 강점 중 하나 (실제로 Welford의 방법이라는 이름으로 진행됨)는 그것이 특별히 정확하고 안정적이라는 사실입니다 . 여기 에서 토론을 참조 하십시오 . 장점 중 하나는 총합 또는 총 제곱합을 저장할 필요가 없다는 것입니다.

한 번에 전체 목록을 고려해야하는 것처럼 보이는 모드와 중앙값에 대한 온라인 접근 방식은 생각할 수 없습니다. 그러나 분산 및 평균에 대한 접근 방식과 유사한 접근 방식이 왜도 및 첨도에도 효과가있을 수 있습니다.


답변

질문에 인용 된 Wikipedia 기사에는 온라인으로 왜도 및 첨도를 계산하는 공식이 포함되어 있습니다.

모드의 경우-나는 이것을 온라인으로 할 방법이 없다고 생각합니다. 왜? 입력의 모든 값이 이전 값을 복제하는 마지막 값 외에 다른 것으로 가정하십시오. 이 경우 입력에서 볼 수있는 모든 값을 기억하여 마지막 값이 이전에 본 값을 복제하고 가장 빈번하게 만드는 값을 감지해야합니다.

중앙값의 경우 거의 동일합니다. 마지막 입력까지 모든 입력 값이 현재 중앙값 이전 또는 이후 일 수 있기 때문에 어떤 값이 중앙값이 될지 알 수 없습니다. 입력의 길이를 알고 있다면 모든 값을 메모리에 저장하지 않고도 중앙값을 찾을 수 있지만 잘못된 입력 시퀀스가 ​​중앙값을 크게 이동할 수 있기 때문에 여전히 많은 값을 저장해야합니다 (약 절반 정도). 후반부는 중앙값의 전반부에서 값을 만들 수 있습니다.

(정확한 계산만을 참조하고 있습니다.)


답변

수십억 개의 데이터 포인트가있는 경우 마감 답변이 아니라 정확한 답변이 필요하지 않을 수 있습니다. 일반적으로 수십억 개의 데이터 포인트가있는 경우이를 생성하는 기본 프로세스는 일종의 통계적 정상 성 / 에르 고딕 성 / 혼합 속성을 따를 가능성이 높습니다. 또한 분포가 합리적으로 연속적 일 것으로 예상하는지 여부도 중요 할 수 있습니다.

이러한 상황에서 정확한 답변이 필요하지 않은 경우 온라인, 낮은 메모리, 분위수 추정 (중앙값은 0.5 분위수의 특수한 경우)에 대한 알고리즘이 있습니다 . 이것은 통계의 활성 분야입니다.

분위수 추정 예 : http://www.computer.org/portal/web/csdl/doi/10.1109/WSC.2006.323014

모드 추정 예 : Bickel DR. 연속 데이터의 최빈값 및 왜도에 대한 강력한 추정량입니다. 계산 통계 및 데이터 분석. 2002; 39 : 153–163. 도이 : 10.1016 / S0167-9473 (01) 00057-3.

이들은 계산 통계의 활성 분야입니다. 가장 정확한 알고리즘은 하나도 없지만 다양한 속성, 가정 및 성능을 가진 다양한 알고리즘 (실제로는 통계적 추정기)이있는 분야에 진입하고 있습니다. 실험적인 수학입니다. 이 주제에 관한 논문이 수백 개에서 수천 개에 달할 것입니다.

마지막 질문은 왜도 및 첨도 자체가 정말로 필요한지 아니면 확률 분포를 특성화하는 데 더 신뢰할 수있는 다른 매개 변수가 더 필요한지 여부입니다 (확률 분포가 있다고 가정합니다!). 가우스를 기대하고 있습니까?

데이터를 대부분 가우 시아 어로 만들기 위해 데이터를 정리 / 전처리하는 방법이 있습니까? (예를 들어, 금융 거래 금액은 종종 로그를 취한 후 다소 가우스입니다). 유한 표준 편차를 기대하십니까? 뚱뚱한 꼬리를 기대하십니까? 관심있는 양이 꼬리 또는 대량입니까?


답변

모두가 온라인 방식으로 모드를 할 수 없다고 계속 말하지만 그것은 사실이 아닙니다. 다음은 예일 대학의 Michael E. Fischer와 Steven L. Salzberg가 1982 년에 발명 한 바로이 문제를 해결하기위한 알고리즘을 설명 하는 기사 입니다. 기사에서 :

다수 찾기 알고리즘은 스트림에서 단일 항목의 임시 저장을 위해 레지스터 중 하나를 사용합니다. 이 항목은 현재 다수 요소 후보입니다. 두 번째 레지스터는 0으로 초기화 된 카운터입니다. 스트림의 각 요소에 대해 알고리즘에 다음 루틴을 수행하도록 요청합니다. 카운터가 0이면 현재 스트림 요소를 새 다수 후보로 설치합니다 (이미 레지스터에있을 수있는 다른 요소를 대체). 그런 다음 현재 요소가 다수 후보와 일치하면 카운터를 증가시킵니다. 그렇지 않으면 카운터를 줄입니다. 사이클의이 시점에서 지금까지 본 스트림의 일부에 다수 요소가있는 경우 해당 요소는 후보 레지스터에 있으며 카운터는 0보다 큰 값을 보유합니다. 다수 요소가 없으면 어떻게됩니까? 스트림 환경에서는 불가능한 데이터를 두 번째로 전달하지 않으면 알고리즘이이 상황에서 항상 명확한 답변을 제공 할 수 없습니다. 다수의 요소가있는 경우이를 정확하게 식별 할뿐입니다.

더 많은 메모리가있는 상위 N 개를 찾기 위해 확장 할 수도 있지만 모드에 대해 해결해야합니다.