Generalized function-on-scalar regression¶
This example treats a binary AOI-occupancy trajectory as a repeated, non-Gaussian functional response.
Model¶
Suppose every trial contains a binary trajectory
where 1 means that the gaze sample belongs to the target AOI. The marginal model is
Fit¶
from eyetrajectoriespy import (
fit_generalized_function_on_scalar_regression,
)
fit = fit_generalized_function_on_scalar_regression(
trajectories,
design,
predictors=("condition",),
participant_column="participant_id",
dimension="target_aoi",
family="binomial",
basis_size=4,
spline_degree=2,
)
The condition predictor may vary from trial to trial within participant. The participant remains the independent cluster for robust GEE inference.
Inspect coefficient functions¶
fit.coefficient_functions
fit.coefficient_standard_errors
fit.mean_functions
The coefficient curves are on the logit scale. mean_functions contains the
fitted marginal Bernoulli probabilities for the observed trial predictor rows.
from eyetrajectoriespy import (
generalized_function_on_scalar_coefficient_frame,
)
coefficient_frame = generalized_function_on_scalar_coefficient_frame(
fit
)
Whole-participant bootstrap¶
from eyetrajectoriespy import (
bootstrap_generalized_function_on_scalar_coefficients,
generalized_function_on_scalar_simultaneous_bands,
)
bootstrap = bootstrap_generalized_function_on_scalar_coefficients(
fit,
n_bootstrap=1000,
random_state=51,
)
band = generalized_function_on_scalar_simultaneous_bands(
bootstrap,
confidence_level=0.95,
simultaneous_scope="coefficient",
)
The bootstrap resamples complete participant bundles. Trials and time points are never independently resampled.
If a participant is selected twice in one bootstrap replicate, the two sampled copies receive different GEE cluster IDs.
Plot¶
from eyetrajectoriespy import (
plot_generalized_function_on_scalar_coefficients,
)
plot_generalized_function_on_scalar_coefficients(
band,
coefficient="condition",
)
A positive condition coefficient at time \(t\) indicates larger marginal log-odds of target-AOI occupancy at that time, holding the other declared predictors fixed.
Grouped-binomial success counts¶
When each functional observation summarizes several binary opportunities, retain the integer successes and denominator explicitly:
grouped_fit = fit_generalized_function_on_scalar_regression(
grouped_success_trajectories,
design,
predictors=("condition",),
participant_column="participant_id",
dimension="successes",
family="binomial",
binomial_denominator=trial_counts,
basis_size=4,
spline_degree=2,
)
The trajectory values are integer successes. trial_counts contains the
corresponding positive integer denominators. The result retains successes,
denominators, observed proportions and fitted expected successes, while the
coefficient functions remain marginal log-odds effects on success probability.
Do not replace successes / trial_counts with a proportion-only response:
the denominator is required because 2/3 and 670/1000 do not contain the same
amount of information.
Count-valued response and exposure-adjusted rates¶
For non-negative integer count functions use the same interface with
family="poisson". Without exposure, coefficients describe log expected
counts:
count_fit = fit_generalized_function_on_scalar_regression(
count_trajectories,
design,
predictors=("condition",),
participant_column="participant_id",
dimension="fixation_count",
family="poisson",
basis_size=4,
spline_degree=2,
)
When counts were accumulated under unequal, scientifically meaningful observation opportunities, supply exposure explicitly:
rate_fit = fit_generalized_function_on_scalar_regression(
count_trajectories,
design,
predictors=("condition",),
participant_column="participant_id",
dimension="fixation_count",
family="poisson",
exposure=valid_monitored_seconds,
exposure_units="seconds",
basis_size=4,
spline_degree=2,
)
Then rate_fit.rate_functions contains fitted marginal rates,
rate_fit.mean_functions contains exposure-specific expected counts, and
rate_fit.linear_predictor_rate is separated from
rate_fit.linear_predictor_count.
from eyetrajectoriespy import generalized_function_on_scalar_exposure_frame
exposure_frame = generalized_function_on_scalar_exposure_frame(rate_fit)
exposure_frame.attrs["exposure_audit"]
Use exposure only when expected count is substantively proportional to the declared denominator. The package does not infer exposure from time-grid spacing, trial duration, sample counts, or metadata.
Reporting¶
from eyetrajectoriespy import (
generalized_function_on_scalar_reporting_text,
)
print(
generalized_function_on_scalar_reporting_text(
fit,
band=band,
)
)
Report the family/link, explicit basis dimension, participant cluster definition, working-independence choice, robust sandwich covariance, bootstrap resampling unit and simultaneous scope. Do not describe these marginal coefficients as conditional random-effects coefficients.