Компенсация "дисперсии" в опросе - PullRequest
2 голосов
/ 27 февраля 2011

Название для этого было довольно сложно.

Я пытаюсь решить сценарий, Представьте себе, что опрос был разослан XXXXX людям с вопросом, какой у них любимый футбольный клуб. Судя по ответу, очевидно, что, хотя многие являются фаворитами одного и того же клуба, все они «выражают» это по-разному. Например,

Для Манчестер Юнайтед некоторые варианты включают ...

  • Человек U
  • Манчестер Юнайтед.
  • Манчестер Юнайтед
  • Манчестер U
  • Манчестер Юнайтед

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

Теперь, если мы еще больше усложним сценарий, допустим, что из-за огромного количества различных клубов (например, Манчестер Сити, как М. Сити, Манчестер Сити и т. Д.), Снова страдающих от этой проблемы, невозможно вручную «введите» эти отклонения и используйте его для создания пользовательского фильтра, который конвертирует все Man U -> Manchester United, Man Utd. > Манчестер Юнайтед и т. Д. Но вместо этого мы хотим автоматизировать этот фильтр, чтобы найти наиболее вероятное совпадение и соответствующим образом преобразовать данные.

Я пытаюсь сделать это в Python (из файла .cvs), однако приветствую любые псевдо-ответы, которые описывают хороший подход к решению этой проблемы.

Редактировать: Дополнительная информация Это не работает с установленным списком клубов, идея состоит в том, чтобы «объединить» те, которые мы имеем вместе. Предположение, что нет орфографических ошибок. Там нет предполагаемой длины, сколько клубов И список опросов длинный. Достаточно долго, чтобы не делать это вручную (1000 запросов)

Ответы [ 3 ]

1 голос
/ 27 февраля 2011

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
0 голосов
/ 28 февраля 2011

Пожалуйста, отредактируйте свой вопрос с ответами на следующие вопросы:

Вы говорите: «Мы хотим автоматизировать этот фильтр, чтобы найти наиболее вероятное совпадение» - соответствует чему ??У вас есть список стандартных названий всех возможных футбольных клубов, или для создания такого списка необходимо сгруппировать множество вариантов каждого имени?

Сколько клубов?

Сколько ответов на опрос?

После очень легкой нормализации (замените . пробелом, уберите пробелы в начале / конце, замените пробелы одним пробелом, преобразуйте в нижний регистр [в таком порядке])и считая, сколько у вас уникальных ответов?

Кажется, вы концентрируетесь на сокращениях стандартного имени.Вам нужно справиться с прозвищами, например, Gunners -> Arsenal, Spurs -> Tottenham Hotspur?Сокращения (WBA -> West Bromwich Albion)?А как насчет орфографических ошибок, ошибок клавиатуры, SMS-диалекта, ...?В целом, какие исследования ваших данных вы провели и каковы были результаты?

Вы говорите "" "невозможно вручную" ввести "эти отклонения" "" - возможно / допустимо "ввести""некоторые" отклонения ", например, чтобы справиться с псевдонимами, как указано выше?

Каковы ваши критерии успеха в этом упражнении и как вы будете его измерять?

0 голосов
/ 27 февраля 2011

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

Если у вас былсписок всех фактических названий клубов, которые вы можете сравнить непосредственно с этим;а для строк, которые не соответствуют первым 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'])
...