저장하기에 너무 큰 데이터 세트의 중앙값을 추정하여 각 값을 한 번만 읽을 수 있도록 (해당 값을 명시 적으로 저장하지 않는 한) 좋은 알고리즘 (최소 계산, 최소 스토리지 요구 사항)을 찾고 있습니다. 추정 할 수있는 데이터에는 한계가 없습니다.
정확도가 알려진 한 근사치가 좋습니다.
어떤 포인터?
저장하기에 너무 큰 데이터 세트의 중앙값을 추정하여 각 값을 한 번만 읽을 수 있도록 (해당 값을 명시 적으로 저장하지 않는 한) 좋은 알고리즘 (최소 계산, 최소 스토리지 요구 사항)을 찾고 있습니다. 추정 할 수있는 데이터에는 한계가 없습니다.
정확도가 알려진 한 근사치가 좋습니다.
어떤 포인터?
답변:
각 그룹의 중앙값을 계산 한 경우 데이터 세트를 훨씬 더 작은 데이터 세트 (예 : 100 또는 1000 또는 10,000 데이터 포인트)로 그룹화 할 수 있습니까? 충분한 데이터 세트로이 작업을 수행 한 경우, 더 작은 데이터 세트를 실행하면 '평균'솔루션으로 수렴하여 각 작은 세트 및이 woul의 평균 결과와 같은 것을 그릴 수 있습니다.
비닝 절차와 같은 것은 어떻습니까? 값이 백만에서 백만 사이임을 아는 것으로 (예시 적으로) 가정하십시오. 크기가 S 인 N 빈을 설정합니다. 따라서 S = 10000 인 경우 값 [1 : 10000, 10001 : 20000, ..., 990001 : 1000000]에 해당하는 100 개의 빈을 갖게됩니다.
그런 다음 값을 단계별로 살펴보십시오. 각 값을 저장하는 대신 적절한 빈에서 카운터를 늘리십시오. 각 구간의 중간 점을 추정값으로 사용하면 중간 값을 합리적으로 근사화 할 수 있습니다. 출력 함의 크기를 변경하여 원하는 해상도로 세밀하게 조정할 수 있습니다. 당신은 당신이 가진 메모리의 양에 의해서만 제한됩니다.
값이 얼마나 큰지 알지 못하므로 빠른 백 오브 백 계산을 사용하여 메모리가 부족하지 않을 정도로 큰 빈 크기를 선택하십시오. 빈이 희박하게 저장되어 빈이 값을 포함하는 경우에만 빈을 추가 할 수 있습니다.
편집하다:
링크 ryfm은 중간 지점을 사용하는 대신 누적 비율을 사용하여 중앙 빈 내의 지점을보다 정확하게 추정하는 추가 단계와 함께이 작업을 수행하는 예를 제공합니다. 이것은 좋은 개선입니다.
Rivest에-Tarjan-선택 알고리즘은 당신이 어떤 정렬하지 않고 선형 시간에 중간 요소를 계산하게됩니다 (때로는 중간 - 중 - 중간 값 알고리즘이라고합니다). 큰 데이터 세트의 경우 로그 선형 정렬보다 훨씬 빠릅니다. 그러나 메모리 저장 문제를 해결하지는 못합니다.
나는 이것을 할 필요가 없었으므로 이것은 단지 제안 일뿐입니다.
두 가지 다른 가능성이 있습니다.
반 데이터
샘플링 분포
다른 옵션은 샘플링 분포와 관련된 근사값을 사용하는 것입니다. 데이터가 보통이면 중간 n 의 표준 오차는 다음과 같습니다.
1.253 * sd / sqrt (n)
n 의 크기를 결정하기 위해 R에서 빠른 Monte-Carlo 시뮬레이션을 실행했습니다.
n = 10000
outside.ci.uni = 0
outside.ci.nor = 0
N=1000
for(i in 1:N){
#Theoretical median is 0
uni = runif(n, -10, 10)
nor = rnorm(n, 0, 10)
if(abs(median(uni)) > 1.96*1.253*sd(uni)/sqrt(n))
outside.ci.uni = outside.ci.uni + 1
if(abs(median(nor)) > 1.96*1.253*sd(nor)/sqrt(n))
outside.ci.nor = outside.ci.nor + 1
}
outside.ci.uni/N
outside.ci.nor/N
n = 10000의 경우, 균일 한 중앙값 추정치의 15 %가 CI 외부에있었습니다.
그룹화 된 주파수 분포를 기반으로 중앙값을 찾으려고 시도 할 수 있습니다. 여기에 몇 가지 세부 사항이 있습니다.
다음은 질문에 대한 답변에 유래에 질문 있어요 : https://stackoverflow.com/questions/1058813/on-line-iterator-algorithms-for-estimating-statistical-median-mode-skewness/2144754#2144754
반복 업데이트 중앙값 + = eta * sgn (sample-median)은 갈 수있는 것처럼 들립니다.
Remedian 알고리즘 (PDF)는 낮은 저장 요구 사항 및 잘 정의 된 정확도로 원 패스 중앙값을 준다.
기본 b에 대한 교정은 단일 관측치 만 남을 때까지 b 개의 관측치 그룹의 중간 값을 계산 한 다음이 중간 값의 중간 값을 계산하여 진행됩니다. 이 방법은 단지 크기가 b 인 k 개의 배열 만 필요합니다 (n = b ^ k) ...
사용 하고있는 값 이 1 ~ 100000과 같은 특정 범위 내에있는 경우 정수 버킷 (이 코드는 BSD 라이센스를받은 ea에서 가져온 코드)을 사용하여 매우 많은 수의 값 (예 : 수조 개의 항목)에서 중앙값을 효율적으로 계산할 수 있습니다 -utils / sam-stats.cpp)
class ibucket {
public:
int tot;
vector<int> dat;
ibucket(int max) {dat.resize(max+1);tot=0;}
int size() const {return tot;};
int operator[] (int n) const {
assert(n < size());
int i;
for (i=0;i<dat.size();++i) {
if (n < dat[i]) {
return i;
}
n-=dat[i];
}
}
void push(int v) {
assert(v<dat.size());
++dat[v];
++tot;
}
};
template <class vtype>
double quantile(const vtype &vec, double p) {
int l = vec.size();
if (!l) return 0;
double t = ((double)l-1)*p;
int it = (int) t;
int v=vec[it];
if (t > (double)it) {
return (v + (t-it) * (vec[it+1] - v));
} else {
return v;
}
}