I'm trying to apply the power martingale framework by [Vovk et al., 2003] to change detection in unlabeled data streams, just like in [Ho and Wechsler, 2007]. The basic idea involves using a power martingale of the form $$M_n^{(\epsilon)} := \prod_{i=1}^n\left(\epsilon p_i^{\epsilon-1}\right) = \epsilon p_n^{\epsilon-1} M_{n-1}^{(\epsilon)}.$$ If I understand the method correctly, it is supposed to work as follows:
- $p_i$ are p-values of some input sequence that are distributed uniformly on $[0,1]$ when the sequence is exchangeable;
- when exchangeability is violated, $p_i$ become smaller, and $M_n$ starts to grow;
- when $M_n$ has grown to some threshold or the difference between neighboring $M_n$ has exceeded some threshold, we ring the alarm that some change has occurred and start over.
Looks very simple, but I couldn't get it to work: on my data, the values of $M_n$ did oscillate randomly for a while but very soon dropped to zero (to values like 1e-100) an stayed there; there were some large factors when actual change occurred in the data, but it would take a lot of factors to return from 1e-100...
I tried a simple test: generated uniformly distributed $p_i$ and computed $M_n$ for them. Here is the complete python code of my test ($\epsilon=0.92$ is a suggested value from the papers, but I've tried other $\epsilon$ with similar results):
epsilon = 0.92
pv_test = [random.random() for _ in xrange(5000)]
test_mult = [epsilon * (x ** (epsilon - 1)) for x in pv_test]
Mtest = [1]
for i in xrange(len(test_mult)):
Mtest.append(Mtest[i] * test_mult[i])
And I observed the very same behaviour: $M_n$ always dropped to zero! Sometimes faster, sometimes slower, but always. Here are some sample graphs of $M_n$:
It does look like a random walk, but it always eventually drops to zero even for perfectly uniform p-values. This obviously will not work for change detection because even a relatively long sequence of small p-values cannot resurrect $M_n$ from 1e-100.
So my question is: what am I doing wrong?..