【问题标题】:Compare group of tags to find similarity/score with PHP/MySQL比较标签组以查找与 PHP/MySQL 的相似性/分数
【发布时间】:2010-08-10 05:32:06
【问题描述】:

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

我要做的是将帖子上的一组标签与另一个帖子的标签进行比较,而不是单独比较每个标签。因此,假设您想根据帖子中的标签获取真正相关的项目,然后从最相关到​​最不相关显示它们。无论关系级别如何,每次都必须显示三个相关项目。

帖子 A 的标签有:“建筑”、“木材”、“现代”、“瑞士”
帖子 B 的标签有:“建筑”、“木材”、“现代”
Post C 有标签:“建筑”、“现代”、“石头”
帖子 D 有标签:“建筑”、“房子”、“住宅”

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

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

posts
> id
> image
> date

post_tags
> post_id
> tag_id

tags
> id
> name

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

【问题讨论】:

  • 我已经用更清晰的问题更新了我的帖子。
  • 你如何计算你的百分比?您期望从 A 与 B 的关系(而不是 B 与 A)中得到什么关系百分比? 100% 还是 75%?如果答案是 75%,那么在 B 中添加另一个不相关的标签会改变这种情况吗? B与C的关系如何? 66% 或 50%(2 个相关,2 个不相关)?
  • 这是个好问题。我认为通过计算相关分数,结果会更好。我不知道计算标签是否无关的额外工作是否重要——不过这可能是有益的。

标签: php mysql tags


【解决方案1】:

注意:此解决方案仅适用于 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

【讨论】:

  • Ivar,非常感谢您的帮助 - 这非常有效。我已经稍微改变了分组以更好地组织结果。我想知道的一件事是,如果结果少于 3 个,是否可以从数据库中随机获取一组项目?
【解决方案2】:

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

但实际上,Ivars 解决方案会更好,虽然这更容易理解 :)

【讨论】:

  • 这绝对更容易理解,如果必须的话,这是我的后备解决方案。我现在正在尝试检查是否返回的结果少于 3 个,是否有办法(在查询中)从数据库中获取一组随机项目?
猜你喜欢
  • 2013-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多