【问题标题】:Fuzzy matching for slight difference细微差别的模糊匹配
【发布时间】:2019-10-14 21:55:52
【问题描述】:

我有一列公司名称,我想计算该列中有多少不同的公司。在该列中,一些相同的公司名称略有不同,例如,这些公司应该只计算一次。

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)

我看了 How can I match fuzzy match strings from two datasets? 但我仍然不知道如何构建代码。希望大家给点建议

【问题讨论】:

    标签: r fuzzy-comparison


    【解决方案1】:

    要比较字符串之间的相似性,第一步通常是用你所掌握的知识来清理数据:

    由于许多计算字符串距离的方法会将大写和小写字母视为不同的字母,因此首先应将所有字符转换为相同的大小写。您可以进行任何其他清洁以帮助提高准确性。

    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
    

    【讨论】:

    • 非常感谢,我将尝试运行您的代码
    • 计算“独特”公司的数量,使用行数是错误的。它应该是唯一项目的数量。
    • 这里有一个问题,你是在比较每家公司的第一个字吗?由于我发现在我的数据集中,有“Eli Lilly Inc”和“Lilly USA. Corp”,您的代码无法识别这种特殊情况......
    • 我不是在比较第一个词。 soundex 比较单词发音的相似程度。为了更好地识别这些公司,您可以尝试不同的方法、调整参数并进行更多的数据清理。但是,仍然没有任何方法可以保证 100% 的准确度。
    猜你喜欢
    • 1970-01-01
    • 2011-04-26
    • 1970-01-01
    • 1970-01-01
    • 2020-12-13
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多