Представьте себе следующую проблему:
- У вас есть база данных, содержащая около 20 000 текстов в таблице под названием "статьи".
- Вы хотите связать связанные с ним алгоритмы кластеризации, чтобы отображать связанные статьи вместе.
- Алгоритм должен выполнять плоскую кластеризацию (не иерархическую)
- Связанные статьи должны быть вставлены в таблицу "related"
- Алгоритм кластеризации должен решить, связаны ли две или более статьи или нет на основе текстов
- Я хочу кодировать на PHP, но примеры с псевдокодом или другими языками программирования в порядке, тоже
Я закодировал первый черновик с функцией check(), которая дает "true", если две исходные статьи связаны, а "false", если нет. Остальная часть кода (выбор статей из базы данных, выбор статей для сравнения с вставкой соответствующих) также завершен. Может быть, вы тоже можете улучшить остальные. Но главное, что важно для меня, это функция 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;
}
}
?>
Я также хотел бы сказать, что я знаю, что существует множество алгоритмов кластеризации, но на каждом сайте есть только математическое описание, которое мне трудно понять. Поэтому примеры кодирования в (псевдо) коде были бы большими.
Надеюсь, ты поможешь мне. Спасибо заранее!