Онлайн-оцінка квартілів без зберігання спостережень


13

Мені потрібно обчислювати квартілі (Q1, медіану та Q3) у реальному часі на великому наборі даних, не зберігаючи спостереження. Я спершу спробував алгоритм P-квадратів (Jain / Chlamtac), але я його не задовольнив (трохи занадто багато використання процесора і не переконаний у точності принаймні на моєму наборі даних).

Зараз я використовую алгоритм FAME ( Feldman / Shavitt ) для оцінки медіани на ходу і намагаюся вивести алгоритм для обчислення також Q1 і Q3:

M = Q1 = Q3 = first data value 
step =step_Q1 = step_Q3 = a small value
for each new data :
        # update median M 
        if M > data:
            M = M - step
        elif M < data:
            M = M + step
        if abs(data-M) < step:
            step = step /2

        # estimate Q1 using M
        if data < M:
            if Q1 > data:
                Q1 = Q1 - step_Q1
            elif Q1 < data:
                Q1 = Q1 + step_Q1
            if abs(data - Q1) < step_Q1:
                step_Q1 = step_Q1/2
        # estimate Q3 using M
        elif data > M:
            if Q3 > data:
                Q3 = Q3 - step_Q3
            elif Q3 < data:
                Q3 = Q3 + step_Q3
            if abs(data-Q3) < step_Q3:
                step_Q3 = step_Q3 /2

Для відновлення він просто використовує медіану M, отриману на льоту, щоб розділити набір даних надвоє, а потім повторно використовувати один і той же алгоритм як для Q1, так і для Q3.

Це, здається, працює якось, але я не в змозі продемонструвати (я не математик). Це хибно? Буду вдячний за будь-яку пропозицію чи можливу іншу техніку, яка відповідає проблемі.

Велике спасибі за вашу допомогу !

==== EDIT =====

Для тих, хто цікавиться такими питаннями, через кілька тижнів я нарешті закінчився простим використанням відбору проб водойми з ревервором 100 значень, і це дало дуже задовольняючі результати (для мене).


Ви шукаєте доказ того, що Q1 і Q2 сходяться до справжніх квантилів, оскільки кількість прикладів збільшується таким чином, як аналіз ланцюгового аналізу Маркова на слайдах, з якими ви пов'язані? З точки зору реалізації, вищевказаний алгоритм не здається недосконалим (я перевірив наближення квантових значень для нормальних норм в R, і алгоритм працює нормально).
Theja

1
@Я дякую, я не шукаю доказів (занадто багато роботи), а лише поради та зауваження. Основна проблема, яку я бачу, полягає в тому, щоб обчислити основу на оцінці медіани, як показав Уабер.
Луї Хьюз

Відповіді:


3

Медіана - це точка, в якій 1/2 спостережень падають нижче і на 1/2 вище. Аналогічно, 25-й перецентил є медіаною для даних між хв і медіаною, а 75-й перцентиль - медіаною між медіаною та макс. весь набір даних, щоб розділити його, а потім на дві отримані частини.

Оновлення :

Це питання про stackoverflow призводить до цієї роботи: Raj Jain, Imrich Chlamtac: Алгоритм P² для динамічного обчислення квантолів та гістограм без збереження спостережень. Комун. ACM 28 (10): 1076-1085 (1985) , анотація якого свідчить про те, що вас, мабуть, цікавить:

Запропоновано евристичний алгоритм для динамічного обчислення qf медіани та інших квантилів. Оцінки виробляються динамічно в міру формування спостережень. Спостереження не зберігаються; отже, алгоритм має дуже малу та фіксовану вимогу зберігання незалежно від кількості спостережень. Це робить його ідеальним для впровадження в кількісний чіп, який може бути використаний у промислових контролерах та рекордерах. Алгоритм далі поширюється на побудову гістограми. Проаналізовано точність алгоритму.


4
Ця відповідь оглядає два найтонших пункту, один неважливий, але інший, можливо, дуже важливий. Неважливим є те, що техніка подвійного розщеплення обчислює верхні та нижні петлі, які можуть дещо відрізнятися від медіани, залежно від розмірів вибірки. Важливим є те, що, як видається, подвійне розщеплення базується на поточній оцінці медіани. Будь-яка різниця між цією оцінкою та фактичною медіаною також призведе до зміни шарнірів. Інтуїтивно це не повинно бути проблемою, оскільки кількість даних збільшується, але це питання, який потребує певного аналізу.
whuber

Невже безпосередньо оцінювання квартилів не буде предметом подібних питань? Пряма оцінка дозволить розділити точок даних на співвідношення . Цей розділяє елементи на а потім бере один із цих "2" s і розбиває його . Я не теоретик, правда, але, взагалі, хіба не буде різниця між двома, щонайменше, однією точкою ліворуч або праворуч і не збігалася б із збільшенням ? Так, патологічний розподіл може бути створений, але це також постраждає від прямої медіанної оцінки. Очевидно, що зберігати всі значення краще, звичайно. н1:32:21:1н
Аврахам

2
@Avraham, дякую за вказівку на статтю, як я вже згадував, я вже спробував алгоритм P-квадрата від Chain і Chlamtac. на моєму наборі даних альго, яке я визначив, дає кращий результат (MSE) і швидше. Тож я запитував, чи все-таки це може мати якусь проблему. Оскільки зауважив, той факт, що він використовує поточну оцінку, є потенційною проблемою; але я не знаю, чи це дійсно важливо чи ні.
Луї Хьюз

Уопс, побачив це і забув. Мої вибачення.
Аврахам

0

Дуже незначна зміна способу, який ви опублікували, і ви можете обчислити будь-який довільний процентиль, без необхідності обчислювати всі кванти. Ось код Python:

class RunningPercentile:
    def __init__(self, percentile=0.5, step=0.1):
        self.step = step
        self.step_up = 1.0 - percentile
        self.step_down = percentile
        self.x = None

    def push(self, observation):
        if self.x is None:
            self.x = observation
            return

        if self.x > observation:
            self.x -= self.step * self.step_up
        elif self.x < observation:
            self.x += self.step * self.step_down
        if abs(observation - self.x) < self.step:
            self.step /= 2.0

і приклад:

import numpy as np
import matplotlib.pyplot as plt

distribution = np.random.normal
running_percentile = RunningPercentile(0.841)
observations = []
for _ in range(1000000):
    observation = distribution()
    running_percentile.push(observation)
    observations.append(observation)

plt.figure(figsize=(10, 3))
plt.hist(observations, bins=100)
plt.axvline(running_percentile.x, c='k')
plt.show()

Нормальний розподіл з 1 процентилом ІПСШ

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.