Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Simulation tests for coverage + p-values #73

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions sims/anderson_darling.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module SimulateAndersonDarling
using Base.Test
using Distributions, HypothesisTests

include("utils.jl")

has_ci(::Type{OneSampleADTest}) = false
has_p_value(::Type{OneSampleADTest}) = true
function call_test(::Type{OneSampleADTest}, x, simulation)
return OneSampleADTest(x, simulation.d_x)
end

@testset "OneSampleADTest" begin
results = simulate(
OneSampleSimulation(Normal(0.0, 1.0), 100),
OneSampleADTest,
100_000,
)
analyze_simulation(results)
end
end
21 changes: 21 additions & 0 deletions sims/binomial.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module SimulateBinomial
using Base.Test
using Distributions, HypothesisTests

include("utils.jl")

has_ci(::Type{BinomialTest}) = true
has_p_value(::Type{BinomialTest}) = true
function call_test(::Type{BinomialTest}, x, simulation)
return BinomialTest(sum(x), length(x), mean(simulation.d_x))
end

@testset "BinomialTest" begin
results = simulate(
OneSampleSimulation(Bernoulli(0.5), 100),
BinomialTest,
100_000,
)
analyze_simulation(results)
end
end
21 changes: 21 additions & 0 deletions sims/kolmogorov_smirnov.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module SimulateKolmogorovSmirnov
using Base.Test
using Distributions, HypothesisTests

include("utils.jl")

has_ci(::Type{ExactOneSampleKSTest}) = false
has_p_value(::Type{ExactOneSampleKSTest}) = true
function call_test(::Type{ExactOneSampleKSTest}, x, simulation)
return ExactOneSampleKSTest(x, simulation.d_x)
end

@testset "ExactOneSampleKSTest" begin
results = simulate(
OneSampleSimulation(Normal(0.0, 1.0), 100),
ExactOneSampleKSTest,
100_000,
)
analyze_simulation(results)
end
end
21 changes: 21 additions & 0 deletions sims/kruskal_wallis.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module SimulateKruskalWallis
using Base.Test
using Distributions, HypothesisTests

include("utils.jl")

has_ci(::Type{KruskalWallisTest}) = false
has_p_value(::Type{KruskalWallisTest}) = true
function call_test(::Type{KruskalWallisTest}, x, y, simulation)
return KruskalWallisTest(x, y)
end

@testset "KruskalWallisTest" begin
results = simulate(
TwoSampleSimulation(Normal(0.0, 1.0), Normal(0.0, 1.0), 100, 100),
KruskalWallisTest,
100_000,
)
analyze_simulation(results)
end
end
36 changes: 36 additions & 0 deletions sims/mann_whitney.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module SimulateMannWhitney
using Base.Test
using Distributions, HypothesisTests

include("utils.jl")

has_ci(::Type{ExactMannWhitneyUTest}) = false
has_p_value(::Type{ExactMannWhitneyUTest}) = true
function call_test(::Type{ExactMannWhitneyUTest}, x, y, simulation)
return ExactMannWhitneyUTest(x, y)
end

has_ci(::Type{ApproximateMannWhitneyUTest}) = false
has_p_value(::Type{ApproximateMannWhitneyUTest}) = true
function call_test(::Type{ApproximateMannWhitneyUTest}, x, y, simulation)
return ApproximateMannWhitneyUTest(x, y)
end

@testset "ExactMannWhitneyUTest" begin
results = simulate(
TwoSampleSimulation(Normal(0.0, 1.0), Normal(0.0, 1.0), 50, 100),
ExactMannWhitneyUTest,
100_000,
)
analyze_simulation(results)
end

@testset "ApproximateMannWhitneyUTest" begin
results = simulate(
TwoSampleSimulation(Normal(0.0, 1.0), Normal(0.0, 1.0), 100, 100),
ApproximateMannWhitneyUTest,
100_000,
)
analyze_simulation(results)
end
end
25 changes: 25 additions & 0 deletions sims/runsims.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Base.Test

my_tests = (
"binomial.jl",
"kolmogorov_smirnov.jl",
"kruskal_wallis.jl",
"mann_whitney.jl",
"t.jl",
"z.jl",
# "wilcoxon.jl",
"anderson_darling.jl",
)

println("Running simulation tests:")

@testset "All simulation studies" begin
for my_test in my_tests
try
include(my_test)
println("\t\033[1m\033[32mPASSED\033[0m: $(my_test)")
catch e
println("\t\033[1m\033[31mFAILED\033[0m: $(my_test)")
end
end
end
51 changes: 51 additions & 0 deletions sims/t.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
module SimulateTTest
using Base.Test
using Distributions, HypothesisTests

include("utils.jl")

has_ci(::Type{OneSampleTTest}) = true
has_p_value(::Type{OneSampleTTest}) = true
function call_test(::Type{OneSampleTTest}, x, simulation)
return OneSampleTTest(x)
end

has_ci(::Type{EqualVarianceTTest}) = true
has_p_value(::Type{EqualVarianceTTest}) = true
function call_test(::Type{EqualVarianceTTest}, x, y, simulation)
return EqualVarianceTTest(x, y)
end

has_ci(::Type{UnequalVarianceTTest}) = true
has_p_value(::Type{UnequalVarianceTTest}) = true
function call_test(::Type{UnequalVarianceTTest}, x, y, simulation)
return UnequalVarianceTTest(x, y)
end

@testset "OneSampleTTest" begin
results = simulate(
OneSampleSimulation(Normal(0.0, 1.0), 100),
OneSampleTTest,
100_000,
)
analyze_simulation(results)
end

@testset "EqualVarianceTTest" begin
results = simulate(
TwoSampleSimulation(Normal(0.0, 1.0), Normal(0.0, 1.0), 100, 100),
EqualVarianceTTest,
100_000,
)
analyze_simulation(results)
end

