根据术语的位置对文本字符串进行排名

时间:2013-06-18 08:17:43

标签: algorithm sorting ranking

我基本上需要一些数学来根据以下指标对短输入句子进行排名:

1)术语相对于句子开头的距离(注意:相对术语距离,无编辑距离!)。 例如,搜索“a”应该给出比“b a”更高等级的句子“a b”,因为a更接近句子的开头。

2)条款相互之间的距离。 例如搜索“a”和“b”应该将“ccc a b”排在高于“a ccc b”的位置,因为a和b彼此更接近。

3)基于术语顺序的排名。 例如搜索AND b应该将“a b”排在高于“b a”的位置,因为它是正确的顺序。尽管如此,b a也应该在结果集中,所以它必须按照较低的权重进行排名。

4)单词本身是不合适的。这是广泛传播的主要区别,以及我可以轻松找到的信息。但在我的情况下,所有术语都具有相同的权重,无论它们在文档中的出现/计数等等。

我完成了我的研究但发现没有匹配。你知道排名算法会匹配什么,或者至少接近这个吗?

1 个答案:

答案 0 :(得分:1)

  1. 计算主题字符串中每个搜索词的位置。
  2. 计算搜索字符串中所有字词的平均排名。
  3. 计算主题字符串和搜索字词列表中的平均位置之间的绝对差值。
  4. 计算术语位置相对于平均值的绝对差值。
  5. decimal Rank(string subject, IList<string> terms)
    {
        // Isolate all the words in the subject.
        var words = Regex.Matches(subject, @"\w+")
            .Cast<Match>()
            .Select(m => m.Value.ToLower())
            .ToList();
    
        // Calculate the positions
        var positions = new List<int>();
        var sumPositions = 0;
        foreach (var term in terms)
        {
            int pos = words.IndexOf(term.ToLower());
            if (pos < 0) return decimal.MaxValue;
            positions.Add(pos);
            sumPositions += pos;
        }
    
        // Calculate the difference in average positions
        decimal averageSubject = (decimal) sumPositions / terms.Count;
        decimal averageTerms = (terms.Count - 1) / 2m; // average(0..n-1)
        decimal rank = Math.Abs(averageSubject - averageTerms);
    
        for (int i = 0; i < terms.Count; i++)
        {
            decimal relativePos1 = positions[i] - averageSubject;
            decimal relativePos2 = i - averageTerms;
            rank += Math.Abs(relativePos2 - relativePos1);
        }
    
        return rank;
    }
    

    我使用较低的值来获得更好的匹配,因为从完美匹配中测量距离比每场比赛的得分更容易。

    示例

    Subject     Terms       Rank
    "a b"       "a"         0.0
    "b a"       "a"         1.0
    "ccc a b"   "a", "b"    1.0
    "a ccc b"   "a", "b"    1.5
    "a b"       "a", "b"    0.0
    "b a"       "a", "b"    2.0