【问题标题】:How to map the most "similar" strings from one list to another in python?如何在python中将最“相似”的字符串从一个列表映射到另一个列表?
【发布时间】:2012-01-15 23:54:43
【问题描述】:

给定两个包含字符串的列表。

  1. 一个包含世界各地的组织(主要是大学)的名称 - 不仅用英文书写,而且始终使用拉丁字母。

  2. 另一个列表包含大部分完整地址,其中可能出现第一个列表中的字符串(组织)。

一个例子:

addresses = [
             "Department of Computer Science, Katholieke Universiteit Leuven, Leuven, Belgium",
             "Machine Learning and Computational Biology Research Group, Max Planck Institutes     Tübingen, Tübingen, Germany 72076",
             "Department of Computer Science and Engineering, University of Washington, Seattle, USA 98185",
             "Knowledge Discovery Department, Fraunhofer IAIS, Sankt Augustin, Germany 53754",    
             "Computer Science Department, University of California, Santa Barbara, USA 93106",
             "Fraunhofer IAIS, Sankt Augustin, Germany",
             "Department of Computer Science, Cornell University, Ithaca, NY",
             "University of Wisconsin-Madison"
            ]

organisations = [
                 "Catholic University of Leuven"
                 "Fraunhofer IAIS"
                 "Cornell University of Ithaca"
                 "Tübingener Max Plank Institut"
                ]

如您所见,所需的映射是:

"Department of Computer Science, Katholieke Universiteit Leuven, Leuven, Belgium",
--> Catholic University of  Leuven
"Machine Learning and Computational Biology Research Group, Max Planck Institutes     Tübingen, Tübingen, Germany 72076",
--> Max Plank Institut Tübingen
"Department of Computer Science and Engineering, University of Washington, Seattle, USA 98185",
--> --
"Knowledge Discovery Department, Fraunhofer IAIS, Sankt Augustin, Germany 53754",
--> Fraunhofer IAIS 
"Computer Science Department, University of California, Santa Barbara, USA 93106",
"Fraunhofer IAIS, Sankt Augustin, Germany",
--> Fraunhofer IAIS
"Department of Computer Science, Cornell University, Ithaca, NY"
--> "Cornell University of Ithaca",
"University of Wisconsin-Madison",
--> --

我的想法是使用某种“距离算法”来计算字符串的相似度。因为我不能仅仅通过if address in organisation 在地址中查找组织,因为它在不同地方的写法可能略有不同。所以我的第一个猜测是使用 difflib 模块。特别是difflib.get_close_matches() 函数,用于为每个地址从组织列表中选择最接近的字符串。但我不太有信心,结果是否足够准确。虽然我不知道我应该将哪些接缝的比率设置为相似性度量。

在花太多时间尝试 difflib 模块之前,我想问问这里更有经验的人,这是否是正确的方法,或者是否有更适合的工具/方法来解决我的问题。谢谢!

PS:我不需要最优解。

【问题讨论】:

  • @Rodin:link you posted 表示 Levenstein 距离根据将一个字符串转换为另一个字符串所需的“操作”数量来衡量距离。这些操作包括插入、删除和替换。 我的组织列表有大约 8000 个条目,我的地址列表有 230000 个条目。如果组织字符串很短(例如 Fraunhofer IAIS)并且地址很长(例如:Knowledge Discovery Department, Fraunhofer IAIS, Sankt Augustin, Germany 53754)?
  • 我认为你的假设是正确的。想到 Levenshtein 距离,这是:en.wikipedia.org/wiki/Bitap_algorithm.
  • @Aufwind:您应该在比较之前将字符串拆分为单词,然后计算匹配单词的数量。例如,对于“Fraunhofer IAIS”,在每个地址中搜索“Fraunhofer”和“IAIS”的相似词。您还应该规范所有单词的大小写(例如,小写),并且可能希望忽略“干扰词”,如“of”。给出“完全匹配 = 5,接近匹配 = 1”之类的分数,并取得分最高的地址。也许一个好的启发式方法是给长匹配更高的分数。
  • 哦,这是与您的问题密切相关的非常有趣的阅读:“如何编写拼写校正器”norvig.com/spell-correct.html

标签: python string-matching


【解决方案1】:

使用以下作为字符串距离函数(而不是普通的 levenshtein 距离):

def strdist(s1, s2):
    words1 = set(w for w in s1.split() if len(w) > 3)
    words2 = set(w for w in s2.split() if len(w) > 3)

    scores = [min(levenshtein(w1, w2) for w2 in words2) for w1 in words1]
    n_shared_words = len([s for s in scores if s <= 3])
    return -n_shared_words 

然后使用 Munkres 分配算法shown here,因为组织和地址之间似乎存在 1:1 映射。

【讨论】:

    【解决方案2】:

    您可以使用 soundex 或 metaphone 将句子翻译成音素列表,然后比较最相似的列表。

    这是double-metaphone algo 的 Python 实现。

    【讨论】:

      猜你喜欢
      • 2011-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多