the RH decision rule: answer only when the winner is clearly ahead
Source:R/scoreboard.R
match_scoreboard_rh.RdNarayanan & Shmatikov's Scoreboard-RH pairs the score with a refusal: the attacker computes the eccentricity of the score distribution – how far the best candidate is ahead of the runner-up, in units of the spread of that record's scores – and outputs no answer at all when it falls below a threshold. That is what makes the attack *robust*: it trades recall for precision, and an attacker who only claims what they are sure of is the realistic one.
Usage
match_scoreboard_rh(
scores,
phi = 0,
seed = 0L,
assignment = c("greedy", "optimal"),
...
)Arguments
- scores
a score table, normally from [score_scoreboard()]
- phi
eccentricity threshold below which the attacker declines to answer (default 0: always answer, so the result is the plain best-match attack)
- seed
integer seed for the tie-break (default 0L)
- assignment
`"greedy"` (default, each ANON record chosen independently, as in the paper) or `"optimal"` to additionally impose the one-to-one constraint via [match_optimal()]
- ...
passed to the underlying matcher
Value
a data frame as returned by [match_greedy()]: ANON_ROW_NUMBER, RAW_ROW_NUMBER, CONFIDENCE, RESULT. Records the attacker declined have `RAW_ROW_NUMBER = NA` and `RESULT = FALSE`, and keep their row, so the trial count is unaffected by how selective the attacker was.
Details
This is a thin wrapper: it is [match_greedy()] with `confidence = "margin"`, which is where the eccentricity already lives (Issue #16). It exists so the algorithm can be found under the name the paper gives it.
Choosing phi
The paper's threshold of 1.5 is not portable, and using it blind is a trap worth naming: eccentricity is scaled by the sd of a record's candidate scores, so what counts as "clearly ahead" depends entirely on the score and the number of candidates. On some of this package's fixtures no record anywhere reaches 1.5, and a blind `phi = 1.5` would return zero reidentifications – output that is indistinguishable from a genuinely safe data set. A threshold rejecting everything raises a warning for exactly that reason. Take `phi` from the observed distribution (`reid_confidence(scores, "margin")$CONFIDENCE`), or leave it at 0 and read the precision-recall curve from [reid_evaluate()] instead.
References
Narayanan, A. and Shmatikov, V. (2008) Robust De-anonymization of Large Sparse Datasets. IEEE Symposium on Security and Privacy, 111-125.
Examples
anon <- data.frame(
ROW_NUMBER = 1:3,
I1 = c(5, NA, 1), I2 = c(NA, 2, 2), I3 = c(3, 4, NA), I4 = c(NA, 1, 5)
)
d <- join_raw_anon_data(anon, anon)
match_scoreboard_rh(score_scoreboard(d, c("I1", "I2", "I3", "I4")))
#> ANON_ROW_NUMBER RAW_ROW_NUMBER CONFIDENCE RESULT
#> 1 1 1 1.732051 TRUE
#> 2 2 2 1.309307 TRUE
#> 3 3 3 1.309307 TRUE