Wyobraźmy sobie następujący problem:Najlepszy algorytm grupowania? (Prosto wyjaśnione)
- Masz bazę danych zawierającą około 20.000 tekstów w tabeli o nazwie „Artykuły”
- Chcesz połączyć związanych te stosując algorytm klastrowania w celu wyświetlenia wyroby związanych razem
- algorytm należy do płaskiej klastrów (nie hierarchicznej)
- Odnośne artykuły powinny być wstawiony do tabeli „związanej”
- algorytmu klasteryzacji powinien zdecydować, czy dwa lub mor Artykuły E są związane lub nie oparte na tekstach
- Chcę kod w PHP, ale przykłady z pseudo kod lub innych języków programowania są ok, zbyt
mam zakodowane pierwszy projekt z czekiem function (), co daje "prawda", jeśli dwa artykuły wejściowe są powiązane i "fałsz", jeśli nie. Reszta kodu (wybór artykułów z bazy danych, wybór artykułów do porównania, wstawienie powiązanych) również jest kompletny. Może też poprawisz resztę. Ale najważniejszą kwestią, która jest dla mnie ważna, jest funkcja check(). Byłoby wspaniale, gdybyś mógł opublikować poprawki lub zupełnie inne podejścia.
PODEJŚCIE 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);
}
}
}
}
?>
PODEJŚCIE 2 [tylko sprawdzić()]
<?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;
}
}
?>
Chciałbym również powiedzieć, że wiem, że istnieje wiele algorytmów grupowania ale na każdej stronie jest tylko opis matematyczny, który jest dla mnie nieco trudny do zrozumienia. Więc kodowanie przykładów w (pseudo) kodzie byłoby świetne.
Mam nadzieję, że możesz mi pomóc. Z góry dziękuję!
Istnieje WordPress Wtyczki (tak, fuj, wiem, oszczędź mi tego), że roboty zaskakująco dobrą pracę na to, że rzeczywiście wykonać rozsądny klastrów (zazwyczaj robią tfidf z tyłu słów z k-średnich lub coś w ten sposób) i można ich użyć do inspiracji (niektóre z nich to open source w ramach MIT). –
Myślę, że Anony-Mousse ma rację: klastrowanie nie jest tutaj idealnym narzędziem. Jeśli każdy dokument należy do tylko jednego klastra, to masz problem z dokumentami znajdującymi się w pobliżu granic klastra, które są * bardziej podobne * do dokumentów w innych pobliskich klastrach niż do większości dokumentów w ich własnym klastrze. –