2

这个标题很棘手。

我正在尝试解决一个场景,假设向 XXXXX 人发送了一项调查,询问他们最喜欢的足球俱乐部是什么。从回复来看,很明显,虽然很多人是同一家具乐部的最爱,但他们都以不同的方式“表达”了这一点。例如,

对于曼联来说,一些变化包括......

  • 曼U
  • 曼联。
  • 曼联。
  • 曼彻斯特大学
  • 曼联

显然,所有人都是同一个俱乐部,但是,如果使用一种简单的技术,只是试图获得一个提取字符串匹配,每个都会是一个单独的结果。

现在,如果我们进一步使情况复杂化,假设由于不同俱乐部(例如曼城,如M. City,曼城等)的庞大数量,再次困扰着这个问题,不可能手动“进入”这些差异并使用它来创建自定义过滤器,以便转换所有 Man U -> Manchester United, Man Utd。> 曼联等。但相反,我们希望自动执行此过滤器,以寻找最可能的匹配并相应地转换数据。

我正在尝试在 Python 中执行此操作(来自 .cvs 文件),但是欢迎任何概述解决此问题的好方法的伪答案。

编辑:一些附加信息 这不是一套俱乐部列表,我们的想法是“聚集”我们一起拥有的俱乐部。假设没有拼写错误。没有假定多少俱乐部的长度并且调查列表很长。足够长,它不保证手动执行此操作(1000 次查询)

4

3 回答 3

1

Google Refine 就是这样做的,但我假设您想自己动手。

请注意,difflib 内置于 Python 中,并且具有许多功能(包括消除垃圾元素)。我会从那开始。

您可能不想以完全自动化的方式进行操作。我会做这样的事情:

# load corrections file, mapping user input -> output
# load survey
import difflib

possible_values = corrections.values()

for answer in survey:
    output = corrections.get(answer,None)
    if output = None:
        likely_outputs = difflib.get_close_matches(input,possible_values)
        output = get_user_to_select_output_or_add_new(likely_outputs)
        corrections[answer] = output
        possible_values.append(output)
save_corrections_as_csv
于 2011-02-27T16:08:00.173 回答
0

在我看来,您可以通过获取字符串,将其小写,删除所有标点符号,然后比较每个单词的开头来将其中许多转换为标准形式。

如果您有一份所有实际俱乐部名称的列表,您也可以直接与之进行比较;对于与任何实际团队的前 n 个字母不匹配的字符串,您可以尝试对任何实际匹配的返回字符串进行字典比较。

它并不完美,但它应该能让你达到 99% 的目标。

import string

def words(s):
    s = s.lower().strip(string.punctuation)
    return s.split()

def bestMatchingWord(word, matchWords):
    score,best = 0., ''
    for matchWord in matchWords:
        matchScore = sum(w==m for w,m in zip(word,matchWord)) / (len(word) + 0.01)
        if matchScore > score:
            score,best = matchScore,matchWord
    return score,best

def bestMatchingSentence(wordList, matchSentences):
    score,best = 0., []
    for matchSentence in matchSentences:
        total,words = 0., []
        for word in wordList:
            s,w = bestMatchingWord(word,matchSentence)
            total += s
            words.append(w)
        if total > score:
            score,best = total,words
    return score,best

def main():
    data = (
        "Man U",
        "Man. Utd.",
        "Manch Utd",
        "Manchester U",
        "Manchester Utd"
    )

    teamList = (
        ('arsenal',),
        ('aston', 'villa'),
        ('birmingham', 'city', 'bham'),
        ('blackburn', 'rovers', 'bburn'),
        ('blackpool', 'bpool'),
        ('bolton', 'wanderers'),
        ('chelsea',),
        ('everton',),
        ('fulham',),
        ('liverpool',),
        ('manchester', 'city', 'cty'),
        ('manchester', 'united', 'utd'),
        ('newcastle', 'united', 'utd'),
        ('stoke', 'city'),
        ('sunderland',),
        ('tottenham', 'hotspur'),
        ('west', 'bromwich', 'albion'),
        ('west', 'ham', 'united', 'utd'),
        ('wigan', 'athletic'),
        ('wolverhampton', 'wanderers')
    )

    for d in data:
        print "{0:20} {1}".format(d, bestMatchingSentence(words(d), teamList))

if __name__=="__main__":
    main()            

在样本数据上运行让你

Man U                (1.9867767507647776, ['manchester', 'united'])
Man. Utd.            (1.7448074166742613, ['manchester', 'utd'])
Manch Utd            (1.9946817328797555, ['manchester', 'utd'])
Manchester U         (1.989100008901989, ['manchester', 'united'])
Manchester Utd       (1.9956787398647866, ['manchester', 'utd'])
于 2011-02-27T16:05:38.727 回答
0

请使用以下答案编辑您的问题:

你说“我们想自动化这个过滤器,寻找最可能的匹配”——匹配什么?您是否有所有可能的足球俱乐部的标准名称列表,或者是否需要将每个名称的许多变体进行聚类以创建这样的列表?

几家具乐部?

多少调查回复?

在进行了非常轻量级的规范化(用.空格替换,去除前导/尾随空格,用单个空格替换空格,转换为小写 [按该顺序])并计数之后,您有多少独特的响应?

您的重点似乎是标准名称的缩写。您是否需要处理昵称,例如枪手 -> 阿森纳、马刺 -> 托特纳姆热刺?首字母缩略词(WBA -> 西布罗姆维奇)?拼写错误、键盘错误、短信方言……?总的来说,您对您的数据进行了哪些研究,结果如何?

你说“”“不可能手动“输入”这些差异“””——是否可以/允许“输入”一些“差异”,例如处理上面的昵称?

你在这个练习中成功的标准是什么,你将如何衡量它?

于 2011-02-27T22:33:02.620 回答