Skip to contents

Narayanan & 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