#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. Не уверен, что понимаю. Это всего лишь примеры, и можно ввести еще много других, которые должны ссылаться на одно и то же. У меня нет проблем с их связыванием, в первую очередь нужно сопоставить их, чтобы создать ссылку.