C.1 Run Test (런 검정)
잔차같은 어떤 일련의 숫자들이 무작위(random)인지 아닌지 검정하는 방법의 하나이다. 잔차의 경우 양수와 음수가 무작위적으로 나와야 한다. 동일한 부호가 연속적으로 나오는 경우, 그들을 묶어서 하나의 run이라고 한다. 잔차의 개수와 run의 개수를 비교해보면 무작위성(randomness)을 어느 정도 판정할 수 있다. 잔차의 개수가 run의 갯수와 같다는 것은 잔차의 부호가 번갈아가면서(alternative하게) 나온다는 것(즉, 매번 부호가 바뀐다는 것)을 의미하므로 무작위(random)가 아니다. 반면에 run의 개수가 적다는 것은 부호가 변하지 않고 같은 부호가 연속해서 많이 나온다는 것을 의미하므로 이것 역시 무작위가 아니다. 즉, run의 개수가 너무 적거나, 너무 많으면 무작위적이라고 할 수 없다.
\[P(u \leq u') = \sum_{u=2}^{u'}f_u \div \binom{m + n}{m}\] where
\(f_u = 2 \binom{m-1}{k-1} \binom{n-1}{k-1}, \quad k=\frac{u}{2}\), when is even;
and
\(f_u = \binom{m-1}{k-1} \binom{n-1}{k-2} + \binom{m-1}{k-2} \binom{n-1}{k-1}, \quad k=\frac{u+1}{2}\), when is odd.
위의 수식을 이용하여 R 함수를 만들면 다음과 유사하다.
= function(m, n, r)
run.p
{# INPUT
# m : count of fewer species (minimum value = 0)
# n : count of more frequent species (minimum value = 1)
# r : count of run (minimum value = 1)
# RETURNS probability of run count to be less than or equal to r with m and n
# P(Run count <= r | m, n)
if (m==0 & r==1) {
return(1)
else if (m > n | m < 1 | n < 1 | r < 2 | (r > min(m + n, 2 * m + 1))) {
} return(0);
}
= 0
sumfu for (u in 2:r) {
if (u %% 2 == 0) {
= u / 2
k = 2 * choose(m-1, k-1) * choose(n-1, k-1)
fu else {
} = (u + 1) / 2
k = choose(m-1, k-1) * choose(n-1, k-2) + choose(m-1, k-2) * choose(n-1, k-1)
fu
}= sumfu + fu
sumfu
}return(sumfu / choose(m+n, m))
}
= function(RES)
Run.test
{= RES[RES != 0] # Zeros are omitted.
RES = length(RES)
t = RES > 0
r = sum(r)
m if (t > 1) {
= 2:t
j = sum(abs(r[j] - r[j-1])) + 1
run else {
} = 1
run
}= min(m, t-m)
m = max(m, t-m)
n if (run > 1) {
= run.p(m, n, run)
p if (p > 0.5) {
= 1 - run.p(m, n, run-1)
p
}else {
} = 0.5^(t-1)
p
}return(p)
}