Это решение реализует предложение, сделанное @Innuo в комментарии к вопросу:
Вы можете поддерживать однородную выборку случайного подмножества размером 100 или 1000 из всех данных, просмотренных до сих пор. Этот набор и связанные с ним «ограждения» могут быть обновлены за раз.O(1)
Как только мы узнаем, как поддерживать это подмножество, мы можем выбрать любой метод, который нам нравится, чтобы оценить среднее значение популяции из такой выборки. Это универсальный метод, не делающий никаких предположений, который будет работать с любым входным потоком с точностью, которая может быть предсказана с использованием стандартных формул статистической выборки. (Точность обратно пропорциональна корню квадратному из размера выборки.)
Этот алгоритм принимает в качестве входных данных поток данных размер выборки и выводит поток выборок каждая из которых представляет совокупность . В частности, для , представляет собой простой случайной выборки размера от (без замены).t = 1 , 2 , … , m s ( t ) X ( t ) = ( x ( 1 ) , x ( 2 ) , … , x ( t ) ) 1 ≤ i ≤ t s ( i ) м х ( т )x(t), t=1,2,…,ms(t)X(t)=(x(1),x(2),…,x(t))1≤i≤tс ( я )мИкс( т )
Для этого достаточно, чтобы каждое подмножество -элемента имело равные шансы быть индексами в . Это означает, что вероятность того, что находится в равна при условии .{ 1 , 2 , … , t } x s ( t ) x ( i ) , 1 ≤ i < t , s ( t ) m / t t ≥ mм{ 1 , 2 , … , т }Иксс ( т )х ( я ) , 1 ≤ i < t ,с ( т )м / тt ≥ m
В начале мы просто собираем поток, пока не будет сохранено элементов. На данный момент существует только одна возможная выборка, поэтому условие вероятности тривиально выполняется.м
Алгоритм вступает во владение, когда . Индуктивно предположим, что - простая случайная выборка для . Предварительно установите . Пусть - равномерная случайная величина (независимая от любых предыдущих переменных, использованных для построения ). Если то заменить случайно выбранный элемент на . Вот и вся процедура!s ( t ) X ( t ) t > m s ( t + 1 ) = s ( t ) U ( t + 1 ) s ( t ) U ( t + 1 ) ≤ m / ( t + 1 ) s x ( t + 1 )т = м + 1с ( т )Икс( т )т > мs ( t + 1 ) = s ( t )U( т + 1 )с ( т )U( t + 1 ) ≤ m / ( t + 1 )sх ( т + 1 )
Ясно, что имеет вероятность быть в . Более того, по предположению индукции, имел вероятность быть в когда . С вероятностью = он будет удален из , откуда его вероятность оставшихся равнаm / ( t + 1 ) s ( t + 1 ) x ( i ) m / t s ( t ) i ≤ t m / ( t + 1 ) × 1 / m 1 / ( t + 1 ) s ( t + 1 )х ( т + 1 )м / ( т + 1 )с ( т + 1 )х ( я )м / тс ( т )я ≤ тм / ( т + 1 ) × 1 / м1 / ( т + 1 )с ( т + 1 )
мT( 1 - 1т + 1) = мт + 1,
именно так, как нужно. Таким образом, по индукции все вероятности включения в являются правильными, и ясно, что между этими включениями нет особой корреляции. Это доказывает, что алгоритм правильный.s ( t )х ( я )с ( т )
Эффективность алгоритма составляет потому что на каждом этапе вычисляются не более двух случайных чисел и заменяется не более одного элемента массива из значений. Требование к хранению составляет .m O ( м )O ( 1 )мO ( м )
Структура данных для этого алгоритма состоит из выборки вместе с индексом популяции которую он выбирает. Сначала мы берем и продолжаем алгоритм для Вот реализация для обновления значением для получения . (Аргумент играет роль и равен . Индекс будет поддерживаться вызывающей стороной.)t X ( t ) s = X ( m ) t = m + 1 , m + 2 , … . ( s , t ) x ( s , t + 1 ) t m tsTИкс( т )s = X( м )t = m + 1 , m + 2 , … .R
( с , т )Икс( с , т + 1 )n
Tsample.size
мT
update <- function(s, x, n, sample.size) {
if (length(s) < sample.size) {
s <- c(s, x)
} else if (runif(1) <= sample.size / n) {
i <- sample.int(length(s), 1)
s[i] <- x
}
return (s)
}
Чтобы проиллюстрировать и проверить это, я буду использовать обычную (ненадежную) оценку среднего значения и сравнивать среднее значение, оцененное по с фактическим средним значением (совокупный набор данных, наблюдаемых на каждом этапе ). Я выбрал довольно сложный входной поток, который меняется довольно плавно, но периодически подвергается резким скачкам. Размер выборки довольно мал, что позволяет нам увидеть колебания выборки на этих графиках.X ( t ) m = 50с ( т )Икс( т )м = 50
n <- 10^3
x <- sapply(1:(7*n), function(t) cos(pi*t/n) + 2*floor((1+t)/n))
n.sample <- 50
s <- x[1:(n.sample-1)]
online <- sapply(n.sample:length(x), function(i) {
s <<- update(s, x[i], i, n.sample)
summary(s)})
actual <- sapply(n.sample:length(x), function(i) summary(x[1:i]))
На этом этапе online
представлена последовательность средних оценок, полученных при сохранении этой текущей выборки из значений, а также последовательность средних оценок, полученных на основе всех данных, доступных в каждый момент. На графике показаны данные (серым цветом), (черным цветом) и два независимых применения этой процедуры отбора проб (в цветах). Соглашение находится в пределах ожидаемой ошибки выборки:50actual
actual
plot(x, pch=".", col="Gray")
lines(1:dim(actual)[2], actual["Mean", ])
lines(1:dim(online)[2], online["Mean", ], col="Red")
Для надежной оценки среднего, пожалуйста, ищите на нашем сайте выбросы и связанные с ними термины. Среди возможностей, которые стоит рассмотреть, - средства Winsorized и M-оценки.