(no subject)
Wednesday, 28 December 2011 22:57![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
сижу вот это, ковыряюсь с среднеквадратичными и прочими экспоненциальными скользящими, да и думаю что надо было тот семестр статистики досидеть всё же. Чтоб представлять, что как, чего на самом деле можно ожидать, и какие артефакты могут вылезти.
Хотя, с другой стороны, сотрудники неподалёку честно учили, но им на данный момент вся эта байда кажется ещё более мутной чем мне. Оно ж когда понадобится, а бывает это не так часто, тут и оказывается что эээ, ммм, вроде чота десять лет назад слышал :)
Ну и я "слышал".
Итак. Есть некоторый цикл, в котором происходит нечто. Интересно время исполнения этого цикла и длительность его отдельных этапов. То есть, по окончании каждой итерации имеем набор (total=27.3, stage1=20.17, stage2=6.43, stage3=0.02, stage4=0.63). Некая штука время от времени запрашивает эти циферки. Существенно реже, чем происходят сами итерации (по наблюдениям, одна итерация может занять от 10 до 40 секунд).
Я бы с удовольствием напрямую пушил в момент окончания циферки с таймстампом, но давайте попробуем обойтись без этого. При таком раскладе, конечно, мы часть информации теряем, и это ок. Главное, не потерять что-нибудь важное и интересное (~ общие тренды + аномалии).
Опуская всю проведённую теоретическую и экспериментальную исследовательскую работу, схема такова:
- тайминг каждой итерации записывается в кольцевой буфер размером 5.
- при этом сразу записывается в специально отведённое место пара (ring[-1], qaverage(ring, exp)) - значение из последней итерации и среднеквадратичное взвешенное по e^i:
def qaverage(ring, weight_function = lambda x: 1):
s = sum([ring[i]*ring[i]*weight_function(i) for i in xrange(len(ring))])
d = sum([weight_function(i) for i in xrange(len(ring))])
return sqrt(s/d)
То есть, значимость самых новых элементов больше.
На графике рисуется это самое значение и соответствующее ему qaverage (очевидно, бегающее где-то около, выше или ниже, самого значения). Из постановки задачи ясно, что бОльшая часть этих пар будет благополучно профачена - забирается консумером, грубо говоря, каждая n-я при случайном n из [2,7].
То есть общее состояние "примерно" видно. Конкретные высокие значения могут никогда не попасть в график, но оставят след в qaverage, хотя сам qaverage конечно ихникогда не достигнет только если все пять последних будут одинаковые. В принципе, их можно будет ручками посмотреть в логе :) И понятно, что если qaverage больше выхваченного значения, то до него были цифры выше, и наоборот. На самом деле я бы увеличил длину буфера до 10, и показывал дополнительно qaverage от (последней) половины сохранённых данных. Или можно обойтись одним числом (каким)?
В общем, природа данных известна, граничные условия известны - ругайте :)
ЗЫ. Вопросы вида "почему среднеквадратичное?" и "почему e^i?" лучше формулировать в виде "надо использовать XXX потому что А, B, C".
ЗЗЫ. C реализацией exponential moving average возиться пока не стал ибо не уверен что есть смысл.
Хотя, с другой стороны, сотрудники неподалёку честно учили, но им на данный момент вся эта байда кажется ещё более мутной чем мне. Оно ж когда понадобится, а бывает это не так часто, тут и оказывается что эээ, ммм, вроде чота десять лет назад слышал :)
Ну и я "слышал".
Итак. Есть некоторый цикл, в котором происходит нечто. Интересно время исполнения этого цикла и длительность его отдельных этапов. То есть, по окончании каждой итерации имеем набор (total=27.3, stage1=20.17, stage2=6.43, stage3=0.02, stage4=0.63). Некая штука время от времени запрашивает эти циферки. Существенно реже, чем происходят сами итерации (по наблюдениям, одна итерация может занять от 10 до 40 секунд).
Я бы с удовольствием напрямую пушил в момент окончания циферки с таймстампом, но давайте попробуем обойтись без этого. При таком раскладе, конечно, мы часть информации теряем, и это ок. Главное, не потерять что-нибудь важное и интересное (~ общие тренды + аномалии).
Опуская всю проведённую теоретическую и экспериментальную исследовательскую работу, схема такова:
- тайминг каждой итерации записывается в кольцевой буфер размером 5.
- при этом сразу записывается в специально отведённое место пара (ring[-1], qaverage(ring, exp)) - значение из последней итерации и среднеквадратичное взвешенное по e^i:
def qaverage(ring, weight_function = lambda x: 1):
s = sum([ring[i]*ring[i]*weight_function(i) for i in xrange(len(ring))])
d = sum([weight_function(i) for i in xrange(len(ring))])
return sqrt(s/d)
То есть, значимость самых новых элементов больше.
На графике рисуется это самое значение и соответствующее ему qaverage (очевидно, бегающее где-то около, выше или ниже, самого значения). Из постановки задачи ясно, что бОльшая часть этих пар будет благополучно профачена - забирается консумером, грубо говоря, каждая n-я при случайном n из [2,7].
То есть общее состояние "примерно" видно. Конкретные высокие значения могут никогда не попасть в график, но оставят след в qaverage, хотя сам qaverage конечно их
В общем, природа данных известна, граничные условия известны - ругайте :)
ЗЫ. Вопросы вида "почему среднеквадратичное?" и "почему e^i?" лучше формулировать в виде "надо использовать XXX потому что А, B, C".
ЗЗЫ. C реализацией exponential moving average возиться пока не стал ибо не уверен что есть смысл.