Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Approximate text matching with the stringdist package

4,159 views

Published on

Approximate text matching with the stringdist package

Approximate text matching with the stringdist package

  1. 1. . ...... Approximate text matching with the stringdist package Mark van der Loo Statistics Netherlands useR!2014 markvanderloo.eu @MarkPJvanderLoo ........ ..... ................. ................. ................. .... .... . .... ........ .
  2. 2. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. The stringdist package . Fuzzy dictionary lookup .. ...... amatch Fuzzy matching equivalent of match ain Fuzzy matching equivalent of %in% Mark van der Loo Approximate text matching with the stringdist package
  3. 3. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. The stringdist package . Fuzzy dictionary lookup .. ...... amatch Fuzzy matching equivalent of match ain Fuzzy matching equivalent of %in% . String metrics .. ...... stringdist Pairwise distances stringdistmatrix Distance matrix qgrams Compute q-gram profile Mark van der Loo Approximate text matching with the stringdist package
  4. 4. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. The stringdist package . Fuzzy dictionary lookup .. ...... amatch Fuzzy matching equivalent of match ain Fuzzy matching equivalent of %in% . String metrics .. ...... stringdist Pairwise distances stringdistmatrix Distance matrix qgrams Compute q-gram profile . Design“philosophy” .. ...... Create interfaces that resemble base R (e.g. match, adist, nchar, agrep) Mark van der Loo Approximate text matching with the stringdist package
  5. 5. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Dictionary lookup > match("leia", c("leela","leia")) [1] 2 Mark van der Loo Approximate text matching with the stringdist package
  6. 6. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Dictionary lookup > match("leia", c("leela","leia")) [1] 2 > match("liea", c("leela","leia")) [1] NA Mark van der Loo Approximate text matching with the stringdist package
  7. 7. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Dictionary lookup > match("leia", c("leela","leia")) [1] 2 > match("liea", c("leela","leia")) [1] NA > amatch("liea", c("leela","leia"), maxDist=1) [1] 2 Mark van der Loo Approximate text matching with the stringdist package
  8. 8. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Dictionary lookup > match("leia", c("leela","leia")) [1] 2 > match("liea", c("leela","leia")) [1] NA > amatch("liea", c("leela","leia"), maxDist=1) [1] 2 > "liea" %in% c("leela","leia") [1] FALSE Mark van der Loo Approximate text matching with the stringdist package
  9. 9. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Dictionary lookup > match("leia", c("leela","leia")) [1] 2 > match("liea", c("leela","leia")) [1] NA > amatch("liea", c("leela","leia"), maxDist=1) [1] 2 > "liea" %in% c("leela","leia") [1] FALSE > ain("liea", c("leela","leia"), maxDist=1) [1] TRUE Mark van der Loo Approximate text matching with the stringdist package
  10. 10. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. String distance Mark van der Loo Approximate text matching with the stringdist package
  11. 11. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. String distances . Implemented in the package .. ...... edit-based distances q-gram based distances heuristic distances . Review papers .. ...... L. Boytsov (2011). ACM Journal of Experimental Algorithmics 16 1–86. G. Navarro (2001). ACM Computing Surveys 33 31–88. . stringdist paper .. ...... M.P.J. van der Loo (2014). The stringdist package for approximate string matching. The R Journal 6 xx-xx. Mark van der Loo Approximate text matching with the stringdist package
  12. 12. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Edit-based distances . Definition .. ...... Count the minimum number of (weighted) basic operations that turns string s into string t. Mark van der Loo Approximate text matching with the stringdist package
  13. 13. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Edit-based distances . Definition .. ...... Count the minimum number of (weighted) basic operations that turns string s into string t. Allowed operation Distance substitution deletion insertion transposition Hamming LCS Levenshtein OSA ∗ Damerau- Levenshtein ∗Substrings may be edited only once. Mark van der Loo Approximate text matching with the stringdist package
  14. 14. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Edit-based distances . Definition .. ...... Count the minimum number of (weighted) basic operations that turns string s into string t. Allowed operation Distance substitution deletion insertion transposition Hamming LCS Levenshtein OSA ∗ Damerau- Levenshtein ∗Substrings may be edited only once. stringdist(leia,liea,method=hamming) [1] 2 Mark van der Loo Approximate text matching with the stringdist package
  15. 15. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Edit-based distances . Definition .. ...... Count the minimum number of (weighted) basic operations that turns string s into string t. Allowed operation Distance substitution deletion insertion transposition Hamming LCS Levenshtein OSA ∗ Damerau- Levenshtein ∗Substrings may be edited only once. stringdist(leia,liea,method=hamming) [1] 2 stringdist(leia,liea,method=dl) [1] 1 Mark van der Loo Approximate text matching with the stringdist package
  16. 16. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. q-gram based distances . Definition .. ......Any (vector) distance between two q-gram profiles. banana Q: x : Mark van der Loo Approximate text matching with the stringdist package
  17. 17. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. q-gram based distances . Definition .. ......Any (vector) distance between two q-gram profiles. ba nana Q: ba x : 1 Mark van der Loo Approximate text matching with the stringdist package
  18. 18. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. q-gram based distances . Definition .. ......Any (vector) distance between two q-gram profiles. b an ana Q: ba an x : 1 1 Mark van der Loo Approximate text matching with the stringdist package
  19. 19. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. q-gram based distances . Definition .. ......Any (vector) distance between two q-gram profiles. ba na na Q: ba an na x : 1 1 1 Mark van der Loo Approximate text matching with the stringdist package
  20. 20. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. q-gram based distances . Definition .. ......Any (vector) distance between two q-gram profiles. ban an a Q: ba an na x : 1 2 1 Mark van der Loo Approximate text matching with the stringdist package
  21. 21. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. q-gram based distances . Definition .. ......Any (vector) distance between two q-gram profiles. bana na Q: ba an na x : 1 2 2 Mark van der Loo Approximate text matching with the stringdist package
  22. 22. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. q-gram based distances . Definition .. ......Any (vector) distance between two q-gram profiles. Jaccard |Q1 ∩ Q2| |Q1 ∪ Q2| stringdist(leia,leela + , method=jaccard,q=2) [1] 0.8333333 Cosine cos (x∠y) stringdist(leia,leela + , method=cosine,q=2) [1] 0.7113249 Mark van der Loo Approximate text matching with the stringdist package
  23. 23. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. q-gram based distances . Definition .. ......Any (vector) distance between two q-gram profiles. qgrams(x = leia,y = leela,q=2) le ei ia la el ee x 1 1 1 0 0 0 y 1 0 0 1 1 1 Mark van der Loo Approximate text matching with the stringdist package
  24. 24. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Heuristic distances: Jaro-Winkler . Definition .. ...... It’s complicated :-). Intended for human-typed name/address data stringdist(liea,leia,method=jw,p=0.1) [1] 0.075 Ranges from 0 (equal) to 1 (dissimilar). 0 ≤ p ≤ 0.25: emphasis on first 4 characters. p = 0: Jaro-distance Mark van der Loo Approximate text matching with the stringdist package
  25. 25. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Character encoding Image from https://code.google.com/p/tworsekey/ Mark van der Loo Approximate text matching with the stringdist package
  26. 26. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Character encoding stringdist(’¨o’,’o’) [1] 1 # Replace one symbol stringdist(’¨o’,’o’,useBytes=TRUE) [1] 2 # delete one byte, replace another (utf-8) Mark van der Loo Approximate text matching with the stringdist package
  27. 27. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Missing values Name : Value Six Missing Since : 30-06-2014 Last seen at : input.csv If you have seen Value Six or know someone who has, please contact your local statistician at +31 415 926 53 Mark van der Loo Approximate text matching with the stringdist package
  28. 28. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Handling missing values NA == NA Mark van der Loo Approximate text matching with the stringdist package
  29. 29. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Handling missing values NA == NA [1] NA Mark van der Loo Approximate text matching with the stringdist package
  30. 30. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Handling missing values NA == NA [1] NA adist(NA, NA) Mark van der Loo Approximate text matching with the stringdist package
  31. 31. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Handling missing values NA == NA [1] NA adist(NA, NA) [1] NA Mark van der Loo Approximate text matching with the stringdist package
  32. 32. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Handling missing values NA == NA [1] NA adist(NA, NA) [1] NA stringdist(NA, NA) Mark van der Loo Approximate text matching with the stringdist package
  33. 33. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Handling missing values NA == NA [1] NA adist(NA, NA) [1] NA stringdist(NA, NA) [1] NA Mark van der Loo Approximate text matching with the stringdist package
  34. 34. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Handling missing values NA == NA [1] NA adist(NA, NA) [1] NA stringdist(NA, NA) [1] NA match(NA, NA) Mark van der Loo Approximate text matching with the stringdist package
  35. 35. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Handling missing values NA == NA [1] NA adist(NA, NA) [1] NA stringdist(NA, NA) [1] NA match(NA, NA) [1] 1 # - note the useR’s OMGWTFBBQ right there Mark van der Loo Approximate text matching with the stringdist package
  36. 36. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Handling missing values NA == NA [1] NA adist(NA, NA) [1] NA stringdist(NA, NA) [1] NA match(NA, NA) [1] 1 # - note the useR’s OMGWTFBBQ right there amatch(NA, NA) Mark van der Loo Approximate text matching with the stringdist package
  37. 37. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Handling missing values NA == NA [1] NA adist(NA, NA) [1] NA stringdist(NA, NA) [1] NA match(NA, NA) [1] 1 # - note the useR’s OMGWTFBBQ right there amatch(NA, NA) [1] 1 # - ok, at least we’re consistent Mark van der Loo Approximate text matching with the stringdist package
  38. 38. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Handling missing values NA == NA [1] NA adist(NA, NA) [1] NA stringdist(NA, NA) [1] NA match(NA, NA) [1] 1 # - note the useR’s OMGWTFBBQ right there amatch(NA, NA) [1] 1 # - ok, at least we’re consistent amatch(NA, NA, matchNA=FALSE) Mark van der Loo Approximate text matching with the stringdist package
  39. 39. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Handling missing values NA == NA [1] NA adist(NA, NA) [1] NA stringdist(NA, NA) [1] NA match(NA, NA) [1] 1 # - note the useR’s OMGWTFBBQ right there amatch(NA, NA) [1] 1 # - ok, at least we’re consistent amatch(NA, NA, matchNA=FALSE) [1] NA Mark van der Loo Approximate text matching with the stringdist package
  40. 40. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Parallelization For a single call: stringdistmatrix(a,b,ncores=4) Or, define your own cluster: cl - makeCluster(4) stringdistmatrix(a, b, cluster=cl) stringdistmatrix(c, d, cluster=cl) stopCluster(cl) Mark van der Loo Approximate text matching with the stringdist package
  41. 41. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Performance stringdist(method=’lv’) About 30% faster than adist About 2 times faster then RecordLinkage When comparing strings of 5 - 25 characters Mark van der Loo Approximate text matching with the stringdist package
  42. 42. ..... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . .... . .... . ..... . .... . ..... . .... . .... . .. Summary Nine different string metrics; core in C99 (sorry Dirk :-) ) Approximate dictionary lookup Proper handling of encoding and missing values Fast Paralellization built in Thank you for your attention! t : @markpjvanderloo e : mark.vanderloo@gmail.com w : markvanderloo.eu Mark van der Loo Approximate text matching with the stringdist package

×