У меня есть следующие данные, которые я хочу сопоставить, и после прохождения нескольких техник наиболее подходящим оказался метод расстояния Левенштейна - согласны ли вы с этим подходом на основе данных ниже или порекомендуете какой-либо другой метод, который иметь возможность лучше сопоставить следующее в больших объемах?
Пример данных можно увидеть ниже:
**Column1** **Column2**
Modra Digest (DC) Oldstewart2
South West Local /Sunday Times (new) Oldstewart
OldStewart political print Saigon Last month Saigon Last month
Oldstewart2 Local print (Former) Modra Digest Velehrad Digest (DC) (used via Bembek)
Saigon Last month South West Local South West Local /Sunday Times
ввод данных
Если я решу на go заранее использовать метод расстояния Левенштейна (определяемый как функция в VBA под названием Левенштейн, где результаты преобразуются в результаты в проценты), я хотел бы немного настроить применение этой функции и запустить его. как макрос. Столбцы, которые я сопоставляю (A и B), имеют разное количество входов, которые различаются по структуре (т.е. даже при сортировке по алфавиту совпадающие элементы не будут рядом друг с другом. Можно ли сделать следующее?
- Временно удалите все в скобках и его содержимое из обеих сравниваемых строк и ОБРЕЗЬТЕ строки, чтобы удалить пустое пространство до и после оставшейся строки.
- Удалите все повторяющиеся слова из каждой строки.
- Найдите совпадение Левенштейна из (A и B) на основе наивысшего процента сходства (в соответствии с заданной функцией) и расположите соответственно в столбцах A и B, чтобы «наиболее подходящие элементы» были размещены рядом с друг друга.
- Показать исходную форму (т.е. включая скобки, дубликаты слов) в структуре, описанной в пункте 3, однако без необходимости повторного вычисления (т.е. процент совпадения должен быть сохранен из TRIMmed, дедупликации и форму без скобок, как указано в пункте 1 и 2)
- Список записей записей должен быть отсортирован от наиболее подходящих к наименее подходящим.
Наконец (здесь я считаю выбранный подход немного сомнительным), поскольку приведенное выше упомянутый метод подсчитывает количество изменений, которые необходимо сделать для соответствия строкам, что было бы наилучшим способом (возможно, еще один уровень проверки) для работы с такими примерами, как «oldsteward» против «Oldstewart2 Local print (бывший)», так как это потребует удаления текста, который считается изменением (что снижает сходство) и, следовательно, будет иметь низкое сходство согласно методу Левенштейна?
Что касается использования метода Левенштейна, результат будет выглядеть примерно так:
****Column1** **Column2** **Match(%)**
Modra Digest (DC) Modra Digest Velehrad Digest (DC) (used via Bembek) 63
South West Local /Sunday Times (new) South West Local South West Local /Sunday Times 64
OldStewart political print Oldstewart 38
Oldstewart2 Local print (Former) Oldstewart2 48
Saigon Last month Saigon Last month Saigon Last month 94
Вывод данных
Функция:
Function Levenshtein3(ByVal string1 As String, ByVal string2 As String) As Long
Dim i As Long, j As Long, string1_length As Long, string2_length As Long
Dim distance(0 To 90, 0 To 80) As Long, smStr1(1 To 90) As Long, smStr2(1 To 800) As Long
Dim min1 As Long, min2 As Long, min3 As Long, minmin As Long, MaxL As Long
string1_length = Len(string1): string2_length = Len(string2)
distance(0, 0) = 0
For i = 1 To string1_length: distance(i, 0) = i: smStr1(i) = Asc(LCase(Mid$(string1, i, 1))): Next
For j = 1 To string2_length: distance(0, j) = j: smStr2(j) = Asc(LCase(Mid$(string2, j, 1))): Next
For i = 1 To string1_length
For j = 1 To string2_length
If smStr1(i) = smStr2(j) Then
distance(i, j) = distance(i - 1, j - 1)
Else
min1 = distance(i - 1, j) + 1
min2 = distance(i, j - 1) + 1
min3 = distance(i - 1, j - 1) + 1
If min2 < min1 Then
If min2 < min3 Then minmin = min2 Else minmin = min3
Else
If min1 < min3 Then minmin = min1 Else minmin = min3
End If
distance(i, j) = minmin
End If
Next
Next
' Levenshtein3 will properly return a percent match (100%=exact) based on similarities and Lengths etc...
MaxL = string1_length: If string2_length > MaxL Then MaxL = string2_length
Levenshtein3 = 100 - CLng((distance(string1_length, string2_length) * 100) / MaxL)
End Function
- Расстояние Левенштейна представляет собой строку метри c для измерения разница между двумя последовательностями. Неформально расстояние Левенштейна между двумя словами - это минимальное количество односимвольных правок (т.е. вставок, удалений или замен), необходимых для замены одного слова на другое.
Большое спасибо за вашу помощь.
Джей