πŸŽ‰ 75% of content is free forever β€” Unlock Premium from $10/mo β†’
CW
Search courses…
πŸ’Ό Servicesℹ️ Aboutβœ‰οΈ ContactView Pricing Plansfrom $10

Runs Test for Randomness

Nonparametric TestsNonparametric Tests🟒 Free Lesson

Advertisement

Runs Test for Randomness

Nonparametric Tests

Detecting Non-Random Patterns in Binary Sequences

The runs test checks whether a sequence of binary observations appears randomly ordered or exhibits systematic clustering. It counts transitions between categories to detect patterns that violate randomness.

  • Quality Control β€” Verify that manufacturing defects occur randomly over time
  • Clinical Trials β€” Check randomization integrity in treatment assignments
  • Financial Markets β€” Test whether price movements show non-random sequences

Random sequences should have neither too many nor too few transitions between categories.


The runs test (Wald-Wolfowitz test) checks whether a sequence of binary observations is randomly ordered or shows systematic patterns.

DfRun

A run is a consecutive sequence of identical values in a binary sequence.

import numpy as np
from scipy.stats import runstest_1samp
import matplotlib.pyplot as plt

# Example: Quality control β€” is the defect pattern random?
np.random.seed(42)

# Scenario 1: Truly random sequence
random_seq = np.random.choice([0, 1], size=50, p=[0.7, 0.3])

# Scenario 2: Systematic pattern (not random)
pattern_seq = np.array([0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,
                         0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,
                         0,0,0,1,0,0,0,1,0,0])

def runs_test(sequence, label):
    """Manual runs test computation."""
    n = len(sequence)
    n1 = sequence.sum()     # number of 1s
    n0 = n - n1             # number of 0s
    
    # Count runs
    runs = 1
    for i in range(1, n):
        if sequence[i] != sequence[i-1]:
            runs += 1
    
    # Expected runs and variance under Hβ‚€
    E_R = 2*n1*n0/n + 1
    Var_R = 2*n1*n0*(2*n1*n0 - n) / (n**2 * (n-1))
    z = (runs - E_R) / np.sqrt(Var_R)
    
    from scipy import stats as sc
    p = 2 * sc.norm.sf(abs(z))
    
    print(f"\n{label}:")
    print(f"  nβ‚€={n0}, n₁={n1}, Runs={runs}")
    print(f"  E[R]={E_R:.2f}, Var[R]={Var_R:.4f}")
    print(f"  z={z:.4f}, p={p:.4f}")
    print(f"  Decision: {'NOT random (reject Hβ‚€)' if p < 0.05 else 'Appears random'}")
    return runs, z, p

r1, z1, p1 = runs_test(random_seq, "Random sequence")
r2, z2, p2 = runs_test(pattern_seq, "Systematic pattern")

# Visualize
fig, axes = plt.subplots(2, 1, figsize=(14, 6))
for ax, seq, label, p_val in zip(axes, [random_seq, pattern_seq],
                                   ['Random Sequence', 'Systematic Pattern'],
                                   [p1, p2]):
    colors = ['steelblue' if x == 0 else 'coral' for x in seq]
    ax.bar(range(len(seq)), seq, color=colors, edgecolor='black', linewidth=0.5)
    ax.set_title(f'{label} (p={p_val:.4f})')
    ax.set_ylabel('Value')
    ax.set_yticks([0, 1])
plt.tight_layout()
plt.savefig('runs_test.png', dpi=150)
plt.show()

Interpreting Runs

  • Too few runs: positive autocorrelation (clustering)
  • Too many runs: negative autocorrelation (alternating)

Key Takeaways

Summary: Runs Test

  • Runs test checks randomness in binary sequences
  • Too few runs: positive autocorrelation (clustering)
  • Too many runs: negative autocorrelation (alternating)
  • Applications: quality control, testing for systematic trends, auditing
  • For continuous data: convert to binary using median as cutpoint, then apply runs test
⭐

Premium Content

Runs Test for Randomness

Unlock this lesson and 900+ advanced tutorials with a Premium plan.

🎯End-to-end Projects
πŸ’ΌInterview Prep
πŸ“œCertificates
🀝Community Access

Already a member? Log in

Need Expert Statistics Help?

Get personalized tutoring, project support, or professional consulting.

Advertisement