首页 > 解决方案 > python天真的字符串令牌匹配器

问题描述

我写了一个非常幼稚的令牌字符串搜索匹配器。不过,这有点太天真了,就像下面的代码一样,由于“arizon a”是如何标记化的,它会带回艺术家列表中的所有艺术家。

import collections
import re

def __tokenised_match(artist, search_artist):
        matches = []
        if len(re.split(r'[\\\s/-]', search_artist)) > 1:
            a = [artist.sanitisedOne, search_artist]
            bag_of_words = [ collections.Counter(re.findall(r'\w+', words)) for words in a]
            sumbags = sum(bag_of_words, collections.Counter())
            print(sumbags)
            for key, value in sumbags.items():
                if len(re.findall(r'\b({k})\b'.format(k=key), search_artist)) > 0 and value > 1:
                    matches.append(artist)

        if len(matches):
            return matches


artists = [
{ 'artist': 'A R I Z O N A', 'sanitisedOne': 'a r i z o n a'},
{ 'artist': 'Wutang Clan', 'sanitisedOne': 'wutang clan'}
]

search_artist = 'a r i z o n a'

for artist in artists:
    print(__tokenised_match(artist, search_artist))

这将创建一个像这样的 sumbags:

计数器({'a': 4, 'r': 2, 'i': 2, 'z': 2, 'o': 2, 'n': 2})

Counter({'a': 2, 'wutang': 1, 'clan': 1, 'r': 1, 'i': 1, 'z': 1, 'o': 1, 'n': 1 })

这是一种边缘案例,但我想知道如何才能收紧这种边缘案例。'wutang clang' 可以匹配,但是像这样的单个字母时......有点多,并且会因为匹配两次而将每个艺术家都带回来。

标签: pythonstringstring-matching

解决方案


基本问题是您只在一次比赛中返回成功。对于名称中带有易于匹配的标记的任何艺术家,这将扼杀您的准确性。我们可以调整您的算法以匹配一定百分比的单词,或者进行字母袋、交叉联合比率,但是......

我建议你使用更强大的东西,比如字符串相似度,这在 Python 代码中很容易找到。已经打包,它比编写自己的解决方案更容易使用


推荐阅读