| Title: | Projection Pursuit with Monotone Scoring for Ordered Categorical Data |
|---|---|
| Description: | Exploratory projection pursuit for ordered categorical (ordinal) items. Monotone category scores and a projection direction are estimated jointly by maximizing a weighted characteristic-function discrepancy between the projected joint distribution and the projection implied by item independence with the observed marginal distributions. Fitted category dictionaries and loadings can be frozen and evaluated on held-out data, with a finite-sample-valid held-out permutation test, a refitted permutation test, a variance/shape decomposition of the index and bootstrap stability summaries. |
| Authors: | Diego Andres Perez Ruiz [aut, cre] |
| Maintainer: | Diego Andres Perez Ruiz <[email protected]> |
| License: | GPL-3 |
| Version: | 0.1.0 |
| Built: | 2026-11-14 12:03:25 UTC |
| Source: | https://github.com/dapr12/ordpp |
Wraps category scores and a direction obtained by another method
(for example optimal-scaling or polychoric PCA) as an ordpp object, so
that it can be evaluated with validate_ordpp,
heldout_test_ordpp and decompose_ordpp.
as_ordpp_map(x, scores, direction, weights = NULL, frequencies = seq(0.2, 3, length.out = 15), index = c("full", "shape"), label = "external")as_ordpp_map(x, scores, direction, weights = NULL, frequencies = seq(0.2, 3, length.out = 15), index = c("full", "shape"), label = "external")
x |
Training data used to standardize the scores. |
scores |
List with one numeric vector per item, one value per observed category in increasing category order. |
direction |
Loading vector. |
weights |
Optional positive training weights. |
frequencies, index
|
As in |
label |
Name stored in the |
An object of class "ordpp" that can be evaluated but not refitted.
s <- simulate_ordpp(150, 4, seed = 1) m <- as_ordpp_map(s$x, lapply(s$x, function(v) sort(unique(v))), direction = c(1, 1, 1, -1), label = "sum score") validate_ordpp(m, s$x)s <- simulate_ordpp(150, 4, seed = 1) m <- as_ordpp_map(s$x, lapply(s$x, function(v) sort(unique(v))), direction = c(1, 1, 1, -1), label = "sum score") validate_ordpp(m, s$x)
Reports the ratio of the projection variance to its independence variance together with the full and shape indices.
decompose_ordpp(object, newdata = NULL, weights = NULL)decompose_ordpp(object, newdata = NULL, weights = NULL)
object |
A fitted |
newdata |
Optional held-out data; if omitted the training data are used. |
weights |
Optional positive weights for |
At low frequencies the full index is dominated by
, which is driven by pairwise
correlations between transformed items and rewards both inflated and deflated
projection variance. The shape index removes this component. A variance ratio
well below one indicates a contrast among positively correlated items.
A one-row data frame with variance_ratio, full and
shape.
s <- simulate_ordpp(150, 5, seed = 1) f <- suppressWarnings(ordpp(s$x, scoring = "linear", nstart = 1, maxit = 30, seed = 2)) decompose_ordpp(f)s <- simulate_ordpp(150, 5, seed = 1) f <- suppressWarnings(ordpp(s$x, scoring = "linear", nstart = 1, maxit = 30, seed = 2)) decompose_ordpp(f)
Tests mutual independence of the items in held-out data along a map (scores and loadings) estimated on separate observations.
heldout_test_ordpp(object, newdata, B = 999L, seed = NULL, type = NULL) ## S3 method for class 'ordpp_test' print(x, ...)heldout_test_ordpp(object, newdata, B = 999L, seed = NULL, type = NULL) ## S3 method for class 'ordpp_test' print(x, ...)
object |
A fitted |
newdata |
Held-out data not used to estimate |
B |
Number of permutations. |
seed |
Optional seed for reproducible permutations; the caller's random number state is restored on exit. |
type |
Index type; defaults to the fitted type. |
x |
A test result. |
... |
Unused. |
Each item column of the held-out data is permuted independently and
the index is recomputed with the map held fixed. Under iid rows and mutual
item independence the permuted samples are exchangeable with the observed one,
so the Monte Carlo p-value is valid in finite
samples. Validity requires that newdata played no part in fitting or
tuning. No refitting is performed, so the test is fast. It is not valid for
clustered or complex survey samples.
An object of class "ordpp_test" with statistic,
null, p.value, B, n, type, method
and hypothesis.
s <- simulate_ordpp(300, 5, seed = 1) f <- suppressWarnings(ordpp(s$x[1:150, ], scoring = "linear", nstart = 1, maxit = 30, seed = 2)) heldout_test_ordpp(f, s$x[151:300, ], B = 99, seed = 3)s <- simulate_ordpp(300, 5, seed = 1) f <- suppressWarnings(ordpp(s$x[1:150, ], scoring = "linear", nstart = 1, maxit = 30, seed = 2)) heldout_test_ordpp(f, s$x[151:300, ], B = 99, seed = 3)
Jointly estimates monotone category scores and a unit-length projection direction by maximizing a characteristic-function discrepancy between the projected joint distribution and its counterpart under item independence with the observed marginals.
ordpp(x, weights = NULL, scoring = c("item", "common", "linear"), lambda = 0, gamma = 0.01, nstart = 3L, maxit = 500L, frequencies = seq(0.2, 3, length.out = 15), min_gap = 0.03, variance_floor = 0.05, index = c("full", "shape"), seed = NULL) ## S3 method for class 'ordpp' predict(object, newdata, ...) ## S3 method for class 'ordpp' print(x, ...) ## S3 method for class 'ordpp' plot(x, type = c("projection", "scores"), ...)ordpp(x, weights = NULL, scoring = c("item", "common", "linear"), lambda = 0, gamma = 0.01, nstart = 3L, maxit = 500L, frequencies = seq(0.2, 3, length.out = 15), min_gap = 0.03, variance_floor = 0.05, index = c("full", "shape"), seed = NULL) ## S3 method for class 'ordpp' predict(object, newdata, ...) ## S3 method for class 'ordpp' print(x, ...) ## S3 method for class 'ordpp' plot(x, type = c("projection", "scores"), ...)
x |
For |
weights |
Optional positive observation weights; their scale is irrelevant. |
scoring |
|
lambda |
Nonnegative L1 penalty on loadings. Encourages concentration; it does not perform exact variable selection. |
gamma |
Nonnegative penalty on unequal adjacent score gaps. |
nstart |
Number of optimizer starts (the first is the leading principal component of equally scored items). |
maxit |
Iteration budget per start for L-BFGS-B. |
frequencies |
Positive frequencies, on the scale of the independence standard deviation, at which characteristic functions are compared. |
min_gap |
Lower bound on each raw gap as a fraction of the mean gap. |
variance_floor |
Soft lower bound on the projection variance (the reference variance is one). |
index |
|
seed |
Optional seed for reproducible starts; the caller's random number state is restored on exit. |
object |
A fitted |
newdata |
Complete data with the same named items and no unseen categories. |
type |
Kernel density of the training projection, or category-score curves. |
... |
Further graphical arguments, or unused. |
All declared categories must occur in the training data; missing
values and unseen categories are rejected. Scores are strictly increasing,
centred and of unit variance under the (weighted) training marginals. Weights
change the target distribution but do not provide design-based standard
errors. Inspect convergence, starts and at_bounds
before interpretation.
An object of class "ordpp": a list with direction,
scores, levels, variable_names, projection,
transformed, weights, index (unpenalized),
objective (penalized), roughness, projection_variance,
n, scoring, convergence, at_bounds,
starts, settings and call. predict returns the
projected scores of newdata using the frozen training dictionary.
validate_ordpp, heldout_test_ordpp,
permutation_ordpp, stability_ordpp
s <- simulate_ordpp(150, 5, seed = 1) f <- ordpp(s$x, scoring = "linear", nstart = 2, seed = 2) f predict(f, s$x[1:3, ]) # Item-specific monotone scores (slower) fi <- ordpp(s$x, scoring = "item", nstart = 2, seed = 2) fi$scoress <- simulate_ordpp(150, 5, seed = 1) f <- ordpp(s$x, scoring = "linear", nstart = 2, seed = 2) f predict(f, s$x[1:3, ]) # Item-specific monotone scores (slower) fi <- ordpp(s$x, scoring = "item", nstart = 2, seed = 2) fi$scores
Compares the characteristic function of a projection with the product of the characteristic functions of its item components, i.e. with the projection's law under item independence with the same marginals.
ordpp_index(y, direction, weights = NULL, frequencies = seq(0.2, 3, length.out = 15), type = c("full", "shape")) validate_ordpp(object, newdata, weights = NULL, type = NULL)ordpp_index(y, direction, weights = NULL, frequencies = seq(0.2, 3, length.out = 15), type = c("full", "shape")) validate_ordpp(object, newdata, weights = NULL, type = NULL)
y |
Finite numeric matrix of transformed items. |
direction |
Nonzero loading vector, one entry per column of |
weights |
Optional positive observation weights. |
frequencies |
Positive frequencies on the independence-SD scale. |
type |
|
object |
A fitted |
newdata |
Complete held-out data with known categories and named items. |
validate_ordpp freezes the fitted scores and loadings; the
reference marginals and the independence variance are re-estimated from the
held-out rows. The index measures departure from item independence along the
projection; it is not a test of polarization or of a particular factor
structure. A finite frequency grid need not detect every alternative. The
empirical index is positive in finite samples even under independence; use
heldout_test_ordpp for calibration.
A nonnegative scalar.
y <- as.matrix(expand.grid(a = c(-1, 1), b = c(-1, 1))) ordpp_index(y, c(1, 1)) # exact independence: 0 ordpp_index(cbind(c(-1, 1), c(-1, 1)), c(1, 1)) # perfect dependencey <- as.matrix(expand.grid(a = c(-1, 1), b = c(-1, 1))) ordpp_index(y, c(1, 1)) # exact independence: 0 ordpp_index(cbind(c(-1, 1), c(-1, 1)), c(1, 1)) # perfect dependence
Independently permutes each item and repeats the entire fixed-setting optimization, so that the null distribution includes the search over scores and directions.
permutation_ordpp(x, B = 99L, seed = NULL, fit = NULL, trace = FALSE, ...)permutation_ordpp(x, B = 99L, seed = NULL, fit = NULL, trace = FALSE, ...)
x |
Complete ordinal data frame. |
B |
Number of permutations. |
seed |
Optional seed for the permutations and optimizer starts; the caller's random number state is restored on exit. |
fit |
Optional |
trace |
Print progress every 10 permutations. |
... |
Fitting arguments passed to |
Valid for iid unweighted rows under mutual item independence when the
settings are fixed independently of x. If tuning parameters were chosen
using x, the selection must be repeated inside each permutation. The
test is computationally expensive; heldout_test_ordpp is a fast
alternative when a held-out sample is available.
An object of class "ordpp_test"; the observed statistic is the
maximized penalized objective of a refit to x, returned as
observed_fit. null_convergence records optimizer codes of the
null fits.
s <- simulate_ordpp(120, 4, seed = 1) f <- suppressWarnings(ordpp(s$x, scoring = "linear", nstart = 1, maxit = 20, seed = 2)) permutation_ordpp(s$x, B = 9, seed = 3, fit = f)s <- simulate_ordpp(120, 4, seed = 1) f <- suppressWarnings(ordpp(s$x, scoring = "linear", nstart = 1, maxit = 20, seed = 2)) permutation_ordpp(s$x, B = 9, seed = 3, fit = f)
Five-category items obtained by thresholding latent continuous responses, with informative and noise items.
simulate_ordpp(n = 500, p = 8, separation = 1.5, seed = NULL, strength = 1, scenario = c("mixture", "independent", "rare", "two_factor", "response_style"))simulate_ordpp(n = 500, p = 8, separation = 1.5, seed = NULL, strength = 1, scenario = c("mixture", "independent", "rare", "two_factor", "response_style"))
n |
Number of observations (at least 10). |
p |
Number of items (at least 4). |
separation |
Half-distance between the means of a two-component normal mixture for the latent factor; 0 gives a single normal factor. |
seed |
Optional seed; the caller's random number state is restored on exit. |
strength |
Multiplier of all factor loadings; small values give weak dependence for power studies, and 0 gives independent items. |
scenario |
|
Zero separation still yields dependent items through a shared factor
and is not an independence null; use scenario = "independent" for that.
A list with x, latent, group, loading,
thresholds and scenario.
s <- simulate_ordpp(100, 6, seed = 1, scenario = "independent") sapply(s$x, table)s <- simulate_ordpp(100, 6, seed = 1, scenario = "independent") sapply(s$x, table)
Refits the projection on bootstrap resamples of rows (or of clusters), aligns signs with the original direction and summarizes variability.
stability_ordpp(fit, x, B = 50L, seed = NULL, weights = NULL, cluster = NULL, trace = FALSE) ## S3 method for class 'ordpp_stability' print(x, ...)stability_ordpp(fit, x, B = 50L, seed = NULL, weights = NULL, cluster = NULL, trace = FALSE) ## S3 method for class 'ordpp_stability' print(x, ...)
fit |
A fitted |
x |
For |
B |
Number of bootstrap refits. |
seed |
Optional seed for resampling and optimizer starts; the caller's random number state is restored on exit. |
weights |
Optional weights, resampled with their rows. |
cluster |
Optional cluster identifiers; whole clusters are resampled. |
trace |
Print progress every 5 refits. |
... |
Unused. |
The summaries describe algorithmic stability. Percentile intervals after data-driven selection need not have nominal coverage, and resampling rows ignores stratification and other design features.
An object of class "ordpp_stability" with a loading
summary, the matrix of aligned directions, per-item score
matrices scores, index, convergence, absolute cosine
congruence with the original direction and the number of
failures (for example, resamples missing a rare category).
s <- simulate_ordpp(150, 4, seed = 1) f <- suppressWarnings(ordpp(s$x, scoring = "linear", nstart = 1, maxit = 20, seed = 2)) stability_ordpp(f, s$x, B = 5)s <- simulate_ordpp(150, 4, seed = 1) f <- suppressWarnings(ordpp(s$x, scoring = "linear", nstart = 1, maxit = 20, seed = 2)) stability_ordpp(f, s$x, B = 5)