次の問題を想像してください。
- 「articles」というテーブルに約 20,000 のテキストを含むデータベースがあります。
- 関連記事をまとめて表示するために、クラスタリングアルゴリズムを使って関連記事をつなぎたい
- アルゴリズムはフラット クラスタリングを行う必要があります (階層的ではありません)。
- 関連記事は「関連」テーブルに挿入する必要があります
- クラスタリング アルゴリズムは、テキストに基づいて、2 つ以上の記事が関連しているかどうかを判断する必要があります。
- PHPでコーディングしたいが、疑似コードや他のプログラミング言語を使ったサンプルでもOK
2 つの入力記事が関連している場合は「true」を返し、そうでない場合は「false」を返す関数 check() を使用して最初のドラフトをコーディングしました。残りのコード (データベースからの記事の選択、比較対象の記事の選択、関連記事の挿入) も完了しています。たぶん、残りも改善できます。しかし、私にとって重要なポイントは関数 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 [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;
}
}
?>
また、クラスタリングには多くのアルゴリズムがあることを知っていますが、すべてのサイトには数学的な説明しかなく、理解するのが少し難しいことも知っています. したがって、(疑似)コードでのコーディング例は素晴らしいでしょう。
あなたが私を助けてくれることを願っています。前もって感謝します!