Stellen Sie sich das folgende Problem vor:
- Sie haben eine Datenbank mit etwa 20.000 Texten in einer Tabelle namens "Artikel".
- Sie möchten die verwandten Artikel mithilfe eines Clustering-Algorithmus miteinander verbinden, um verwandte Artikel gemeinsam anzuzeigen
- Der Algorithmus sollte ein flaches Clustering durchführen (nicht hierarchisch)
- Die verwandten Artikel sollten in die Tabelle "Verwandte" eingefügt werden.
- Der Clustering-Algorithmus sollte anhand der Texte entscheiden, ob zwei oder mehr Artikel miteinander verwandt sind oder nicht
- Ich möchte in PHP programmieren, aber Beispiele mit Pseudocode oder anderen Programmiersprachen sind auch in Ordnung
Ich habe einen ersten Entwurf mit einer Funktion check() kodiert, die "true" ausgibt, wenn die beiden eingegebenen Artikel miteinander verwandt sind, und "false", wenn nicht. Der Rest des Codes (Auswahl der Artikel aus der Datenbank, Auswahl der Artikel, mit denen verglichen werden soll, Einfügen der verwandten Artikel) ist ebenfalls vollständig. Vielleicht können Sie auch den Rest noch verbessern. Aber der wichtigste Punkt, der mir wichtig ist, ist die Funktion check(). Es wäre also toll, wenn Sie einige Verbesserungen oder ganz andere Ansätze posten könnten.
ANFAHRT 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);
}
}
}
}
?>
APPROACH 2 [nur check()]
<?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;
}
}
?>
Ich möchte auch sagen, dass ich weiß, dass es viele Algorithmen für Clustering gibt, aber auf jeder Website gibt es nur die mathematische Beschreibung, die für mich etwas schwer zu verstehen ist. Beispiele in (Pseudo-)Code wären also großartig.
Ich hoffe, Sie können mir helfen. Vielen Dank im Voraus!