-
Notifications
You must be signed in to change notification settings - Fork 2
Implemented some goodness-of-fit tests #60
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
Conversation
- Bootstrap and non-bootstrap based tests
- KSDistance statistic for hypothesis testing
- Time re-scaled events againt uniform
- Time re-scaled inter events against exponential
- Tests take types instead of instances of point processes - `NoBootstrapTest` may take an instances TODO: - Add Tests
- Statistics now work for general types
- Added a `AbstractRNG` to the tests to control simulations
- `BootstrapTest` and `NoBootstrapTest` are subtypes of `HypothesisTest`
- Fields have fixed types, as done in `HypothesisTests.jl`
- Fixed some mistakes
TODO: Add tests
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
ISSUES:
- Type piracy: needed to implement `fit` for the `Dirac` distribution
- Names: type and method names could maybe be improved
- PPTest: Fields in `BootstrapTest` and `NoBootstrapTest` make sense
only for simulation based tests. Anything more general?
`Distributions.jl` does not provide a `fit` method, so a separate `fit` method for unmarked Poisson processes was added.
src/HypothesisTests/pp_test.jl
Outdated
| on the event times according to the selected distribution. | ||
| =# | ||
| function transform(::Type{<:Uniform}, pp::AbstractPointProcess, h) | ||
| (length(h.times) < 1) && return 1.0 # No events ⇒ maximum distance |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this line could be a problem. The first is that this creates a type instability. In the normal branching logic we return a tuple (inter_transf, Uniform(1)) but in this other logic we return just 1.0. Would it make more sense to throw an error? 1.0 doesn'thave a clear statistical meaning to me as we can't even really do any type of GOF here? E.g., if i witnessed a single observation how can i really say whether or not it fits my model without strong prior info? We could also throw a warning and do something like:
if length(h.times) < 2
@warn "No inter-event times: length(h.times) = $(length(h.times))"
return Float64[], Uniform(1)
endThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is a reminiscent of some old code, it does not make sense.
In principle, we could just send the result of the time_transform as it is, no matter if it is empty or not.
Now, perhaps performing a test on an empty history would not make sense, so it might make sense to throw an error if the argument h in NoBootstrapTest or BootstrapTest is an empty history. What would make sense is if one of the simulated histories inside the loop are empty.
The thing is how to define the empirical cumulative distribution when the number of samples is 0. To me, it makes sense to define it to be
src/HypothesisTests/pp_test.jl
Outdated
| end | ||
|
|
||
| function transform(::Type{<:Exponential}, pp::AbstractPointProcess, h) | ||
| (length(h.times) < 2) && return 1.0 # If `h` has only 2 elements, than there are no interevent times |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as in the uniform case.
- Fixed tests for empty histories - Added `@testset`s for clarity
|
I think everything was resolved. Two remarks: Not sure about all the names, especially And I kept the value of the test statistic equal to 1 when the simulated event history is empty, but I raise an error when history to be tested is empty. The exception is when the |
| - `pp::Union{AbstractPointProcess, Type{<:AbstractPointProcess}}`: the null hypothesis model family | ||
| - `h::History`: the observed event history | ||
| - `n_sims::Int=1000`: number of simulations to perform for the test | ||
| - `rng::AbstractRNG=default_rng()test statistics from simulated data`: Random number generator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| - `rng::AbstractRNG=default_rng()test statistics from simulated data`: Random number generator | |
| - `rng::AbstractRNG=default_rng()`: Random number generator |
|
My thoughts on naming:
|
| function StatsAPI.pvalue(bt::BootstrapTest) | ||
| (count(>=(bt.stat), bt.sim_stats) + 1) / (bt.n_sims + 1) | ||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| function StatsAPI.pvalue(bt::BootstrapTest) | |
| (count(>=(bt.stat), bt.sim_stats) + 1) / (bt.n_sims + 1) | |
| end | |
| function StatsAPI.pvalue(bt::BootstrapTest) | |
| return (count(>=(bt.stat), bt.sim_stats) + 1) / (bt.n_sims + 1) | |
| end |
src/HypothesisTests/pp_test.jl
Outdated
| Calculate the p-value of a goodness-of-fit test on a process. | ||
|
|
||
| # Arguments | ||
| - `::PPTest`: the bootstrap test result object |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| - `::PPTest`: the bootstrap test result object | |
| - `::PPTest`: the test result object |
|
Left my last final comments as well! |
|
Incorporated the minor suggestions, but, more importantly, refactored the multi-threaded part of the tests. I was getting an error in |
|
Looks good to me. Just approved the merge |
|
Added a lock for accessing the master rng in the tests. Although the |
Statistics
Implemented two versions of the Kolmogorov-Smirnov distance as a test statistic.
Tests
Bootstrap and non-bootstrap based tests
Bootstrap
Non-bootstrap
Same as above, but skip step 4, so use estimation in step 1 to calculate test statistic
Issues
Types and methods names
Perhaps the names can be improved. If you have any suggestions...
Type piracy
Tried implementing a
fitmethod for theDiracdistribution (there isn't one inDistributions.jl), so thefitmethod works for theUnivariatePoissonProcess, but tests complain about type piracy. Decided to implement afitmethod specifically for unmarked Poisson processes instead.