ベストクラスタリングアルゴリズム?(説明)
-
21-08-2019 - |
質問
想像以下の問題:
- お持ちのデータベースを含む約20,000テキストテーブルという記事"
- 接続したいのとなってくると考えられる利用クラスタリングアルゴリズムを表示するためには、関連する記事と
- このアルゴリズムをなすべき平クラスタリング(階層)
- に関連する記事に入れておきのテーブルの関連"
- のクラスタリングアルゴリズムを決定すべきであるかどうか二つ以上の記事に関係なのテキスト
- したいコードでPHPが例擬似コードまたはその他のプログラミング言語でもok
私はコード最初の草案の機能をチェックを"true"の場合には、入力記事に関連し、"false"の場合。他のコードを選択する論文データベースから選択品との比較を挿入しながら、その関係者が完了している。ものを向上させることができ、残ります。その主な点において重要となるというのは、機能確認().であれば良後の改善もしくは全く異なるアプローチ。
アプローチ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;
}
}
?>
もっと言うことを知っている多くのアルゴリズムのクラスタリングが複数のウェブサイトが数学的に説明するのは少し難解でした。で符号化の例(擬似コードす。
かんでいただけたでしょうか助けてくれます。感謝。
解決
私はあなたが持っているように、テキストデータでこれを行うためにの知っている最も標準的な方法は、技術の言葉の袋 "を使用することです。
まず、各記事の言葉の「ヒストグラム」を作成します。あなたが唯一のそれらの間の500のユニークな言葉を持っている、すべてのあなたの記事の間で言うことができます。そして、このヒストグラムは、データが各単語が記事に表示された回数で大きさ500のベクトル(配列、リスト、どのような)になるだろう。ベクトルの最初のスポットが単語を表すのであれば「尋ね」、およびその単語が記事に5回登場し、ベクトルは[0] 5になります:
for word in article.text
article.histogram[indexLookup[word]]++
さて、任意の二つの記事を比較するために、それは非常に簡単です。我々は、単に二つのベクトルを乗算します:
def check(articleA, articleB)
rtn = 0
for a,b in zip(articleA.histogram, articleB.histogram)
rtn += a*b
return rtn > threshold
(代わりにPHPのPythonの使用のため申し訳ありませんが、私のPHPは錆びているとジップの使用は、そのビット容易になります)。
これは基本的な考え方です。閾値は半任意で気づきます。おそらくあなたのヒストグラムの内積を正規化(これはほとんどどこかの記事の長さも考慮しなければならない)、あなたは「関連」考えるものを決定するための良い方法を見つけたいと思うでしょう。
また、あなたは自分のヒストグラムにすべての単語を置くべきではありません。必ずしもすべての記事にも一つだけの記事で:あなたは、一般的には、半頻繁に使用されているものを挙げることになるでしょう。これは、あなたのヒストグラム上のオーバーヘッドのビットを保存し、あなたの関係の価値を高めます。
ところで、この技術をより詳細に説明されているこちら
他のヒント
か クラスタリングは間違った戦略 いので、これから
表示したい場合 類似の 記事 使用 類似度検索 代わりに.
テキストの記事が考えられている。ですの記事テキスト検索データベースのような可能、現在の条において検索を返します。に導入可能であ クエリーと呼ばれ MoreLikeThis
を行うこ:見らに類す
クラスタリングを間違えることができない(特にお客様の要件), 毎 第条取り除く取組みが不可欠であるがクラスター;に関連する項目も同じですべてのオブジェクトのクラスターがある場合はオプションに設定された値のデータベースある場合も破綻にクラスタリング.さらに、 クラスターが非常に大きな.ありサイズの制約、クラスタリングアルゴリズムの決定により入の半分のデータセットを同じクラスターい10000関連記事の各条にデータベースです。との類似性を検索したりすることも可能ですのトップ10の類似項目。
最後に:忘れPHP用クラスタリング.この設計にはなっておりませんのでこなperformant十分です。ができるのではないでしょうかアクセス可能ファイルとディレクPHPも十分です。
ダウンロードいただけまつかデザイン決定のクラスタリング、続けてからもコメントありがとうございます
- なぜクラスタリングテキスト?いディスプレイに関する文書の相互の関連性を検討した。いをお書コーパス経由でクラスター?
- その結果、い 平 または 階層 クラスタリング?
- 現在の複雑な問題は、二つの外形寸法:第一に、グループのリスク-プロファイルの作成からテキスト個人の言葉が数万人.違いによって一部 特徴選択を などのN番参考に、または、Nの言葉に現れるのも、後を無視して ストップワード.
- 第二に、たいへの回数を最小限に抑えるために何度で測定間の類似度を提出する。としてbubaker正しいポイントは、チェック間の類似度すべてのペアの書きます。場合にクラスタリングに少人数のクラスターが上がれます♪※数に限りがございえ K-meansクラスタリング, は、基本的には:選べる最初のK書類としてクラスターセンターに割り当て各文書は、最寄りのクラスターでは、音楽はグラミー賞にノミネータセンターによる発見の文書ベクトルと、繰り返し処理を実行し.これだけコストのK-文りになります。があると考えていまヒューリスティックスを低減するために必要な数計算のための階層的クラスタリングします。
similar_text
機能のようなアプローチ#1の外観に何と呼ばれていますか?私はあなたがクラスタリングされていないを参照するが、類似性メトリックしているものと思います。私は本当にホワイトWallounの:-)ヒストグラムのアプローチを改善することはできません - 。いくつかは、上読ん行うには興味深い問題
あなたはcheck()
を実装ただし、少なくとも200Mの比較(20000^2
の半分)を作るためにそれを使用するようになってきました。 「関連」の記事のためのカットオフは、データベースに格納するものに制限はなく、テキストのすべての有用なクラスタリングをキャッチするために、あまりにも任意と思われるかもしれ、
私のアプローチは、「類似性」メトリック(check()
または$prozent
)を返すようにrtn
を変更することであろう。ファイルへの20K x 20K
行列を書き、あなたがrelated
テーブルにロードすることができ、各記事のための最も近い隣人を識別するために、クラスタリングを実行するために外部プログラムを使用します。私はR
でクラスタリングを行うだろう - href="http://www.stanford.edu/~mjockers/cgi-bin/drupal/node/25" rel="nofollow noreferrer">チュートリアル R
からphp
を実行しているファイル内のデータをクラスタリングする。