«Онлайн» (итератор) алгоритмы для оценки статистической медианы, режима, асимметрии, эксцесса?


86

Есть ли алгоритм для оценки медианы, режима, асимметрии и / или эксцесса набора значений, но он НЕ требует одновременного сохранения всех значений в памяти?

Я хочу посчитать основную статистику:

  • среднее: среднее арифметическое
  • дисперсия: среднее квадратов отклонений от среднего
  • стандартное отклонение: квадратный корень из дисперсии
  • медиана: значение, отделяющее большую половину чисел от меньшей половины.
  • режим: наиболее частое значение в наборе
  • асимметрия: tl; доктор
  • эксцесс: tl; доктор

Основные формулы для вычисления любого из них - это арифметика в начальной школе, и я знаю их. Есть много библиотек статистики, которые их реализуют.

Моя проблема заключается в большом количестве (миллиарды) значений в наборах, которые я обрабатываю: работая в Python, я не могу просто составить список или хэш из миллиардов элементов. Даже если бы я написал это на C, массивы из миллиардов элементов не слишком практичны.

Данные не отсортированы. Он производится случайно, на лету другими процессами. Размер каждого набора сильно варьируется, и размеры не будут известны заранее.

Я уже понял, как хорошо обрабатывать среднее значение и дисперсию, перебирая каждое значение в наборе в любом порядке. (На самом деле, в моем случае я беру их в том порядке, в котором они генерируются.) Вот алгоритм, который я использую, любезно http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#On-line_algorithm :

  • Инициализировать три переменные: count, sum и sum_of_squares
  • Для каждого значения:
    • Счетчик приращения.
    • Добавьте значение к сумме.
    • Добавьте квадрат значения к sum_of_squares.
  • Разделите сумму на количество, сохраняя как среднее значение переменной.
  • Разделите sum_of_squares на количество, сохранив как переменную mean_of_squares.
  • Среднее значение квадрата, сохраняемое как square_of_mean.
  • Вычтите square_of_mean из mean_of_squares, сохраняя как дисперсию.
  • Среднее значение и дисперсия вывода.

У этого «оперативного» алгоритма есть слабые места (например, проблемы с точностью, поскольку сумма_квадратов быстро становится больше, чем целочисленный диапазон или точность с плавающей запятой), но он в основном дает мне то, что мне нужно, без необходимости хранить каждое значение в каждом наборе.

Но я не знаю, существуют ли подобные методы для оценки дополнительной статистики (медиана, мода, асимметрия, эксцесс). Я мог бы жить со смещенной оценкой или даже с методом, который в определенной степени ставит под угрозу точность, пока память, необходимая для обработки N значений, существенно меньше O (N).

Указание мне на существующую библиотеку статистики тоже поможет, если в библиотеке есть функции для вычисления одной или нескольких из этих операций «в режиме онлайн».


будут ли данные передаваться в отсортированном виде, и будете ли вы знать заранее количество входов?
chillysapien


Это целочисленные данные или данные с плавающей запятой? У вас есть максимальное или минимальное значение?
Stephan

dmckee: Я использую метод Велфорда для определения стандартного отклонения. Но я не вижу в этой ссылке ничего о моде, медиане, эксцессе или асимметрии ... Я что-то упускаю?
Ryan B. Lynch

Стефан: Некоторые наборы данных являются целыми числами, другие - числами с плавающей запятой. Распределение населения довольно близко к нормальному (гауссову), поэтому мы можем установить доверительный интервал, но нет границы жесткого диапазона (кроме x> 0 в некоторых случаях).
Райан Б. Линч

Ответы:


53

Асимметрия и эксцесс

Для онлайн-алгоритмов асимметрии и эксцесса (по линиям дисперсии) см. На той же странице вики здесь параллельные алгоритмы для статистики с более высокими моментами.

Медиана

Медиана трудна без отсортированных данных. Если вы знаете, сколько точек данных у вас есть, теоретически вам нужно только частично отсортировать, например, используя алгоритм выбора . Однако с миллиардами ценностей это не очень помогает. Я бы посоветовал использовать подсчет частоты, см. Следующий раздел.

Медиана и режим с подсчетом частоты

Если это целые числа, я бы посчитал частоты , вероятно, отсекая самые высокие и самые низкие значения за пределами некоторого значения, где я уверен, что это больше не актуально. Для чисел с плавающей запятой (или слишком большого количества целых чисел) я, вероятно, создал бы сегменты / интервалы, а затем использовал бы тот же подход, что и для целых чисел. (Приблизительный) режим и расчет медианы, чем становится проще, на основе таблицы частот.

Нормально распределенные случайные переменные

