具有多个参数的客户端预测搜索相关性计算

时间:2011-01-28 13:07:22

标签: javascript algorithm search client-side relevance

我正在编写一个预测性搜索,为了服务器性能要求(全部被缓存),必须在客户端浏览器上运行。这些项目是电视节目和电影,并由标题,演员和导演名称匹配。执行搜索后,它会返回一个匹配项列表,其中包含每个结果的两个值:

  1. 匹配单词的数量(n):用户可以输入4个单词,但只有2个单词与一个项目匹配。越多越好。

  2. Levenshtein Edit Distance加法(ld)。用户可以键入3个单词,但其中2个单词与索引的单词有差错或其他小差异。我使用编辑距离来查找最近的索引字。所有Levenshtein距离的添加都作为接近指示符返回。越少越好。

  3. 要求

    1. 客户端。没有Sphinx,Lucene或任何其他服务器端解决方案。

    2. 速度超过准确性。该算法在每次击键时运行,我们不想让用户厌烦。保持大O 不是那么

    3. 非递归的。每个项目相关性的计算不应该依赖于其他项目计算。我不想击败谷歌,只提供一小部分的最佳结果。

    4. 有界形式0到1,0到100或类似的东西。不是必需品,但能够显示“相关百分比”是一个加号。

    5. 关于实施的想法。我正在寻找一种比特定实现更好的算法/公式。

    6. 我的aproach

      基于指数衰减(如放射性半衰期分解),我制定了这个公式。

      Math style, thanks to wikipedia LaTeX support

      其中:

      • T是用户提供的字数。
      • n是匹配单词的数量。
      • ld是此匹配词的Levenshtein距离加法。

      在伪代码中。

      function lambda(n, ld) {
          lambda = (n/T) * e^(-ld * 1/n);
          return lambda;
      }
      

      一点解释:

      • -ld * 1/n是相关性度量核心。如果ld较低且n较大,则接近于零(-0侧)并表示此结果更具相关性。

      • n/T是准确率。匹配单词与所有单词。通过考虑总用户输入来优化先前的相关性。

      指数函数,对于负数幂,将结果绑定在0和1之间。

      最后,问题

      我想要的不是基于具有额外编辑距离计算的this response来优化搜索算法,而是通过将相关值设置为每个来提高返回元素的相关性排序。如果需要nld以外的任何参数并且可以轻松计算,则可以使用。在我的解决方案中,我添加了T,即用户提供的字数。

1 个答案:

答案 0 :(得分:7)

一般情况下,我认为您必须简化您的公式。事实上,像tf-idf这样的大多数基本相关公式非常简单,只使用生产或参数的一部分,可能还有“强化”或“弱化”功能。例如,tf-idf只是术语频率的乘法和对数逆文档频率的“弱化”。首先,我会快速分析您的公式,然后提出一些建议。

分析

让我们改写你的公式:

enter image description here

首先,请注意,n/T 未规范化:可能会有更多结果(n),然后搜索字词(T)。考虑这样的例子:用户输入查询“John Malkovich”,并且数据库中有电影Being John Malkovich。用户输入了2个单词,即T = 2,但电影在电影片名和演员表中都有这些术语,所以n = 2 * 2 = 4。鉴于此,最终的相关性将更加严重。缺乏正常化本身并不是问题,但在实践中,它可能会在未来导致许多错误。

现在让我们看一下公式的第二部分 - 1 / e^(ld/n)。我们将ld/n表示为x。在这种情况下,公式的第二部分将如下所示:

enter image description here

因此,对于x的高值,它会削弱最终的相关性。虽然我不明白为什么它必须是指数级的,但它仍然有意义。但是x不是自变量,它本身就是2个变量的函数:x = x(ld, n)。此外,ld也是一个函数:ld = ld(MAX_LD, T),因此x取决于3个不同的自变量/参数:x = x(MAX_LD, T, n)。在这种情况下,很难预测所有可能情况下x的行为(以及最终相关性)。

提案

<强> 1。简化x()。如果您希望公式的第二部分仅跟踪Levenshtein距离,则仅依赖于此距离,而不是所有3个独立变量。例如,您的公式可能如下所示:

enter image description here

甚至:

enter image description here

其中distance是实际的Levenshtein编辑距离,而不是TMAX_LD的函数。

<强> 2。使用词干。我知道,我知道,你说过,你不能使用服务器端编程。但是你确定它无法在客户端执行吗? Steming似乎比它容易得多。大多数词干只是截断后缀和结尾,如“-s”,“-ing”,“-ment”等。这不是理想的,但我相信它会给出更好的结果,然后是Levenshtein距离。这里唯一强大的限制是:词干必须同时用于 - 索引和搜索

有关更精确的词干算法,请参阅Lucene sources中的PorterStemmer类。

第3。使用逆记录频率。使用查询“John Malkovich”调用示例。可能有很多电影用“约翰”这个词,但只有几部用“马尔科维奇”。很自然地假设,第二项必须在搜索结果中具有更大的权重,然后是第一项。 tf-idf在其idf(逆文档频率)部分中涉及此事实。你可以通过计算逆记录频率来做同样的事情:

irf = number-of-all-found-records / number-of-records-with-current-term

并添加相关公式第三部分:

enter image description here

当然,请记住:在真实数据上测试之前,没有公式是好的