0

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

  1. 忽略冠词、代词等('a'、'an'、'the'、'him'、'them'等)
  2. 忽略连字符
  3. 保留专有名词

并获取每个文本的类型标签及其条目数。

现在我有标签和文本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 相似度”算法是不够的,因为它只计算标签关系

4

2 回答 2

1

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

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

如果您的频率仅在一个列中,而文本和标签 ID 在另外两列中,则执行此计算会更容易。假设您有一个名为freqs列的表text_idtag_id并且frequency。然后你可以做类似的事情

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看到这一点

于 2013-09-06T22:10:48.777 回答
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 |
+----------+-------+
于 2013-09-06T16:38:09.677 回答