Skip to content

Linking / deduplication with a list of possible candidates #83

Description

@BERENZ

Imagine that blocking variables are not free of errors (include typos, missing data etc.) so I cannot use blockData function to narrow down number of possible pairs.

As a solution, I am using approximate nearest neighbours algorithms and graphs to create blocks of records (see my blocking package). This somehow mimics the microclustering approach (see also Johndrow et al. (2018)).

However, the resulting blocks are small, containing only 2, 3, or 4 pairs. This makes them unsuitable for use with the blockData function, as the blocks are too small.

That is why I would like to ask if it is possible in some way to use the fastLink package for such cases? The main function fastLink takes all possible combinations for dfA and dfB but I would like to limit the number of pairs to the candidates and then apply the EM algorithm (FS model).

Below you may find an example with the problem (detailed description can be found here).

library(blocking)
library(data.table)
census <- read.csv("https://raw.githubusercontent.com/djvanderlaan/tutorial-reclin-uros2021/main/data/census.csv")
cis <- read.csv("https://raw.githubusercontent.com/djvanderlaan/tutorial-reclin-uros2021/main/data/cis.csv")
setDT(census)
setDT(cis)
census[is.na(dob_day), dob_day := ""]
census[is.na(dob_mon), dob_mon := ""]
census[is.na(dob_year), dob_year := ""]
cis[is.na(dob_day), dob_day := ""]
cis[is.na(dob_mon), dob_mon := ""]
cis[is.na(dob_year), dob_year := ""]
census[, txt:=paste0(pername1, pername2, sex, dob_day, dob_mon, dob_year, enumcap, enumpc)]
cis[, txt:=paste0(pername1, pername2, sex, dob_day, dob_mon, dob_year, enumcap, enumpc)]
census[, x:=1:.N]
cis[, y:=1:.N]

## create blocks based on the ANN algorithm and graphs
set.seed(2024)
result1 <- blocking(x = census$txt, y = cis$txt, verbose = 1, n_threads = 8)

You can see that the majority of blocks are of size 2.

> result1
========================================================
Blocking based on the nnd method.
Number of blocks: 23793.
Number of columns used for blocking: 1079.
Reduction ratio: 1.0000.
========================================================
Distribution of the size of the blocks:
    2     3     4     5 
22998   772    21     2 

Here is the list of candidate pairs.

> head(result1$result)
       x     y block       dist
   <int> <int> <num>      <num>
1:     1  8152  8020 0.02941167
2:     2  8584  8441 0.04878050
3:     3 20590 19941 0.01290381
4:     4 18456 17935 0.07158583
5:     5 17257 16801 0.05370837
6:     6 19868 19265 0.05675775

I would like to use this information about pairs (x, y) for the linkage using the fastLink package.

EDIT: to fully understand my problem I provide an example using the reclin2 package.

library(reclin2)

## add blocks to each dataset
census[result1$result, on = "x", block := result1$result$block]
cis[result1$result, on = "y", block := result1$result$block]

## reclin2 pipeline
pairs <- pair_blocking(x = census, y = cis, on = "block") |>
  compare_pairs(on = c("pername1", "pername2", "sex", "dob_day", "dob_mon", "dob_year", "enumcap", "enumpc"),
                default_comparator = cmp_jarowinkler(0.9))

em_res <- problink_em(~ pername1 + pername2+sex + dob_day + dob_mon + dob_year + enumcap + enumpc, data = pairs)

predict(em_res, pairs = pairs, add = TRUE) |>
  select_threshold(pairs = _, "threshold", score = "weights", threshold = 8) |> 
  select_n_to_m(pairs = _, "weights", variable = "ntom", threshold = 0) |>
  link(pairs = _, selection = "ntom") 

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions