Представьте себе следующую задачу:Лучший алгоритм кластеризации? (Просто объяснил)
- У вас есть база данных, содержащая около 20 000 текстов в таблице под названием «статьи»
- Вы хотите подключить соответствующие те, используя алгоритм кластеризации для того, чтобы отобразить соответствующие статьи вместе
- алгоритм должен сделать плоскую кластеризацию (не иерархическую)
- Соответствующие статьи должны быть вставлены в таблицу «связанную»
- алгоритм кластеризации должен решить, следует ли два или мор е статьи связаны или не на основе текстов
- Я хочу, чтобы закодировать в PHP, но примеры с псевдокод или других языков программирования хорошо, слишком
Я закодированных первый проект с проверкой функции (), который дает «true», если две входные статьи связаны и «ложные», если нет. Остальная часть кода (выбор статей из базы данных, выбор статей для сравнения с вставкой соответствующих) также завершен. Может быть, вы тоже можете улучшить остальные. Но главное, что важно для меня, это функция check(). Поэтому было бы здорово, если бы вы могли опубликовать некоторые улучшения или совершенно разные подходы.
ПОДХОД 1
<?php
$zeit = time();
function check($str1, $str2){
$minprozent = 60;
similar_text($str1, $str2, $prozent);
$prozent = sprintf("%01.2f", $prozent);
if ($prozent > $minprozent) {
return TRUE;
}
else {
return FALSE;
}
}
$sql1 = "SELECT id, text FROM articles ORDER BY RAND() LIMIT 0, 20";
$sql2 = mysql_query($sql1);
while ($sql3 = mysql_fetch_assoc($sql2)) {
$rel1 = "SELECT id, text, MATCH (text) AGAINST ('".$sql3['text']."') AS score FROM articles WHERE MATCH (text) AGAINST ('".$sql3['text']."') AND id NOT LIKE ".$sql3['id']." LIMIT 0, 20";
$rel2 = mysql_query($rel1);
$rel2a = mysql_num_rows($rel2);
if ($rel2a > 0) {
while ($rel3 = mysql_fetch_assoc($rel2)) {
if (check($sql3['text'], $rel3['text']) == TRUE) {
$id_a = $sql3['id'];
$id_b = $rel3['id'];
$rein1 = "INSERT INTO related (article1, article2) VALUES ('".$id_a."', '".$id_b."')";
$rein2 = mysql_query($rein1);
$rein3 = "INSERT INTO related (article1, article2) VALUES ('".$id_b."', '".$id_a."')";
$rein4 = mysql_query($rein3);
}
}
}
}
?>
ПОДХОД 2 [только проверить()]
<?php
function square($number) {
$square = pow($number, 2);
return $square;
}
function check($text1, $text2) {
$words_sub = text_splitter($text2); // splits the text into single words
$words = text_splitter($text1); // splits the text into single words
// document 1 start
$document1 = array();
foreach ($words as $word) {
if (in_array($word, $words)) {
if (isset($document1[$word])) { $document1[$word]++; } else { $document1[$word] = 1; }
}
}
$rating1 = 0;
foreach ($document1 as $temp) {
$rating1 = $rating1+square($temp);
}
$rating1 = sqrt($rating1);
// document 1 end
// document 2 start
$document2 = array();
foreach ($words_sub as $word_sub) {
if (in_array($word_sub, $words)) {
if (isset($document2[$word_sub])) { $document2[$word_sub]++; } else { $document2[$word_sub] = 1; }
}
}
$rating2 = 0;
foreach ($document2 as $temp) {
$rating2 = $rating2+square($temp);
}
$rating2 = sqrt($rating2);
// document 2 end
$skalarprodukt = 0;
for ($m=0; $m<count($words)-1; $m++) {
$skalarprodukt = $skalarprodukt+(array_shift($document1)*array_shift($document2));
}
if (($rating1*$rating2) == 0) { continue; }
$kosinusmass = $skalarprodukt/($rating1*$rating2);
if ($kosinusmass < 0.7) {
return FALSE;
}
else {
return TRUE;
}
}
?>
Я также хотел бы сказать, что я знаю, что есть много алгоритмов для кластеризации, но на каждом сайте есть только математическое описание, которое для меня трудно понять. Поэтому примеры кодирования в (псевдо) коде были бы замечательными.
Надеюсь, вы можете мне помочь. Заранее спасибо!
Есть плагины WordPress (да, да, я знаю, избавлю меня от этого), которые делают удивительно хорошую работу, они на самом деле выполняют разумную кластеризацию (как правило, они используют TF-IDF с обратной связью с помощью k-средств или чего-то еще как это), и вы можете использовать их для вдохновения (некоторые из них с открытым исходным кодом при MIT). –
Я думаю, что Anony-Mousse прав: кластеризация - не идеальный инструмент здесь. Если каждый документ принадлежит только одному кластеру, то у вас есть проблема с документами, расположенными вблизи границ кластера, * более похожих * на документы в других соседних кластерах, чем на большинство документов в их собственном кластере. –