NEWS.md

ebrahim.gof 2.10.0

Behaviour change

To reproduce a p-value of 2.9.0, pass its groups: ef.gof(y, p, groups = pmin(ceiling(rank(p, ties.method = "first") / floor(n / G)), G)). What takes the EF p-value changes with it: the EF row of run.all.gof(), the Ensemble.Univ(3DEF+EF) row, def.ensemble.gof(add_ef = TRUE), legoft() and gof.features().

New features

New functions

Performance

Documentation

Bug fix

ebrahim.gof 2.9.0

Bug fix

New function

Change to the default reading

Behaviour change

Documentation

New features

ebrahim.gof 2.8.0

Bug fix

New features

Behaviour changes

Documentation

ebrahim.gof 2.7.0

Bug fix

Documentation

New features

The reference is built by replacing the fitted Bernoulli variance, which shrinkage inflates towards one quarter, by a de-noised estimate of the null variance obtained from the fit alone through the observable adjustments of Bellec (2025), and then reading the exact tail of the resulting weighted chi-squared law (Davies 1980).

Three statistics are returned. SC.EDGE.adaptive is the one to prefer: it projects the corrected residual onto orthogonal polynomials in the group-mean fitted probability and chooses the degree from the data, keeping the cubic direction only when the fitted index is accurate enough to carry a cubic signal. SC.HL is the shrinkage-corrected Hosmer-Lemeshow statistic, reported for continuity with that tradition; its reference relies on a constant calibrated by simulation, which does not transfer to every design, and ?calm.gof says where it fails.

The reference is validated for aspect ratios p/n up to 0.4 and for penalties that shrink towards zero. The lasso is not covered.

Dependency change

ebrahim.gof 2.6.0

New features

The network was trained once, offline, on simulated departures and ships frozen as 18,273 numbers. Nothing is trained when you call the function, and the p-value is the rank of the observed score inside your own parametric bootstrap -- so the level is a property of the calibration, not of what the network learned. A bootstrap refit that fails is scored +Inf, counting against rejection.

Implemented in pure base R (the forward pass is a few small matrix multiplies), so the package still needs no Python and no additional dependency. The shipped weights are verified against the training framework in tests/testthat/test-deepgof1.R; agreement is to 5e-11.

It is a small-sample instrument: on a published benchmark it outpowers every classical partition test at every sample size, most clearly at n = 50 to 200, while tests that use the whole covariate space rather than a two-covariate grid do better overall. The training corpus, training code, benchmark harness and every per-replicate p-value behind those numbers are archived separately from this package.

ebrahim.gof 2.5.0

New features

On twelve held-out misspecification families the rule attained higher mean power than each of the fourteen individual tests in the study, at n = 500 and n = 1000. It does not dominate them family by family: against the two covariate-space directed tests the advantage is in the mean rather than in per-family consistency, which is the dilution a combination pays for having no catastrophic blind spot.

It does not beat an equal-weight Cauchy combination of the same eleven members (Liu and Xie, 2020). The difference is +0.0045 at n = 500 (sign test p = 0.23) and -0.0005 at n = 1000. Users who want the simpler rule lose nothing measurable; legoft() reduces to it exactly at the boundary of its weight family, so it cannot do worse.

Note the scale: lambda is on the theory scale, lambda = n * lambda_glmnet. Passing a \pkg{glmnet} lambda unchanged is the commonest way to misuse this function.

The implementation is vendored byte-identical from the source of Ebrahim (2026), "Shrinkage invalidates the Hosmer--Lemeshow test", so the paper and the package compute the same numbers. It depends only on base R and stats.

The domains are defined by what the members can see rather than by taxonomy. INDEX holds the seven statistics that read the linear predictor -- the grouping tests, which stratify on fitted risk, and the directed tests, which examine bends in that same index. COV holds the four that read directions orthogonal to it. Calibration and link readings are pooled deliberately: they are not separately identifiable, because fitted risk is a monotone transform of the index, so both read one axis.

A verdict locates the evidence. It does not name the repair: a departure of one kind can move members assigned to the other domain, and an unimplicated domain is not thereby certified correct.

Documentation

The failure modes are stated because they are the part users get wrong. Pigeon--Heyse is conservative in sparse designs; Stukel's two-parameter form does not always hold its nominal level; HL-equalwidth is frequently not computable when fitted risks are concentrated in a narrow band; GiViTI's internal and external forms are not interchangeable; and the chi-squared reference with G - 2 degrees of freedom was established by simulation rather than derived, so G = 10 is a convention and worth varying.

Performance

Measured against the previous implementation, both byte-compiled and called through the installed package: 2.5x at n = 200, 4.5x at n = 500, 11.0x at n = 1000, 42.6x at n = 2000 and 87.7x at n = 3000 (48.1 s down to 1.1 s, and 139.9 s down to 1.6 s). The ratio grows with n because the change is O(n^3) to O(n^2 p) rather than a constant factor; at small n the shared cost of building the kernel matrix, which is unchanged, still dominates. The largest relative difference in the statistic was 6e-14 across null models, misspecified models, factor covariates and designs whose fitted probabilities reach machine zero. Rejection rates agree to four decimal places under the null and under alternatives, so no previously reported result moves. tests/testthat/test-lecessie-algebra.R pins the agreement at 1e-12 relative against the previous code, kept verbatim.

Memory is unchanged: the test still builds the n-by-n kernel matrix and is still O(n^2) in space. This change buys time, not memory.

Notes on what is not here

ebrahim.gof 2.4.1

Bug fix

Wording corrected in 2.5.0. The 2.4.1 note said "the statistic was always correct". That is true of the raw Q and misleading about the Statistic column users actually see: that column reports Q rescaled by the matched moments, Q * 2E[Q]/Var[Q], so it moves with the correction exactly as the degrees of freedom and the p-value do. On the package's own regression example the reported statistic goes from 16.794627 to 15.895427 and the p-value from 0.149928 to 0.177213 (the matched degrees of freedom are 11.648746 after the fix). Expect the printed statistic and degrees of freedom to change too, not only the p-value. The consequence was a mildly liberal test: at n = 1000 with the default bandwidth the empirical null size was about 0.063 instead of the exact-moment value 0.054. Users comparing results across versions should expect slightly larger p-values (hence slightly lower power) from le-Cessie after this fix.

ebrahim.gof 2.4.0

Print method

Battery behaviour

New features

New data

ebrahim.gof 2.3.0

Documentation and data (toolbox reframe)

ebrahim.gof 2.2.0

New features

ebrahim.gof 2.1.1

New features

ebrahim.gof 2.1.0

New features

run.all.gof() additions and improvements

ebrahim.gof 2.0.0

New features

Breaking changes

Pending for the 2.0.0 release

ebrahim.gof 1.0.0

Initial Release

This is the first release of the ebrahim.gof package, implementing the Ebrahim-Farrington goodness-of-fit test for logistic regression models.

Features

Key Capabilities

Advantages over Existing Tests

Technical Details

References

Author

Ebrahim Khaled Ebrahim (Alexandria University) Email: ebrahimkhaled@alexu.edu.eg



Try the ebrahim.gof package in your browser

Any scripts or data that you put into this service are public.

ebrahim.gof documentation built on Oct. 11, 2026, 5:07 p.m.