The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
select_max_dist() selects items using the
entire item-exposure history. It treats the item pool as a
weighted graph and administers the item farthest, in shortest-path
distance, from the items a respondent has already seen. This balances
exposure control against measurement efficiency.
The item pool is a weighted graph: nodes are items, and edge weights
derive from the co-exposure matrix adj_mat (entry \((i, j)\) is the number of respondents who
have seen both items). The Floyd–Warshall algorithm
(Rfast::floyd()) turns the edge-weight matrix \(W\) into an all-pairs shortest-path
distance matrix \(D\). For each
respondent, the distance of a candidate item to the set of administered
items is the minimum distance to any of them, and the farthest candidate
is administered (ties broken by maximum information).
The edge-weight function maps co-exposure counts to graph weights, and the choice shapes behavior. All of these are bundled and unchanged:
edge_weight_inverse(adj_mat, alpha = 1) # 1 / (adj_mat + alpha)
edge_weight_negative_log(adj_mat, alpha = 1) # -log(adj_mat + alpha)
edge_weight_linear(adj_mat, max_co_responses = NULL) # adj_mat / max(adj_mat)
edge_weight_power(adj_mat, beta = 0.5, alpha = 1) # (adj_mat + alpha)^beta
edge_weight_exponential(adj_mat, lambda = 0.1) # exp(-lambda*(adj_mat+alpha))beta < 1 dampens and
beta > 1 amplifies the effect of high co-response
counts.select_max_dist() follows the item selection contract
(vignette("item-selection")): it works on the matrix
administration state and returns an updated admin. After
the distance matrix is computed, the per-item distances are obtained
with Rfast::colMins() rather than a row-wise data-frame
operation:
select_max_dist <- function(pers, item, R, admin, adj_mat = NULL, n_candidates = 1) {
if (!any(admin != 0)) {
admin[, seq_len(min(5, ncol(admin)))] <- 1L # seed five items
return(admin)
}
dist_mat <- Rfast::floyd(1 / adj_mat) # all-pairs shortest paths
info <- { # 2PL information matrix
lin <- sweep(outer(pers$theta, item$b, "-"), 2, item$a, "*")
P <- stats::plogis(lin); sweep(P * (1 - P), 2, item$a^2, "*")
}
for (i in which(rowSums(admin == 0) > 0)) {
administered <- which(admin[i, ] != 0)
candidates <- which(admin[i, ] == 0)
sub <- dist_mat[administered, candidates, drop = FALSE]
cand_dist <- if (length(administered) == 1L) sub[1, ] else Rfast::colMins(sub, value = TRUE)
pool <- candidates[cand_dist >= max(cand_dist)] # farthest items
admin[i, pool[which.max(info[i, pool])]] <- 1L # tie-break by information
}
admin
}select_max_dist_enhanced() is identical except that the
edge weights come from a user-supplied edge_weight_fun
applied to adj_mat before Rfast::floyd().
A small runnable example with the default inverse weights:
sim <- meow(
select_fun = select_max_dist,
update_fun = update_theta_mle,
data_loader = data_simple_1pl,
data_args = list(N_persons = 50, N_items = 30),
select_args = list(n_candidates = 3),
fix = "item"
)
nrow(sim$results)
#> [1] 26Swap in a different edge-weight function through
select_max_dist_enhanced():
# Power transformation with beta = 0.3
meow(
select_fun = select_max_dist_enhanced,
update_fun = update_theta_mle,
data_loader = data_simple_1pl,
data_args = list(N_persons = 100, N_items = 50),
select_args = list(
n_candidates = 3,
edge_weight_fun = edge_weight_power,
edge_weight_args = list(beta = 0.3, alpha = 1)
),
fix = "item"
)| Strategy | Goal | Trade-off |
|---|---|---|
| Inverse (default) | spread exposure across dissimilar items | may over-expose clusters |
| Linear | keep item clusters / topic areas together | can reduce efficiency |
| Power | tune sensitivity to co-response counts | requires choosing beta |
| Exponential | strong exposure control | can reduce efficiency |
Rfast::floyd() is \(O(n^3)\) in the number of items and is run
each iteration, so network selection is more expensive than
select_max_info().n_candidates (1–5) to trade exposure
control against measurement efficiency, and compare against simpler
selectors as a baseline.These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.