Объединить похожие строки Python - PullRequest
0 голосов
/ 17 сентября 2018

У меня две строки

string1 = "apple banna kiwi mango"
string2 = "aple banana mango lemon"

Я хочу, чтобы результат сложения этих двух строк (не конкатенация), т. Е. Результат должен выглядеть как

result = "apple banana kiwi mango lemon"

Мой текущий подходдовольно просто.

  1. Токенизация многострочной строки (вышеуказанные строки после токенизации), удаление любых шумов (специальные / символы новой строки / пустые строки)
  2. Следующим шагом является определениекосинусное сходство строк, если оно выше 0,9, тогда я добавляю одну из строк к окончательному результату

Теперь возникает проблема.Он не охватывает ту часть, где одна строка содержит одну половину слова, а другая - другую половину (или правильное слово в некоторых случаях) слова.Я также добавил эту функцию в мой скрипт.Но опять проблема остается.Любая помощь в том, как двигаться вперед с этим, приветствуется.

def text_to_vector(text):
     words = WORD.findall(text)
     return Counter(words)

def get_cosine(vec1, vec2):
     intersection = set(vec1.keys()) & set(vec2.keys())
     numerator = sum([vec1[x] * vec2[x] for x in intersection])

     sum1 = sum([vec1[x]**2 for x in vec1.keys()])
     sum2 = sum([vec2[x]**2 for x in vec2.keys()])
     denominator = math.sqrt(sum1) * math.sqrt(sum2)

     if not denominator:
        return 0.0
     else:
        return float(numerator) / denominator


def merge_string(string1, string2):
    i = 0
    while not string2.startswith(string1[i:]):
        i += 1

    sFinal = string1[:i] + string2
    return sFinal

for item in c:
for j in d:
    vec1 = text_to_vector(item)
    vec2 = text_to_vector(j)
    r = get_cosine(vec1, vec2)
    if r > 0.5:
        if r > 0.85:
            final.append(item)
            break
        else:
            sFinal = merge_string(item, j)
            #print("1.", len(sFinal), len(item), len(j))
            if len(sFinal) >= len(item) + len(j) -8:
                sFinal = merge_string(j, item)
                final.append(sFinal)
                #print("2.", len(sFinal), len(item), len(j))
                temp.append([item, j])
                break

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018

Сложно проверить, является ли слово действительным английским словом.

Для этого вам нужно иметь словарь, с которым нужно сверять слово, или использовать nltk.

     pip install nltk  

     from nltk.corpus import wordnet  

     set([w for w in (string1 + string2).split() if  wordnet.synsets(w)]) 

     Out[41]: {'apple', 'banana', 'kiwi', 'lemon', 'mango'}

Чтобы поймать цифры, если они есть, добавьте isdigit ().

st1 = 'Includes Og Added Sugars'

st2 = 'Includes 09 Added Sugars 09'


set([w for w in (st1 + st2).split() if  (wordnet.synsets(w) or w.isdigit())])

Out[30]: {'09', 'Added', 'Includes', 'Sugars'}

Чтобы поймать сокращения, такие как g, mg, добавьте re.match ().

set([w for w in (st1 + st2).split() if  (wordnet.synsets(w) or w.isdigit() or re.match(r'\d+g|mg',w))])

Out[40]: {'09', '0g', 'Added', 'Includes', 'Sugars'}
0 голосов
/ 17 сентября 2018

Вы когда-нибудь слышали о расстоянии Левенштейна? Я предлагаю следующий алгоритм:

  1. Разделить списки на элементы (string1.split (""))

  2. Цикл по list(string1). Внутри него переберите list(string2), и если расстояние Левенштейна для двух элементов, скажем, меньше 3, поместите элемент в массив результатов.

  3. Возврат result.

for i in list(string1): for k in list(string2): if levenshtein(i,k) < 3: res.append(i)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...