Нечеткое соответствие для небольшой разницы - PullRequest
1 голос
/ 15 октября 2019

У меня есть столбец названий компаний, и я хотел бы посчитать, сколько разных компаний в этом столбце. В этом столбце некоторые идентичные компании имеют небольшую разницу в названиях, например, эти компании должны учитываться только один раз.

ASAHI INTECC CO., LTD.
Asahi Intecc USA Inc
ASAHI INTECC USA, INC

Я хочу коды, которые могли бы работать в целом, которые могли бы точно подсчитывать числакомпаний без учета дубликатов с небольшой разницей. Например, эти воспроизводимые данные должны возвращать значение 6

company <- read.table(text = "
          CompanyName
          'MERCK SHARP & DOHME CORPORATION'
          'GILEAD SCIENCES INC'
          'BOEHRINGER INGELHEIM PHARMACEUTICALS, INC.'
          'ABBVIE, INC.'
          'JANSSEN SCIENTIFIC AFFAIRS, LLC'
          'BOEHRINGER INGELHEIM PHARMA GMBH & CO.KG'
          'ASAHI INTECC CO., LTD.'
          'Asahi Intecc USA Inc'
", header = TRUE, stringsAsFactors = FALSE)

Я смотрел на Как я могу сопоставить строки нечеткого совпадения из двух наборов данных? Но я до сих пор не знаю, какпостроить коды. Надеюсь на любой совет

1 Ответ

2 голосов
/ 15 октября 2019

Чтобы сравнить сходство между строками, первым шагом обычно является очистка данных с лучшими знаниями, которые у вас есть:

Поскольку многие методы для вычисления расстояния между строками обрабатывают буквы верхнего и нижнего регистра как разные буквы, поэтомусначала вы должны преобразовать все символы в один и тот же регистр. И вы можете выполнить любую другую очистку, чтобы повысить точность.

library(dplyr)
companyName <- company$CompanyName %>%
    toupper() %>% # convert to upper case
    stringr::str_replace_all("\\s+"," ") %>% # convert any consecutive whitespaces to single space
    stringr::str_remove_all("\\.|,") # remove all comma or dot
> companyName
[1] "MERCK SHARP & DOHME CORPORATION"          "GILEAD SCIENCES INC"                      "BOEHRINGER INGELHEIM PHARMACEUTICALS INC"
[4] "ABBVIE INC"                               "JANSSEN SCIENTIFIC AFFAIRS LLC"           "BOEHRINGER INGELHEIM PHARMA GMBH & COKG" 
[7] "ASAHI INTECC CO LTD"                      "ASAHI INTECC USA INC"    

Рассчитать расстояние между строками:

distanceMatrix <- stringdist::stringdistmatrix(
    a = companyName,
    b = companyName,
    # You can pick the method that works best for your data. Also, manual inspection is needed. See ?stringdist 
    # I'm picking soundex for this example
    method = "soundex"
)

Используя метод soundex, если ячейка 0, это означает, что соответствующая строка и столбец очень близки

> distanceMatrix
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,]    0    1    1    1    1    1    1    1
[2,]    1    0    1    1    1    1    1    1
[3,]    1    1    0    1    1    0    1    1
[4,]    1    1    1    0    1    1    1    1
[5,]    1    1    1    1    0    1    1    1
[6,]    1    1    0    1    1    0    1    1
[7,]    1    1    1    1    1    1    0    0
[8,]    1    1    1    1    1    1    0    0

Это означает, что в векторе companyName элемент 3 близок к элементу 6, а элемент 7 близок к элементу 8.

result <- which(distanceMatrix==0,arr.ind = TRUE) %>%
    as.data.frame() %>%
    dplyr::filter(col > row)
> result
  row col
1   3   6
2   7   8

> result %>% mutate_all(~companyName[.x])
                                       row                                     col
1 BOEHRINGER INGELHEIM PHARMACEUTICALS INC BOEHRINGER INGELHEIM PHARMA GMBH & COKG
2                      ASAHI INTECC CO LTD                    ASAHI INTECC USA INC

Обратите внимание, что вы можете повысить точность, очистив строку или выбрав другие методы, параметры или пороговое значение при расчете расстояния в строке. Но он никогда не сможет обеспечить 100% точность.

Наконец, для подсчета уникальных компаний мы можем сделать:

> length(companyName) - length(unique(result$row))
[1] 6
...