Если оно нормально распределено, я бы использовал среднее значение выборки населения , дисперсию , асимметрию и эксцесс в качестве оценок максимального правдоподобия для небольшого подмножества. Алгоритмы (онлайн) для их расчета, вы уже сейчас. Например, прочтите пару сотен тысяч или миллионов точек данных, пока ваша ошибка оценки не станет достаточно маленькой. Просто убедитесь, что вы выбираете случайным образом из своего набора (например, вы не вносите смещения, выбирая первые 100 000 значений). Тот же подход можно использовать для оценки моды и медианы для нормального случая (для обоих выборочное среднее является оценкой).

Дальнейшие комментарии

Все вышеперечисленные алгоритмы можно запускать параллельно (включая множество алгоритмов сортировки и выбора, например QuickSort и QuickSelect), если это помогает.

Я всегда предполагал (за исключением раздела о нормальном распределении), что мы говорим об выборочных моментах, медиане и моде, а не об оценках теоретических моментов при известном распределении.

В общем, выборка данных (то есть просмотр только подмножества) должна быть довольно успешной, учитывая объем данных, при условии, что все наблюдения представляют собой реализацию одной и той же случайной величины (имеют одинаковые распределения) и моменты, режим и медиана действительно существует для этого распределения. Последний нюанс небезобиден. Например, среднего (и всех высших моментов) для распределения Коши не существует. В этом случае выборочное среднее для «небольшого» подмножества может сильно отличаться от выборочного среднего для всей выборки.


57

Я использую эти инкрементные / рекурсивные средние и медианные оценки, которые используют постоянное хранилище:

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

где eta - небольшой параметр скорости обучения (например, 0,001), а sgn () - знаковая функция, которая возвращает одно из значений {-1, 0, 1}. (Используйте постоянную eta, если данные нестационарны и вы хотите отслеживать изменения во времени; в противном случае для стационарных источников вы можете использовать что-то вроде eta = 1 / n для среднего оценщика, где n - количество наблюдаемых выборок, поэтому далеко ... к сожалению, это не работает для средней оценки.)

Этот тип возрастающей средней оценки, кажется, используется повсеместно, например, в правилах обучения нейронных сетей без учителя, но медианная версия кажется гораздо менее распространенной, несмотря на ее преимущества (устойчивость к выбросам). Кажется, что медианная версия может использоваться как замена средней оценки во многих приложениях.

Я бы хотел увидеть оценщик инкрементального режима аналогичной формы ...

ОБНОВИТЬ

