Один из вариантов поиска похожих статей в базе данных основан на схождении слов в двух текстах.
Данный алгоритм не обладает точным результатом, но позволяет выявить явные дубли.
Для поиска понадобится функция, которая очистит текст от html-кода, лишних слов и вернёт массив слов.
function get_minification_array($text)
{
// Удаление экранированных спецсимволов
$text = stripslashes($text);
// Преобразование мнемоник
$text = html_entity_decode($text);
$text = htmlspecialchars_decode($text, ENT_QUOTES);
// Удаление html тегов
$text = strip_tags($text);
// Все в нижний регистр
$text = mb_strtolower($text);
// Удаление лишних символов
$text = str_ireplace('ё', 'е', $text);
$text = mb_eregi_replace("[^a-zа-яй0-9 ]", ' ', $text);
// Удаление двойных пробелов
$text = mb_ereg_replace('[ ]+', ' ', $text);
// Преобразование текста в массив
$words = explode(' ', $text);
// Удаление дубликатов
$words = array_unique($words);
// Удаление предлогов и союзов
$array = array(
'без', 'близ', 'в', 'во', 'вместо', 'вне', 'для', 'до',
'за', 'и', 'из', 'изо', 'из', 'за', 'под', 'к',
'ко', 'кроме', 'между', 'на', 'над', 'о', 'об', 'обо',
'от', 'ото', 'перед', 'передо', 'пред', 'предо', 'по', 'под',
'подо', 'при', 'про', 'ради', 'с', 'со', 'сквозь', 'среди',
'у', 'через', 'но', 'или', 'по'
);
$words = array_diff($words, $array);
// Удаление пустых значений в массиве
$words = array_diff($words, array(''));
return $words;
}
PHP
Пример работы функции:
$array = get_minification_array('
<p>Сегодня существует огромное множество разнообразных диет,
отличающихся степенью строгости и результатами, которых с их
помощью добиваются худеющие. Существует одна эффективная диета
творог + яблоки, которая позволит легко скинуть 4 кг за 4 дня.</p>
');
print_r($array);
PHP
Результат:
Array
(
[0] => сегодня
[1] => существует
[2] => огромное
[3] => множество
[4] => разнообразных
[5] => диет
[6] => отличающихся
[7] => степенью
[8] => строгости
[10] => результатами
[11] => которых
[13] => их
[14] => помощью
[15] => добиваются
[16] => худеющие
[18] => одна
[19] => эффективная
[20] => диета
[21] => творог
[22] => яблоки
[23] => которая
[24] => позволит
[25] => легко
[26] => скинуть
[27] => 4
[28] => кг
[31] => дня
)
Для более точного результата можно удалить из текста все стоп-слова.
Теперь, нужно получить проверяемую статью и сверить с остальными. В примере используется таблица `articles`, с полями `id`, `name`, `text`:
Пример таблицы со статьями
Поиск будет осуществляется для статьи `id` = 1, причём для теста в базе есть копия этой статьи с немного измененным текстом.
// Подключение к БД
$dbh = new PDO('mysql:dbname=db_name;host=localhost', 'логин', 'пароль');
// Получаем статью
$sth = $dbh->prepare("SELECT * FROM `articles` WHERE `id` = 1");
$sth->execute(array());
$article = $sth->fetch(PDO::FETCH_ASSOC);
// Получаем для неё массив слов
$text = get_minification_array($article['name'] . ' ' . $article['text']);
$count = count($text);
$out = array();
// Проход по всем статьям в таблице
$sth = $dbh->prepare("SELECT * FROM `articles`");
$sth->execute();
$list = $sth->fetchAll(PDO::FETCH_ASSOC);
foreach($list as $row) {
$verifiable = get_minification_array($row['name'] . ' ' . $row['text']);
$similar_counter = 0;
foreach ($text as $text_row) {
foreach ($verifiable as $verifiable_row){
if($text_row == $verifiable_row) {
$similar_counter++;
break;
}
}
}
$out[$row['name']] = $similar_counter * 100 / $count;
}
// Сортировка результатов и ограничение до 15шт
arsort($out);
$out = array_slice($out, 0, 15, true);
print_r($out);
PHP
Результат поиска:
Array
(
[Диета на яблоках и твороге] => 100
[Диета на яблоках и твороге (test)] => 97,368421052632
[Диета Ларисы Гузеевой] => 21,052631578947
[Как похудеть в лице] => 19,736842105263
[Соевый соус: польза и вред] => 17,105263157895
[Сырная диета] => 14,473684210526
[Какую обувь выбрать для сильных морозов?] => 13,157894736842
[Какие мышцы работают на эллиптическом тренажере?] => 10,526315789474
[Боль в коленном суставе при нагрузке] => 9,2105263157895
[Польза и вред дыни для организма человека] => 9,2105263157895
[Разгрузочная диета после праздников] => 9,2105263157895
[Вредно ли загорать на солнце?] => 7,8947368421053
[Йогуртовая диета] => 7,8947368421053
[Как стирать пуховое одеяло?] => 7,8947368421053
[Какие витамины в укропе] => 6,5789473684211
)
В результате видно, что статья схожа сама с собой на 100%, с тестовой статьей на 97%, с остальными не более 21%.
Данный алгоритм не обладает точным результатом, но позволяет выявить явные дубли.
Для поиска понадобится функция, которая очистит текст от html-кода, лишних слов и вернёт массив слов.
function get_minification_array($text)
{
// Удаление экранированных спецсимволов
$text = stripslashes($text);
// Преобразование мнемоник
$text = html_entity_decode($text);
$text = htmlspecialchars_decode($text, ENT_QUOTES);
// Удаление html тегов
$text = strip_tags($text);
// Все в нижний регистр
$text = mb_strtolower($text);
// Удаление лишних символов
$text = str_ireplace('ё', 'е', $text);
$text = mb_eregi_replace("[^a-zа-яй0-9 ]", ' ', $text);
// Удаление двойных пробелов
$text = mb_ereg_replace('[ ]+', ' ', $text);
// Преобразование текста в массив
$words = explode(' ', $text);
// Удаление дубликатов
$words = array_unique($words);
// Удаление предлогов и союзов
$array = array(
'без', 'близ', 'в', 'во', 'вместо', 'вне', 'для', 'до',
'за', 'и', 'из', 'изо', 'из', 'за', 'под', 'к',
'ко', 'кроме', 'между', 'на', 'над', 'о', 'об', 'обо',
'от', 'ото', 'перед', 'передо', 'пред', 'предо', 'по', 'под',
'подо', 'при', 'про', 'ради', 'с', 'со', 'сквозь', 'среди',
'у', 'через', 'но', 'или', 'по'
);
$words = array_diff($words, $array);
// Удаление пустых значений в массиве
$words = array_diff($words, array(''));
return $words;
}
PHP
Пример работы функции:
$array = get_minification_array('
<p>Сегодня существует огромное множество разнообразных диет,
отличающихся степенью строгости и результатами, которых с их
помощью добиваются худеющие. Существует одна эффективная диета
творог + яблоки, которая позволит легко скинуть 4 кг за 4 дня.</p>
');
print_r($array);
PHP
Результат:
Array
(
[0] => сегодня
[1] => существует
[2] => огромное
[3] => множество
[4] => разнообразных
[5] => диет
[6] => отличающихся
[7] => степенью
[8] => строгости
[10] => результатами
[11] => которых
[13] => их
[14] => помощью
[15] => добиваются
[16] => худеющие
[18] => одна
[19] => эффективная
[20] => диета
[21] => творог
[22] => яблоки
[23] => которая
[24] => позволит
[25] => легко
[26] => скинуть
[27] => 4
[28] => кг
[31] => дня
)
Для более точного результата можно удалить из текста все стоп-слова.
Теперь, нужно получить проверяемую статью и сверить с остальными. В примере используется таблица `articles`, с полями `id`, `name`, `text`:
Пример таблицы со статьями
Поиск будет осуществляется для статьи `id` = 1, причём для теста в базе есть копия этой статьи с немного измененным текстом.
// Подключение к БД
$dbh = new PDO('mysql:dbname=db_name;host=localhost', 'логин', 'пароль');
// Получаем статью
$sth = $dbh->prepare("SELECT * FROM `articles` WHERE `id` = 1");
$sth->execute(array());
$article = $sth->fetch(PDO::FETCH_ASSOC);
// Получаем для неё массив слов
$text = get_minification_array($article['name'] . ' ' . $article['text']);
$count = count($text);
$out = array();
// Проход по всем статьям в таблице
$sth = $dbh->prepare("SELECT * FROM `articles`");
$sth->execute();
$list = $sth->fetchAll(PDO::FETCH_ASSOC);
foreach($list as $row) {
$verifiable = get_minification_array($row['name'] . ' ' . $row['text']);
$similar_counter = 0;
foreach ($text as $text_row) {
foreach ($verifiable as $verifiable_row){
if($text_row == $verifiable_row) {
$similar_counter++;
break;
}
}
}
$out[$row['name']] = $similar_counter * 100 / $count;
}
// Сортировка результатов и ограничение до 15шт
arsort($out);
$out = array_slice($out, 0, 15, true);
print_r($out);
PHP
Результат поиска:
Array
(
[Диета на яблоках и твороге] => 100
[Диета на яблоках и твороге (test)] => 97,368421052632
[Диета Ларисы Гузеевой] => 21,052631578947
[Как похудеть в лице] => 19,736842105263
[Соевый соус: польза и вред] => 17,105263157895
[Сырная диета] => 14,473684210526
[Какую обувь выбрать для сильных морозов?] => 13,157894736842
[Какие мышцы работают на эллиптическом тренажере?] => 10,526315789474
[Боль в коленном суставе при нагрузке] => 9,2105263157895
[Польза и вред дыни для организма человека] => 9,2105263157895
[Разгрузочная диета после праздников] => 9,2105263157895
[Вредно ли загорать на солнце?] => 7,8947368421053
[Йогуртовая диета] => 7,8947368421053
[Как стирать пуховое одеяло?] => 7,8947368421053
[Какие витамины в укропе] => 6,5789473684211
)
В результате видно, что статья схожа сама с собой на 100%, с тестовой статьей на 97%, с остальными не более 21%.
Источник:
Перейти