@testset "UnequalVarianceTTest" begin
results = simulate(
TwoSampleSimulation(Normal(0.0, 1.0), Normal(0.0, 2.0), 100, 100),
UnequalVarianceTTest,
100_000,
)
analyze_simulation(results)
end
end
128 changes: 128 additions & 0 deletions sims/utils.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
immutable OneSampleSimulation{T}
d_x::T
n_x::Int
end

immutable TwoSampleSimulation{S, T}
d_x::S
d_y::T
n_x::Int
n_y::Int
end

immutable SimulationAnalysis
coverage::Vector{Bool}
p_values::Vector{Float64}
has_ci::Bool
has_p_value::Bool
end

covers(ci, truth) = ci[1] <= truth <= ci[2]

function initialize(simulation::OneSampleSimulation)
return rand(simulation.d_x, simulation.n_x)
end

function initialize(simulation::TwoSampleSimulation)
return (
rand(simulation.d_x, simulation.n_x),
rand(simulation.d_y, simulation.n_y),
)
end

function fill!(x, simulation::OneSampleSimulation)
rand!(simulation.d_x, x)
return
end

function fill!(x, y, simulation::TwoSampleSimulation)
rand!(simulation.d_x, x)
rand!(simulation.d_y, y)
return
end

function simulate(simulation::OneSampleSimulation, test, n_sims)
# Initialize core results.
coverage = Array(Bool, n_sims)
p_values = Array(Float64, n_sims)

# Initialize sample.
x = initialize(simulation)

# Run simulations.
for sim in 1:n_sims
fill!(x, simulation)
test_results = call_test(test, x, simulation)
if has_ci(test)
coverage[sim] = covers(ci(test_results), mean(simulation.d_x))
end
if has_p_value(test)
p_values[sim] = pvalue(test_results)
end
end

return SimulationAnalysis(
coverage,
p_values,
has_ci(test),
has_p_value(test),
)
end

function simulate(simulation::TwoSampleSimulation, test, n_sims)
# Initialize core results.
coverage = Array(Bool, n_sims)
p_values = Array(Float64, n_sims)

# Initialize sample.
x, y = initialize(simulation)

# Run simulations.
for sim in 1:n_sims
fill!(x, y, simulation)
test_results = call_test(test, x, y, simulation)
if has_ci(test)
coverage[sim] = covers(
ci(test_results),
mean(simulation.d_x) - mean(simulation.d_y),
)
end
if has_p_value(test)
p_values[sim] = pvalue(test_results)
end
end

return SimulationAnalysis(
coverage,
p_values,
has_ci(test),
has_p_value(test),
)
end

# τ: Inverted tolerance for failure. Set to 12, which implies a 12-sigma test,
# which should fail during 1.776482112077648e-33 simulation tests. Even when
# we run many tests, this level of failure is rare -- moreover, the SEM is
# also small for large n, so the tests are quite stringent when the hypothesis
# is false.
function analyze_simulation(results::SimulationAnalysis, τ = 12)
if results.has_ci
n_sims = length(results.coverage)
sem_coverage = 0.95 * (1 - 0.95) / sqrt(n_sims)
@test abs(mean(results.coverage) - 0.95) <= τ * sem_coverage
end

if results.has_p_value
n_sims = length(results.p_values)

sem_mean = sqrt(var(Uniform(0, 1)) / n_sims)
@test abs(mean(results.p_values) - 0.50) <= τ * sem_mean

for α in (0.01, 0.05, 0.10, 0.25, 0.50, 0.75, 0.90, 0.95, 0.99)
sem_quantile = sqrt(var(Bernoulli(α)) / n_sims)
@test abs(mean(results.p_values .<= α) - α) <= τ * sem_quantile
end
end

return
end
57 changes: 57 additions & 0 deletions sims/z.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
module SimulateZTest
# TODO: We get occasional failures here. We should consider forcing
# OneSampleZTest to provide the true variance rather than allow it to
# estimate it and pretend the estimate is known with certainty. You
# reliably detect these failtures if you simulate 1,000,000 times instead
# of 10,000. See t.jl for a contrast where all assumptions are satisfied.

using Base.Test
using Distributions, HypothesisTests

include("utils.jl")

has_ci(::Type{OneSampleZTest}) = true
has_p_value(::Type{OneSampleZTest}) = true
function call_test(::Type{OneSampleZTest}, x, simulation)
return OneSampleZTest(x)
end

has_ci(::Type{EqualVarianceZTest}) = true
has_p_value(::Type{EqualVarianceZTest}) = true
function call_test(::Type{EqualVarianceZTest}, x, y, simulation)
return EqualVarianceZTest(x, y)
end

has_ci(::Type{UnequalVarianceZTest}) = true
has_p_value(::Type{UnequalVarianceZTest}) = true
function call_test(::Type{UnequalVarianceZTest}, x, y, simulation)
return UnequalVarianceZTest(x, y)
end

@testset "OneSampleZTest" begin
results = simulate(
OneSampleSimulation(Normal(0.0, 1.0), 100),
OneSampleZTest,
10_000,
)
analyze_simulation(results)
end

@testset "EqualVarianceZTest" begin
results = simulate(
TwoSampleSimulation(Normal(0.0, 1.0), Normal(0.0, 1.0), 100, 100),
EqualVarianceZTest,
10_000,
)
analyze_simulation(results)
end

@testset "UnequalVarianceZTest" begin
results = simulate(
TwoSampleSimulation(Normal(0.0, 1.0), Normal(0.0, 2.0), 100, 100),
UnequalVarianceZTest,
10_000,
)
analyze_simulation(results)
end
end