Сравнение схожести строк с большим количеством записей - PullRequest
2 голосов
/ 12 июля 2020

Данные представляют собой названия продуктов камеры и объективов.

У меня есть 55 000 записей в таблице продуктов, и я хочу сравнить их каждую с чистым набором основных записей 3500, поэтому я знаю, что они представляют для предоставления дополнительной информации .

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

Вот пример данных, с которыми я работаю, эти 5 записей

Canon 45MM 2.8 TSE    
Canon 45mm F2.8 TS-E
Canon 45mm F/2.8L Tilt-Shift - Boxed
Canon EF TS-E 45mm f/2.8 Tilt-shift Black Lens
Canon TS-e 45mm f2.8 Lens - Unboxed

все должно соответствовать основной записи

Canon TS-E 45mm f/2.8

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

Затем я попробовал эта функция расстояния Левенштейна https://lucidar.me/en/web-dev/levenshtein-distance-in-mysql/

Каждое сравнение (1 запись против 3500 основных записей) может занять 30-60 секунд, результаты лучше. Некоторые примеры.

Canon 85 мм 1.2 MK II L - номер 7

    M_PRODUCTNAME   SCORE
1   Canon EOS 5D Mark II    14
2   Canon EOS 6D Mark II    14
3   Canon EOS-1D Mark II N  14
4   Canon EF 85mm F1.2  14
5   Canon EF 50mm F1.8 II   14
6   Canon EOS 7D Mark II    14
7   Canon EF 85mm F1.2L II USM  14
8   Canon EOS 5D Mark III   14
9   Canon EOS-1D Mark II    14
10  Canon EOS M6 Mark II    14

Объектив Canon EF 80-200 мм f4-5.6 II - номер 1 (фактическая ошибка в записи должна быть f4,5, а не f4!)

    M_PRODUCTNAME   SCORE
1   Canon EF 80-200mm f/4.5-5.6 II  12
2   Canon EF 70-300mm f/4-5.6L IS USM   13
3   Canon EF 70-300mm f/4-5.6 IS USM    13
4   Canon EF 70-200mm F4L IS II USM 14
5   Canon EF 55-200mm f/4.5-5.6 II USM  14
6   Canon EF 70-300 F4-5.6 IS II USM    15
7   Canon EF 70-200mm f/2.8L USM    15
8   Canon EF 70-200mm F4L IS USM    15
9   Canon EF 70-200mm f/2.8L IS USM 15
10  Canon EF 70-200mm F4L USM   15

Canon fit zenitar c объектив 16 мм f2,8 - нет совпадения

    M_PRODUCTNAME   SCORE
1   7artisans 12mm F2.8 22
2   Canon TS-E 45mm f/2.8   22
3   Canon TS-E 90mm f/2.8   22
4   7artisans 25mm F1.8 23
5   Canon TS-E 17mm f/4L    23
6   Canon EF 28mm f/2.8 23
7   Canon Extender EF 1.4x III  23
8   Canon Extender EF 1.4x II   23
9   Canon EF 24mm f/2.8 23
10  Canon EF 35mm F2.0  23

CANON EOS IX APS Film с автофокусировкой и ручным управлением SLR EF / EFS Mount Camera Body - TESTED - не совпадает

    M_PRODUCTNAME   SCORE
1   Minolta Maxxum 7 35mm SLR Camera (Body Only)    60
2   Canon EOS 400D (EOS Digital Rebel XTi / EOS Kiss Digital X) 61
3   Canon EOS 300D (EOS Digital Rebel / EOS Kiss Digital)   61
4   Canon EOS 350D (EOS Digital Rebel XT / EOS Kiss Digital N)  61
5   Holga 120FN Medium Format Plastic Camera with Flash 62
6   Canon EOS 1100D (EOS Rebel T3 / EOS Kiss X50)   62
7   Canon EOS 1200D (EOS Rebel T5 / EOS Kiss X70)   62
8   Canon EF-S 35mm F2.8 Macro IS STM   62
9   Canon EF-M 28mm F3.5 Macro IS STM   62
10  Canon EF-S 60mm f/2.8 Macro USM 62

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

например, запрос, который занял 35 секунд.

SELECT m_productname, levenshtein(m_productname, 'Tamron SP 45mm f/1.8 Di VC USD, Canon EF Fit') AS score FROM m_product ORDER by score

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

Либо мне нужен Левенштейн, чтобы дать мне лучший результат и работать намного быстрее, либо мне нужен альтернативный подход, какие-либо идеи?

Мне нужно уметь запускать q Вначале используется 55000 раз, а затем около 3000 раз каждый день для новых записей. Так что 30 секунд на запрос не годятся.

Я использую ColdFusion, если это открывает другие возможности.

Ответы [ 2 ]

3 голосов
/ 12 июля 2020

Кажется, ваши данные содержат много информации, которую можно разбить на более сжатые столбцы. Прежде чем я начал больше работать над подходом Левенштейна, я тратил время на написание сценариев преобразования, которые анализировали бы эти данные в дополнительных столбцах той же таблицы. Другими словами, вместо такой таблицы:

M_PRODUCTNAME
Canon EF 70-200mm f/2.8L USM

у меня была бы такая таблица:

M_PRODUCTNAME                   BRAND   APERTURE  FSTOP
Canon EF 70-200mm f/2.8L USM    Canon   70-200    2.8L

Как бы вы разбили эти данные? Лично я бы взял каждое полное название продукта и разделил его пробелами в массив. Затем я смотрел на каждый элемент в массиве, чтобы применить логику преобразования c. Содержит ли товар какие-либо из ваших известных брендов? Затем добавьте этот бренд в столбец БРЕНД. Строка заканчивается на «мм»? Затем я бы добавил этот элемент в столбец APERTURE. Пункт начинается с "f /" или "F /"? Затем я бы добавил этот элемент в столбец FSTOP.

Этот подход не позволит уловить КАЖДУЮ причуду в ваших данных M_PRODUCTNAME. Но вы, вероятно, можете настроить его, чтобы извлечь большой объем значимых метаданных. И как только данные извлекаются в дополнительные столбцы, поиск этих элементов становится намного быстрее и проще. искать по целевой строке.

2 голосов
/ 12 июля 2020

Мое самое простое предложение - разобрать имя создателя в обеих таблицах и использовать его, чтобы ограничить пространство сравнения для расстояния Левенштейна. Код будет выглядеть примерно так:

select p.*, m.*, levenshtein(m.name, p.name)
from product p join
     master m
     on p.maker = m.maker;

Это может использовать индекс (maker) в двух таблицах.

Вы также можете различать guish между камерами и объективами. Если да, включите это как другой столбец описания.

Если есть другие атрибуты, которые вы можете отфильтровать, они также могут помочь. Другими словами, вы не хотите сравнивать 50 000 записей в одной таблице с 3 500 в другой. Если вместо этого вы сравниваете каждую из 50000 записей, скажем, с 300, тогда ваш код будет намного, намного быстрее.

...