Я только что модифицировал инкрементальную медианную оценку для оценки произвольных квантилей. Как правило, функция квантиля ( http://en.wikipedia.org/wiki/Quantile_function ) сообщает вам значение, которое делит данные на две части: p и 1-p. Следующее оценивает это значение постепенно:

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

Значение p должно быть в пределах [0,1]. Это существенно сдвигает симметричный вывод {-1,0,1} функции sgn () в сторону одной стороны, разделяя выборки данных на две ячейки разного размера (доли p и 1-p данных меньше / больше, чем квантильная оценка соответственно). Обратите внимание, что для p = 0,5 это сводится к средней оценке.


3
Эта средняя оценка великолепна. Вы знаете, существуют ли аналогичные оценки для квантилей 0,25 / 0,75?
Гацек

1
@Gacek, конечно: разделите входной поток на медиану Lohalf <median и Hihalf> и используйте текущую медиану на каждой половине.
denis

2
@Gacek: Я только что обновил свой ответ инкрементным методом для оценки любого квантиля, где вы можете установить p равным 0,25, 0,75 или любому значению в пределах [0,1].
Тайлер Стритер,

10
Это отлично работает для среднего, но я не вижу, как он дает что-то отдаленно близкое к медиане. Возьмем, к примеру, последовательность миллисекундных временных меток: [1328083200000, 981014400000, -628444800000, 318240000000, 949392000000]медиана которых равна 318240000000. Это уравнение сдвигает предыдущую медиану на +/- etaот рекомендованного значения 0.001. Это ничего не даст с такими большими числами, как эти, и может быть слишком большим для действительно маленьких чисел. Как бы вы выбрали etaответ, который действительно дал вам правильный ответ, не зная его априори?
mckamey

9
Представьте, что в числах указаны единицы измерения, например миллиметры. Тогда ясно, что эта (для оценки медианы) должна иметь те же единицы измерения, что и измерения, поэтому общее значение, такое как 0,001, просто не имеет никакого смысла. По-видимому, лучший подход - установить eta на основе текущей оценки абсолютного отклонения: для каждого нового значения sampleобновляйте cumadev += abs(sample-median). Затем установите eta = 1.5*cumadev/(k*k), где k- количество просмотренных образцов.
tholy 07

12

Я реализовал алгоритм P-Square для динамического вычисления квантилей и гистограмм без сохранения наблюдений в аккуратном модуле Python, который я написал под названием LiveStats . Это должно достаточно эффективно решить вашу проблему. Библиотека поддерживает все упомянутые вами статистические данные, кроме режима. Я пока не нашел удовлетворительного решения для оценки режима.


FYI: р-квадрат алгоритм в наддува C ++: <boost/accumulators/statistics/weighted_p_square_cumul_dist.hpp>.
Neil G

7

Райан, я боюсь , что вы не делаете среднее значение и дисперсия права ... Это придумали несколько недель назад здесь . И одна из сильных сторон онлайн-версии (которая на самом деле называется методом Велфорда) - это то, что она особенно точна и стабильна, см. Обсуждение здесь . Одной из сильных сторон является то, что вам не нужно хранить общую сумму или общую сумму квадратов ...

Я не могу придумать какого-либо онлайн-подхода к режиму и медиане, который, кажется, требует одновременного рассмотрения всего списка. Но вполне может быть, что подход, аналогичный подходу для дисперсии и среднего, будет работать также и для асимметрии и эксцесса ...


ре: skewness and kurtosisДа. См. Эту статью: johndcook.com/blog/skewness_kurtosis
Джесси

3

Статья в Википедии, процитированная в вопросе, содержит формулы для вычисления асимметрии и эксцесса в режиме онлайн.

Для режима - я считаю - это невозможно сделать в режиме онлайн. Зачем? Предположим, что все значения вашего ввода отличаются, кроме последнего, которое дублирует предыдущее. В этом случае вы должны запомнить все значения, которые уже были во входных данных, чтобы определить, что последнее значение дублирует предыдущее и делает его наиболее частым.

Для медианы это почти то же самое - до последнего ввода вы не знаете, какое значение станет медианой, если все входные значения будут разными, потому что это может быть до или после текущей медианы. Если вы знаете длину входных данных, вы можете найти медиану, не сохраняя все значения в памяти, но вам все равно придется хранить многие из них (я думаю, около половины), потому что неправильная входная последовательность может сильно сместить медианное значение в вторая половина, возможно, делает любое значение из первой половины медианным.

(Обратите внимание, что я говорю только о точных расчетах.)


2

Если у вас есть миллиарды точек данных, то вряд ли вам нужны точные ответы, а не точные ответы. Как правило, если у вас есть миллиарды точек данных, основной процесс, который их генерирует, скорее всего, будет подчиняться некоторому свойству статистической стационарности / эргодичности / смешивания. Также может иметь значение, ожидаете ли вы, что распределения будут достаточно непрерывными или нет.

В этих условиях существуют алгоритмы для оперативной оценки квантилей с низким объемом памяти (медиана - это частный случай квантиля 0,5), а также режимы, если вам не нужны точные ответы. Это активная область статистики.

Пример квантильной оценки: http://www.computer.org/portal/web/csdl/doi/10.1109/WSC.2006.323014

пример оценки режима: Bickel DR. Робастные оценки режима и асимметрии непрерывных данных. Вычислительная статистика и анализ данных. 2002; 39: 153–163. DOI: 10.1016 / S0167-9473 (01) 00057-3.

Это активные области вычислительной статистики. Вы попадаете в области, где нет единого наилучшего точного алгоритма, а есть их множество (по правде говоря, статистические оценки), которые имеют разные свойства, допущения и производительность. Это экспериментальная математика. По этой теме, вероятно, существуют сотни или тысячи статей.

Последний вопрос: действительно ли вам нужны асимметрия и эксцесс сами по себе или, что более вероятно, некоторые другие параметры, которые могут быть более надежными при характеристике распределения вероятностей (при условии, что у вас есть распределение вероятностей!). Вы ждете гаусса?

Есть ли у вас способы очистки / предварительной обработки данных, чтобы сделать их в основном гауссовскими? (например, суммы финансовых транзакций после логарифмирования часто становятся несколько гауссовыми). Вы ожидаете конечных стандартных отклонений? Вы ожидаете толстых хвостов? Какие количества, которые вам нужны, - в хвосте или в основной массе?


2

Все говорят, что вы не можете использовать этот режим онлайн, но это просто неправда. Вот статья, описывающая алгоритм для решения именно этой проблемы, изобретенный в 1982 году Майклом Э. Фишером и Стивеном Л. Зальцбергом из Йельского университета. Из статьи:

Алгоритм поиска большинства использует один из своих регистров для временного хранения одного элемента из потока; этот элемент является текущим кандидатом в мажоритарный элемент. Второй регистр - это счетчик, инициализированный до 0. Для каждого элемента потока мы просим алгоритм выполнить следующую процедуру. Если счетчик показывает 0, установите текущий элемент потока в качестве нового кандидата на большинство (заменяя любой другой элемент, который уже может быть в регистре). Затем, если текущий элемент соответствует кандидату большинства, увеличьте счетчик; в противном случае уменьшите счетчик. На этом этапе цикла, если часть потока, которая просматривается до сих пор, имеет элемент большинства, этот элемент находится в регистре кандидатов, а счетчик имеет значение больше 0. Что делать, если нет мажоритарного элемента? Без второго прохода через данные - что невозможно в потоковой среде - алгоритм не всегда может дать однозначный ответ в этой ситуации. Он просто обещает правильно определить элемент большинства, если он есть.

Его также можно расширить, чтобы найти верхние N с большим объемом памяти, но это должно решить проблему для режима.


4
Это интересный алгоритм, но если я чего-то не упускаю, в то время как все значения большинства будут режимами, не все режимы будут значениями большинства.
jkebinger 05

Ссылка умерла, поэтому я рад, что описание включено. НО, как описано, счетчик увеличивается только в том случае, если второе вхождение кандидата большинства соседствует с первым вхождением. Что подразумевает отсортированные данные. Что НЕ гарантируется в случае онлайн (потоковой передачи) данных. При случайно упорядоченных данных вряд ли можно найти какие-либо режимы.
Джесси

1

В конечном счете, если у вас нет априорных параметрических знаний о распределении, я думаю, вам нужно сохранить все значения.

Тем не менее, если вы не имеете дело с какой-либо патологической ситуацией, лекарство (Rousseuw and Bassett, 1990) вполне может быть достаточно хорошим для ваших целей.

Очень просто он включает в себя вычисление медианы пакетов медиан.


0

медиана и мода не могут быть рассчитаны онлайн, используя только постоянное доступное пространство. Однако, поскольку медиана и мода в любом случае являются более «описательными», чем «количественными», вы можете оценить их, например, путем выборки набора данных.

Если в долгосрочной перспективе данные распределены нормально, то вы можете просто использовать среднее значение для оценки медианы.

Вы также можете оценить медианное значение, используя следующий метод: установите среднюю оценку M [i] для каждого, скажем, 1 000 000 записей в потоке данных так, чтобы M [0] было медианой первого миллиона записей, M [1] медиана второго миллиона записей и т. д. Затем используйте медиану M [0] ... M [k] в качестве оценки медианы. Это, конечно, экономит место, и вы можете контролировать, сколько вы хотите использовать пространство, «настраивая» параметр 1 000 000. Это также можно обобщить рекурсивно.


0

Хорошо, чувак, попробуй это:

для c ++:

double skew(double* v, unsigned long n){
    double sigma = pow(svar(v, n), 0.5);
    double mu = avg(v, n);

    double* t;
    t = new double[n];

    for(unsigned long i = 0; i < n; ++i){
        t[i] = pow((v[i] - mu)/sigma, 3);
    }

    double ret = avg(t, n);

    delete [] t;
    return ret;
}

double kurt(double* v, double n){
    double sigma = pow(svar(v, n), 0.5);
    double mu = avg(v, n);

    double* t;
    t = new double[n];

    for(unsigned long i = 0; i < n; ++i){
        t[i] = pow( ((v[i] - mu[i]) / sigma) , 4) - 3;
    }

    double ret = avg(t, n);

    delete [] t;
    return ret;
}

где вы говорите, что уже можете рассчитать выборочную дисперсию (svar) и среднее значение (avg), вы указываете их на свои функции для этого.

Кроме того, взгляните на аппроксимацию Пирсона. на таком большом наборе данных это было бы очень похоже. 3 (среднее - медиана) / стандартное отклонение, у вас есть медиана как макс - мин / 2

для режима поплавков значения не имеет. их обычно кладут в бункеры значительного размера (например, 1/100 * (макс. - мин.)).



-1

Я бы предпочел использовать ведра, которые могут быть адаптивными. Размер ведра должен соответствовать необходимой вам точности. Затем по мере поступления каждой точки данных вы добавляете ее к счету соответствующего сегмента. Они должны дать вам простые приближения к медиане и эксцессу, подсчитывая каждое ведро как его значение, взвешенное по его количеству.

Единственная проблема может заключаться в потере разрешения в числах с плавающей запятой после миллиардов операций, т.е. добавление одной больше не меняет значения! Чтобы обойти это, если максимальный размер ведра превышает некоторый предел, вы можете вычесть большое число из всех подсчетов.


-1
for j in range (1,M):
    y=np.zeros(M) # build the vector y
    y[0]=y0

    #generate the white noise
    eps=npr.randn(M-1)*np.sqrt(var)

    #increment the y vector
    for k in range(1,T):
        y[k]=corr*y[k-1]+eps[k-1]

    yy[j]=y

list.append(y)

Можно было бы использовать какое-нибудь объяснение, чтобы лучше связать это с исходным вопросом.
Erica
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.