比较标签组以找到与PHP / MySQL的相似性/得分

时间:2010-08-10 05:32:06

标签: php mysql tags

如何将一组标记与我的数据库中的其他帖子标记进行比较以获取相关帖子?

我要做的是将帖子上的一组标签与另一个帖子的标签进行比较,但不是单独评估每个标签。所以说你希望根据帖子中的标签获得真正相关的项目,然后从最相关和最不相关的项目中显示它们。无论关系水平如何,每次都必须显示三个相关项目。

  

帖子A有标签:“建筑”,“木头”,“现代”,“瑞士”   邮政B有标签:“建筑”,“木材”,“现代”   帖子C有标签:“建筑”,“现代”,“石头”
  Post D有标签:“architecture”,“house”,“residence”

     

职位B与职位A相关75%(3个相关标签)
  帖子C与帖子A相关50%(2个相关标签)
  帖子D与帖子A相关25%(1个相关标签)

我该怎么做?我目前正在使用 3-table

posts
> id
> image
> date

post_tags
> post_id
> tag_id

tags
> id
> name

我搜索过Internet和Stack Overflow以了解如何执行此操作。我最近的发现是How to find "related items" in PHP,但实际上并没有为我解决太多问题。

2 个答案:

答案 0 :(得分:3)

注意:此解决方案仅适用于MySQL,因为MySQL有自己对GROUP BY的解释

我也使用了自己的相似度计算。我已经采用相同标签的数量并将其除以帖子A和帖子B中的平均标签数量。因此,如果帖子A有4个标签,而帖子B有2个标签,它们都与A共享,则相似度为66%

(SHARED:2 / ((A:4 + B:2)/2)(SHARED:2) / (AVG:3)

如果您需要/需要更改公式应该很容易......

SELECT
 sourcePost.id,
 targetPost.id,

 /* COUNT NUMBER OF IDENTICAL TAGS */
 /* REF GROUPING OF sourcePost.id and targetPost.id BELOW */
 COUNT(targetPost.id) /
 (
  (
   /* TOTAL TAGS IN SOURCE POST */
   (SELECT COUNT(*) FROM post_tags WHERE post_id = sourcePost.id)

   +

   /* TOTAL TAGS IN TARGET POST */
   (SELECT COUNT(*) FROM post_tags WHERE post_id = targetPost.id)

  ) / 2  /* AVERAGE TAGS IN SOURCE + TARGET */
 ) as similarity
FROM
 posts sourcePost
LEFT JOIN
 post_tags sourcePostTags ON (sourcePost.id = sourcePostTags.post_id)
INNER JOIN
 post_tags targetPostTags ON (sourcePostTags.tag_id = targetPostTags.tag_id
                             AND 
                              sourcePostTags.post_id != targetPostTags.post_id)
LEFT JOIN
 posts targetPost ON (targetPostTags.post_id = targetPost.id)
GROUP BY
 sourcePost.id, targetPost.id

答案 1 :(得分:0)

将标签放入数组中。每个阵列分别称为Post A / Post B等。 然后使用array_diff_assoc()来确定数组的不同之处。

但实际上,Ivars解决方案可以更好地工作,但这更容易理解:)