通过标签频率获得类似主题文本的算法

时间:2013-09-06 16:07:57

标签: php mysql algorithm

我有一堆文字(标题+信息),我想为它们添加标签。我通过这种方式处理每个文本:

  1. 忽略文章,代词等('a','an','the','他','他们'等)
  2. 忽略连字符
  3. 保留专有名词
  4. 并为每个文本及其条目编号获取一些标记。

    现在我有标签和文本ID的关系频率表:

                     tag_id1 | tag_id2 | tag_id3 | tag_id4
          text_id1  | 10     |  1      | 3       |   1   
          text_id2  | 1      |  1      | 1       |   1
          text_id3  | 13     |  0      | 2       |   0
          text_id4  | 9      |  1      | 2       |   1
          text_id5  | 0      |  0      | 0       |   0
    

    如何通过mysql查询确定text_id1的类似文本? 我想得到排序列表之类的东西 text_id3 text_id4 text_id2

    “Jaccard相似度”algo是不够的,因为它只计算标签关系

2 个答案:

答案 0 :(得分:1)

相似的一个衡量标准是每个标记字段中差异的绝对值。您可以在SQL中计算如下:

select t2.name, abs(t1.tag_id1-t2.tag_id1)+abs(t1.tag_id2-t2.tag_id2)+
abs(t1.tag_id3-t2.tag_id3)+abs(t1.tag_id4-t2.tag_id4) score from 
tag t1, tag t2 where t1.name='text_id1' and t2.name != 'text_id1' 
order by score asc;
+----------+-------+
| name     | score |
+----------+-------+
| text_id4 |     2 |
| text_id3 |     6 |
| text_id2 |    11 |
| text_id5 |    15 |
+----------+-------+

答案 1 :(得分:1)

您可以将文本特征解释为向量,将标记作为维度(或者更确切地说是基础,如果您深入到线性代数中)。然后,您可以计算文本之间的点积以评估相似性。

这将奖励普通标签中的高频率,但不会主动惩罚一个文本中频率较高但另一个文本中频率较低的标签。因此,在很多地方谈论大多数标签的长文本将比仅包含少量标签的短文本排名更高,但这些标签与参考文本非常相似。如果这是一个问题,你可以通过使用相对而不是绝对频率来改善情况,即将频率乘以一个公因子,使得它们的和等于每个文本的1(或100或其他)。

如果您的频率仅在一个列中,并且在另外两列中包含text和tag id,则执行此计算会更容易。假设您有一个名为freqs的表格,其中包含text_idtag_idfrequency列。然后你可以做类似

的事情
SELECT t2.text_id, SUM(t1.frequency * t2.frequency) AS score
FROM freqs AS t1, freqs AS t2
WHERE t1.text_id = ?           -- insert the ID of the reference text
  AND t2.text_id <> t1.text_id -- different text
  AND t1.tag_id = t2.tag_id    -- but same tag
GROUP BY t2.text_id            -- one result for every text
ORDER BY score DESC            -- closest text first

您可以在http://sqlfiddle.com/#!2/a6af7/4

看到这一点