1

我有一个函数,它接受两个包含两个文本的标记/单词的数组,并给出显示两个文本之间关系的余弦相似度值。

该函数接受一个数组 $tokensA (0=>house, 1=>bike, 2=>man) 和一个数组 $tokensB (0=>bike, 1=>house, 2=>car) 并计算相似度,即作为浮点值返回。

function cosineSimilarity($tokensA, $tokensB) {
    $a = $b = $c = 0;
    $uniqueTokensA = $uniqueTokensB = array();
    $uniqueMergedTokens = array_unique(array_merge($tokensA, $tokensB));
    foreach ($tokensA as $token) $uniqueTokensA[$token] = 0;
    foreach ($tokensB as $token) $uniqueTokensB[$token] = 0;
    foreach ($uniqueMergedTokens as $token) {
        $x = isset($uniqueTokensA[$token]) ? 1 : 0;
        $y = isset($uniqueTokensB[$token]) ? 1 : 0;
        $a += $x * $y;
        $b += $x;
        $c += $y;
    }
    return $b * $c != 0 ? $a / sqrt($b * $c) : 0;
}

如果我想比较 75 个文本,我需要进行 5,625 次单次比较才能将所有文本相互比较。

是否可以使用 MySQL 的空间列来减少比较次数?

我不想谈论我的功能或比较文本的方法。只是减少比较的次数。

MySQL的空间列

  • 您使用以下命令创建空间列:CREATE TABLE abc (clmnName TYPE)
  • 此处列出了可能的类型
  • 是我稍后选择数据的方式[例如 MultiPointFromText() 或 AsText()]
  • 您插入这样的值: INSERT INTO clmnName VALUES (GeomFromText('POINT(1 1)'))

但是你如何用它来解决我的问题?

PS:我正在寻找减少与此问题中算法的比较次数的方法。Vinko Vrsalovic 告诉我,我应该针对空间特征提出另一个问题。

4

2 回答 2

1

虽然R-Trees通常可以索引具有任意数量维度的数据,但MySQL空间能力仅限于Geometry类型(2维度)。

如果您的向量是-2维的并且您可以对其进行归一化,请执行以下操作:

  • 将圆圈分成适合您差异的角度数的两倍
  • MBR从每个扇区的中心找到具有给定余弦差的向量
  • 查找范围内的所有向量MBR
  • 对精确差异进行精细过滤。

但是,在这种情况下,最好只预先计算值的角度并使用普通索引对其进行B-Tree索引。

于 2009-09-22T15:06:35.160 回答
1

事实上,您只有75 * 74 / 2 = 2775 次比较。您将每个单词与其他 74 个单词进行比较,但您不需要将 word1 与 word2 以及 word2 与 word1 进行比较。所以它少了一半的比较

于 2009-09-22T15:05:35.910 回答