Mempertimbangkan:

string = 'pizza'
matchings = ['pizzas', 'potato chips', 'cheesy lime', 'pretzels', 'pork']

Saya mencoba menemukan cara yang baik untuk menemukan kecocokan terbaik dalam daftar. yang saya hitung dengan:

matchings_indices = {matching:sum([s == m for s,sdx in enumerate(string)\
                                 for m, mdx in enumerate(matching) if sdx<=mdx])/len(string) 
                     for matching in matchings}
matchings_indices

Yang mengakibatkan:

{'pizzas': 1.0,
 'potato chips': 0.6,
 'cheesy lime': 0.2,
 'pretzels': 0.6,
 'pork': 0.4}

Sederhana tapi cukup bagus! Saya dapat memetik nilai maksimum dan itu akan menjadi kecocokan (saya hanya membutuhkan satu nilai yang cocok, skor yang dihitung untuk kejelasan). Tapi itu benar-benar sulit ketika string yang sangat mirip muncul dalam daftar:

string = 'pizza'
matchings = ['pizzas', 'pizza fries', 'cheesy lime', 'pizzo', 'pizza']

Sekarang output saya menjadi:

{'pizzas': 1.0,
 'pizza fries': 1.0,
 'cheesy lime': 0.2,
 'pizzo': 1.0,
 'pizza': 1.0}

Tentu saja di sini pizza harus memiliki indeks maksimum. Saya mencoba mengurutkannya juga seperti:

matchings_indices = {matching:sum([s == m for s,sdx in enumerate(sorted(string))\
                                 for moose in matching.split() 
                                 for m, mdx in enumerate(sorted(moose)) if sdx==mdx])/len(string) 
                     for matching in matchings}

Tetapi dalam hal ini adalah output untuk kasus pertama: (Masih cukup baik untuk string yang sangat berbeda)

{'pizzas': 0.8,
 'potato chips': 0.0,
 'cheesy lime': 0.0,
 'pretzels': 0.0,
 'pork': 0.2}

Dan di sini untuk yang kedua:

{'pizzas': 0.8,
 'pizza fries': 1.0,
 'cheesy lime': 0.2,
 'pizzo': 0.6,
 'pizza': 1.0}

Mana yang lebih baik tapi tetap saja. pizzas adalah kecocokan yang lebih baik daripada pizza fries dan harus diberi skor lebih tinggi.

Jadi, bantuan apa pun untuk memperbaiki situasi akan sangat bagus!

0
Hamza 20 November 2020, 18:24

1 menjawab

Jawaban Terbaik

Anda bisa melihat menggunakan edit distance/levenshtein distance. Dari laman Wikipedia:

jarak Levenshtein adalah metrik string untuk mengukur perbedaan antara dua urutan. Secara informal, jarak Levenshtein antara dua kata adalah jumlah minimum pengeditan satu karakter (penyisipan, penghapusan, atau penggantian) yang diperlukan untuk mengubah satu kata menjadi kata lainnya.

Saya menemukan jawaban ini yang menghitung jarak, lalu Anda dapat mengurangi jarak ini dari 1 untuk membuat skor maksimum Anda menjadi yang terbaik:

# from https://stackoverflow.com/a/32558749/6386471
def levenshteinDistance(s1, s2):
    if len(s1) > len(s2):
        s1, s2 = s2, s1

    distances = range(len(s1) + 1)
    for i2, c2 in enumerate(s2):
        distances_ = [i2+1]
        for i1, c1 in enumerate(s1):
            if c1 == c2:
                distances_.append(distances[i1])
            else:
                distances_.append(1 + min((distances[i1], distances[i1 + 1], distances_[-1])))
        distances = distances_
    return distances[-1]

string = 'pizza'
matchings = ['pizzas', 'pizza fries', 'cheesy lime', 'pizzo', 'pizza']

scores = {}

for m in matchings:
    scores[m] = 1 - levenshteinDistance(string,m)

scores

>>> {'pizzas': 0, 'pizza fries': -5, 'cheesy lime': -10, 'pizzo': 0, 'pizza': 1}

import operator
max(scores.items(), key=operator.itemgetter(1))[0]

>>> 'pizza'
1
user6386471 20 November 2020, 16:05