score a RAW/ANON table using only the columns an attacker can see
Source:R/knowledge.R
score_by_knowledge.RdBuilds one score per visible column with the score function that column's type declares, and combines them with [combine_scores()].
Usage
score_by_knowledge(
dat_raw_anon,
knowledge,
row_number = "ROW_NUMBER",
weights = NULL,
normalize = c("range", "zscore", "rank", "none"),
method = c("weighted", "mahalanobis"),
split = ":",
cov_from = c("raw", "anon", "pooled"),
ridge = 1e-06,
source = c("anon", "raw", "pooled"),
weight = c("idf", "inv_log", "inv", "none"),
hierarchy = NULL,
rules = NULL,
screen = c("warn", "drop", "none"),
alpha = 0.05
)Arguments
- dat_raw_anon
dataframe of raw_anon form
- knowledge
an [attacker_knowledge()] object
- row_number
name of the row-number column *before* RAW_/ANON_ prefixing (default "ROW_NUMBER")
- weights
numeric vector of per-column weights, one per visible column, in the order of `knowledge$visible` (default: all 1)
- normalize
normalisation applied to each column before combining; see [normalize_scores()]. Default `"range"`.
- method
`"weighted"` (default) or `"mahalanobis"`; see [score_multi()]
- split
separator passed to [score_dist()] for `"dist"` columns (default ":"). Treated as a literal string, never as a regular expression.
- cov_from, ridge
passed to [score_mahalanobis()] when `method = "mahalanobis"`
- source, weight
passed to [score_idf_match()] for `"idf"` columns
- hierarchy, rules
passed to [score_containment()] for `"containment"` columns
- screen, alpha
passed to [score_multi()]; they decide what happens to a visible column that, measured alone, carries no signal. This matters more here than anywhere else: the W / M / S levels are meant to be read as an increasing sequence, and a dead column entering at level M or S can make the *higher* level report a lower risk than the lower one.
Details
NORMALISATION. The per-column scores are rescaled to \[0, 1\] by default. Without it, an unweighted sum is dominated by whichever column happens to have the widest numeric range, so *adding* a column the attacker knows can make the attack worse – which would make the whole W/M/S comparison meaningless. A column with no variation at all contributes exactly 0, because it cannot discriminate between candidates.
The combination itself is done by [score_multi()] (Issue #14); this function only decides *which* columns are handed to it. `normalize` and `method` therefore accept everything `score_multi()` does, including the correlation aware `method = "mahalanobis"`. The default is unchanged (`"range"` / `"weighted"`), which is the stopgap Issue #13 needed.
Examples
d <- create_dummy_qi_data(people = 20, seed = 1)
j <- join_raw_anon_data(d, d)
k <- dummy_qi_knowledge("M")
match_greedy(score_by_knowledge(j, k))
#> ANON_ROW_NUMBER RAW_ROW_NUMBER CONFIDENCE RESULT
#> 1 1 1 0.8099614 TRUE
#> 2 2 2 0.6204426 TRUE
#> 3 3 3 1.2314008 TRUE
#> 4 4 4 1.2916034 TRUE
#> 5 5 5 0.5689543 TRUE
#> 6 6 6 0.8699313 TRUE
#> 7 7 7 0.6954175 TRUE
#> 8 8 8 0.3660894 TRUE
#> 9 9 9 1.8013905 TRUE
#> 10 10 10 0.5145569 TRUE
#> 11 11 11 0.3864884 TRUE
#> 12 12 12 1.0048362 TRUE
#> 13 13 13 0.4184709 TRUE
#> 14 14 14 0.5300424 TRUE
#> 15 15 15 1.2977608 TRUE
#> 16 16 16 0.9785062 TRUE
#> 17 17 17 0.8012976 TRUE
#> 18 18 18 0.5106757 TRUE
#> 19 19 19 0.4085725 TRUE
#> 20 20 20 2.4519630 TRUE