アップダウン フィルターを使用します。
if q < x:
q += .01 * (x - q) # up a little
else:
q += .005 * (x - q) # down a little
ここでは、分位推定器がストリームをq
追跡し、x
それぞれに向かって少しずつ移動しますx
。両方の要素が 0.01 の場合、50 パーセンタイルを追跡して、上と下の両方に移動します。0.01 上昇、0.005 下降では、67 パーセンタイルで浮き上がります。一般に、up / (up + down) パーセンタイルを追跡します。アップ/ダウン ファクターが大きいほど、追跡は速くなりますがノイズが多くなります。実際のデータで実験する必要があります。
(アップダウンを分析する方法がわかりません。リンクをいただければ幸いです。)
以下updown()
は、長いベクトル X、Q をプロットするために機能します。

#!/usr/bin/env python
from __future__ import division
import sys
import numpy as np
import pylab as pl
def updown( X, Q, up=.01, down=.01 ):
""" updown filter: running ~ up / (up + down) th percentile
here vecs X in, Q out to plot
"""
q = X[0]
for j, x in np.ndenumerate(X):
if q < x:
q += up * (x - q) # up a little
else:
q += down * (x - q) # down a little
Q[j] = q
return q
#...............................................................................
if __name__ == "__main__":
N = 1000
up = .01
down = .005
plot = 0
seed = 1
exec "\n".join( sys.argv[1:] ) # python this.py N= up= down=
np.random.seed(seed)
np.set_printoptions( 2, threshold=100, suppress=True ) # .2f
title = "updown random.exponential: N %d up %.2g down %.2g" % (N, up, down)
print title
X = np.random.exponential( size=N )
Q = np.zeros(N)
updown( X, Q, up=up, down=down )
# M = np.zeros(N)
# updown( X, M, up=up, down=up )
print "last 10 Q:", Q[-10:]
if plot:
fig = pl.figure( figsize=(8,3) )
pl.title(title)
x = np.arange(N)
pl.plot( x, X, "," )
pl.plot( x, Q )
pl.ylim( 0, 2 )
png = "updown.png"
print >>sys.stderr, "writing", png
pl.savefig( png )
pl.show()