gpt4 book ai didi

algorithm - 最佳聚类算法? (简单解释)

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:18:23 25 4
gpt4 key购买 nike

想象一下以下问题:

  • 您有一个数据库,在名为“文章”的表中包含大约 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;
}
}
?>

我还想说,我知道有很多聚类算法,但在每个站点上只有数学描述,这对我来说有点难以理解。因此,(伪)代码中的编码示例会很棒。

我希望你能帮助我。提前致谢!

最佳答案

我所知道的对文本数据执行此操作的最标准方法是使用“词袋”技术。

首先,为每篇文章创建一个单词“直方图”。假设在您的所有文章之间,您只有 500 个独特的单词。然后这个直方图将是一个大小为 500 的向量(数组,列表,任何),其中数据是每个单词在文章中出现的次数。因此,如果向量中的第一个点代表单词“asked”,并且该单词在文章中出现了 5 次,则 vector[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

(抱歉使用 python 而不是 PHP,我的 PHP 生锈了,使用 zip 使这更容易一些)

这是基本思想。注意阈值是半任意的;您可能想找到一种好方法来标准化直方图的点积(这几乎必须在某处考虑文章长度)并决定您认为“相关”的内容。

此外,您不应该只将每个词都放入直方图中。一般来说,您会希望包括半频繁使用的那些:不是在每篇文章中,也不是只在一篇文章中。这为您节省了直方图的一些开销,并增加了关系的值(value)。

顺便说一下,这个技术有更详细的描述here

关于algorithm - 最佳聚类算法? (简单解释),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/853139/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com