Сопоставление похожих строк в MySQL / PHP

#php #mysql #string #string-matching

Вопрос:

Я работаю над системой, которая позволяет пользователям создавать списки СМИ. Я пытаюсь сопоставить имена и сгруппировать повторяющиеся элементы, но сохранить исходное имя пользователя. Моя проблема в том, как точно сопоставить похожие имена. Например, если у меня есть:

«Гарри Поттер и философский камень» «Философский камень — Гарри Поттер» «Гарри Поттер — философский камень»

Как я могу сопоставить эти 3 в базе данных MySQL? Есть ли какой-либо запрос, который я могу использовать для этого, или, возможно, другая технология, которую мне нужно будет включить для этого?

Комментарии:

1. Это интересный вопрос… Но только представьте, каковы будут результаты для: 1) «Гарри Поттер», 2) «Гарри философс стоун», 3) «Гарри Поттер и камень», 4) «Майкл Джексон и философс стоун», 5) «Поттер стоун и Гарри философс» — какой из этих вариантов соответствует «Гарри Поттер и философс стоун»?

2. Вы хотите выполнить это сравнение автоматически или вручную создать ссылки между различными вариантами именования?

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

4. Это называется «нечеткое сопоставление» и является большой темой в мире текстовой аналитики. Существует множество различных алгоритмов с различными уровнями сложности и различными преимуществами / недостатками. Некоторые более простые (например, расстояние Левенштейна) могут быть реализованы в mysql, но более сложные требуют соответствующего языка программирования. Большинство из этих алгоритмов реализованы на python или R, а не на php. Вам нужно изучить алгоритмы и выбрать тот, который лучше всего подходит для вашего бизнес-кейса.

Ответ №1:

Прежде всего, вам нужно определить, как понять, являются ли 2 строки «похожими». Какова мера «сходства»?

И пока вы думаете об этом, я могу вспомнить одну встроенную функцию в PHP: similar_text . Вот пример: нажмите.

Код:

 $str = [
    "Harry Potter and the philosophers stone",
    "The philosophers stone - Harry Potter",
    "Harry Potter - the philosophers stone"
];

for ($i = 0; $i < count($str); $i  ) {
    echo "[" . $i . "] " . $str[$i] . "n";
}
for ($i = 0; $i < count($str); $i  ) {
    for ($j = $i   1; $j < count($str); $j  ) {
        $value = similar_text($str[$i], $str[$j], $p);
        echo "[" . $i . "] VS [" . $j . "] = " . $value . " (" . $p . " %)n";
    }
}
 

Дает нам такой результат:

 [0] Harry Potter and the philosophers stone
[1] The philosophers stone - Harry Potter
[2] Harry Potter - the philosophers stone
[0] VS [1] = 21 (55.263157894737 %)
[0] VS [2] = 36 (94.736842105263 %)
[1] VS [2] = 21 (56.756756756757 %)
 

Вы можете видеть, что «Гарри Поттер и философский камень» и «Гарри Поттер — философский камень» на 94% похожи.

Я могу только рекомендовать вам прочитать это руководство по PHP: нажмите со всеми комментариями ниже.

P.S. В PHP есть еще 2 функции: levenshtein и soundex . Вы можете проверить их сами. Они также упомянуты на странице руководства.

Ответ №2:

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

Комментарии:

1. Не уверен, что понимаю. Это всего лишь примеры, и можно ввести еще много других, которые должны ссылаться на одно и то же. У меня нет проблем с их связыванием, в первую очередь нужно сопоставить их, чтобы создать ссылку.