Solr:分数为百分比
Solr: Scores As Percentages
首先,我已经看到 the lucene doc 告诉我们不要以百分比形式生成分数:
People frequently want to compute a "Percentage" from Lucene scores to
determine what is a "100% perfect" match vs a "50%" match. This is
also somethings called a "normalized score"
Don't do this.
Seriously. Stop trying to think about your problem this way, it's not
going to end well.
由于这些建议,我使用了另一种方法来解决我的问题。
但是lucene的论证有几个点我不太明白为什么有些时候会出问题
对于 this post 的情况,我很容易理解为什么它不好:如果用户进行搜索并看到以下结果:
- ProductA:5 颗星
- 产品 B:2 颗星
- ProductC:1 颗星
如果ProductA在第一次搜索后就被删除了,下次用户来的时候,看到下面的结果会很惊讶:
- 产品 B:5 颗星
- ProductC:3 颗星
所以,这个问题正是 Lucene 的文档所指出的。
现在,让我们再举一个例子。
假设我们有一个使用 'classic search' 结合 语音搜索 的电子商务网站。拼音搜索在这里是为了避免由于拼写错误导致的最大数量的空结果。拼音结果的分数相对于经典搜索的分数很低。
在这种情况下,第一个想法是仅 return 结果 至少达到最高分数 的 10%。低于此阈值的结果将不会被视为与我们相关,即使使用经典搜索也是如此。
如果我这样做了,我就没有上面的问题 post 因为如果一个文档被删除,旧的第二个产品似乎是合乎逻辑的成为第一个,用户不会感到非常惊讶(这与我将分数保持为浮点值的行为相同)。
此外,如果拼音搜索的分数很低,正如我们预期的那样,我们将只对 return 相关分数保持相同的行为。
所以我的问题是:按照 Lucene 的建议对分数进行归一化总是不好的吗?我的例子是一个例外还是即使对我的例子也这样做是个坏主意?
如您所述,Lucene 得分值仅与表达组 比赛中每场比赛的相对强度相关].在一组特定搜索结果的上下文中,特定记录的分数没有绝对意义。
出于这个原因,唯一合适的分数规范化是规范化结果集中文档相关性之间的关系,即便如此,您仍需要非常小心地使用此信息。
考虑这个结果集,我们在其中检查每条记录的得分与 紧接在前的结果:
ProductA (Let's pretend the score is 10)
ProductB: 97% (9.7)
ProductC: 8.5% (.82)
ProductD: 100% (.82)
ProductE: 100% (.82)
ProductF: 24% (.2)
在这种情况下,前两个结果的得分非常相似,而接下来的三个结果得分相同但明显落后。这些数字显然不会与在线购物者共享,但 ProductC 和 ProductF 的低 相对 分数代表足够急剧的下降,您 可以 使用他们通知其他显示选项。也许 ProductA 和 ProductB 以比其他字体更大的字体显示。如果只有一种产品出现在急剧下降之前,它可能会得到更特别的突出显示。
我会警告不要在这种搜索中完全抑制相对得分较低的结果。正如您已经在示例中证明的那样,相对分数可能会产生误导,除非您的相关性得到很好的调整,否则最相关的文档可能并不总是最合适的。如果由于单个记录碰巧重复搜索词足够多次以获得出色的分数而导致期望的结果丢失,这对您没有好处,这是一个真正的威胁。
For example, "Hamilton Beach Three-In-One Convection Toaster Oven"
will match one in eight words against a search for toaster
, while "ToastMaster Toast Toaster Toasting Machine TOASTER"
will match as many as five in seven words depending on how you index. (Both product names are completely made up, but I wanted the second one to look less reputable.)
此外,所有返回的文档都是匹配项,无论它们的分数可能有多低。有时排名较低的结果是用户真正想要的黑马发现。用户将 不会 理解除了他们看到的之外还有匹配的文档,除非你告诉他们,所以你可能会在 "page 2" 上或在剪切后面隐藏尾随结果,但你可能不想阻止他们。让用户了解他们的结果集的大小也可以帮助他们决定如何微调他们的搜索。使用分数的显着下降作为分页的阈值可能非常有趣,但可能是一个具有挑战性的实现。
问题是,你如何确定你的截止点,它是什么意思?
看个例子可能更容易。假设我正在尝试按姓氏查找人员。我要搜索:
- "smithfield"
我有以下文件,我认为它们都非常匹配:
- smithfield - 完全匹配
- smithfielde - 非常接近,听起来很像,只有一个(无声)字母偏离
- smythfield - 非常接近,听起来很像,一个元音变了
- smithfelt - 几个字母不一样,但仍然很接近并且听起来很相似
- snithfield - 不太像,但只差一个字母。可能打错了。
- smittfield - 同样,听起来不太像,可能是打字错误或拼写错误
- smythfelt - 拼写有点不对,但可能是听错了
- smithfieldings - 相同的前缀
所以,我有四件事需要匹配。精确匹配要保证得分最高,我们要前缀匹配、模糊匹配、音似匹配。因此,让我们搜索:
smithfield smithfield* smithfield~2 metaphone:sm0flt
结果
- 史密斯菲尔德::: 2.3430576
- 史密斯菲尔德::: 0.97367656
- 史密斯菲尔德::: 0.5657166
- 史密斯费尔特::: 0.50767094
< 10% - 未显示
- 斯尼菲尔德::: 0.2137136
- 斯密特菲尔德::: 0.2137136
- smythfelt ::: 0.0691447
- 史密斯菲尔德::: 0.041700535
我认为 smithfieldings 是一场不错的比赛,但离晋级还有很远的距离!还不到最大值的 2%,别说 10% 了!好的,让我们尝试提升
smithfield^4 smithfield*^2 smithfield~2 metaphone:sm0flt
结果
- 史密斯菲尔德::: 2.8812196
- 史密斯菲尔德::: 0.5907072
- 史密斯菲尔德::: 0.30413133
< 10% - 未显示
- 史密斯费尔特::: 0.2729258
- 斯尼菲尔德::: 0.11489322
- 斯密特菲尔德::: 0.11489322
- 史密斯菲尔德::: 0.044836726
- smythfelt ::: 0.037172448
更糟!
并且在生产中问题更严重。在现实世界中,您可能正在处理冗长的复杂查询和全文文档。字段长度、匹配重复次数、协调因素、提升和大量查询词,所有这些因素都会影响得分。
看到第一个结果的分数比第二个高一个数量级,这真的不是什么不寻常的事情,尽管第二个结果仍然是一个有意义、有趣的结果。无法保证分数的均匀分布,因此我们不知道 10% 的数字意味着什么。并且 lucene 的评分算法往往会在使差异变小和变大方面出错。
总是不好吗?我会说是的。在我看来,总有两个更好的选择。
1 - 用好的查询控制你的结果集。如果您很好地构建了查询,那么 that 将提供结果的截断值,这不是因为分数的任意截断值,而是因为它根本不会被计分。
2 - 如果您不想那样做,那么在那个任意点截断结果真的有什么好处吗?用户非常善于识别搜索结果何时偏离了深度。用户无法找到他们想要的东西是一个严重的烦恼。只要顺序正确,显示太多结果通常不是问题。
首先,我已经看到 the lucene doc 告诉我们不要以百分比形式生成分数:
People frequently want to compute a "Percentage" from Lucene scores to determine what is a "100% perfect" match vs a "50%" match. This is also somethings called a "normalized score"
Don't do this.
Seriously. Stop trying to think about your problem this way, it's not going to end well.
由于这些建议,我使用了另一种方法来解决我的问题。
但是lucene的论证有几个点我不太明白为什么有些时候会出问题
对于 this post 的情况,我很容易理解为什么它不好:如果用户进行搜索并看到以下结果:
- ProductA:5 颗星
- 产品 B:2 颗星
- ProductC:1 颗星
如果ProductA在第一次搜索后就被删除了,下次用户来的时候,看到下面的结果会很惊讶:
- 产品 B:5 颗星
- ProductC:3 颗星
所以,这个问题正是 Lucene 的文档所指出的。
现在,让我们再举一个例子。
假设我们有一个使用 'classic search' 结合 语音搜索 的电子商务网站。拼音搜索在这里是为了避免由于拼写错误导致的最大数量的空结果。拼音结果的分数相对于经典搜索的分数很低。
在这种情况下,第一个想法是仅 return 结果 至少达到最高分数 的 10%。低于此阈值的结果将不会被视为与我们相关,即使使用经典搜索也是如此。
如果我这样做了,我就没有上面的问题 post 因为如果一个文档被删除,旧的第二个产品似乎是合乎逻辑的成为第一个,用户不会感到非常惊讶(这与我将分数保持为浮点值的行为相同)。
此外,如果拼音搜索的分数很低,正如我们预期的那样,我们将只对 return 相关分数保持相同的行为。
所以我的问题是:按照 Lucene 的建议对分数进行归一化总是不好的吗?我的例子是一个例外还是即使对我的例子也这样做是个坏主意?
如您所述,Lucene 得分值仅与表达组 比赛中每场比赛的相对强度相关].在一组特定搜索结果的上下文中,特定记录的分数没有绝对意义。
出于这个原因,唯一合适的分数规范化是规范化结果集中文档相关性之间的关系,即便如此,您仍需要非常小心地使用此信息。
考虑这个结果集,我们在其中检查每条记录的得分与 紧接在前的结果:
ProductA (Let's pretend the score is 10)
ProductB: 97% (9.7)
ProductC: 8.5% (.82)
ProductD: 100% (.82)
ProductE: 100% (.82)
ProductF: 24% (.2)
在这种情况下,前两个结果的得分非常相似,而接下来的三个结果得分相同但明显落后。这些数字显然不会与在线购物者共享,但 ProductC 和 ProductF 的低 相对 分数代表足够急剧的下降,您 可以 使用他们通知其他显示选项。也许 ProductA 和 ProductB 以比其他字体更大的字体显示。如果只有一种产品出现在急剧下降之前,它可能会得到更特别的突出显示。
我会警告不要在这种搜索中完全抑制相对得分较低的结果。正如您已经在示例中证明的那样,相对分数可能会产生误导,除非您的相关性得到很好的调整,否则最相关的文档可能并不总是最合适的。如果由于单个记录碰巧重复搜索词足够多次以获得出色的分数而导致期望的结果丢失,这对您没有好处,这是一个真正的威胁。
For example,
"Hamilton Beach Three-In-One Convection Toaster Oven"
will match one in eight words against a search fortoaster
, while"ToastMaster Toast Toaster Toasting Machine TOASTER"
will match as many as five in seven words depending on how you index. (Both product names are completely made up, but I wanted the second one to look less reputable.)
此外,所有返回的文档都是匹配项,无论它们的分数可能有多低。有时排名较低的结果是用户真正想要的黑马发现。用户将 不会 理解除了他们看到的之外还有匹配的文档,除非你告诉他们,所以你可能会在 "page 2" 上或在剪切后面隐藏尾随结果,但你可能不想阻止他们。让用户了解他们的结果集的大小也可以帮助他们决定如何微调他们的搜索。使用分数的显着下降作为分页的阈值可能非常有趣,但可能是一个具有挑战性的实现。
问题是,你如何确定你的截止点,它是什么意思?
看个例子可能更容易。假设我正在尝试按姓氏查找人员。我要搜索:
- "smithfield"
我有以下文件,我认为它们都非常匹配:
- smithfield - 完全匹配
- smithfielde - 非常接近,听起来很像,只有一个(无声)字母偏离
- smythfield - 非常接近,听起来很像,一个元音变了
- smithfelt - 几个字母不一样,但仍然很接近并且听起来很相似
- snithfield - 不太像,但只差一个字母。可能打错了。
- smittfield - 同样,听起来不太像,可能是打字错误或拼写错误
- smythfelt - 拼写有点不对,但可能是听错了
- smithfieldings - 相同的前缀
所以,我有四件事需要匹配。精确匹配要保证得分最高,我们要前缀匹配、模糊匹配、音似匹配。因此,让我们搜索:
smithfield smithfield* smithfield~2 metaphone:sm0flt
结果
- 史密斯菲尔德::: 2.3430576
- 史密斯菲尔德::: 0.97367656
- 史密斯菲尔德::: 0.5657166
- 史密斯费尔特::: 0.50767094
< 10% - 未显示
- 斯尼菲尔德::: 0.2137136
- 斯密特菲尔德::: 0.2137136
- smythfelt ::: 0.0691447
- 史密斯菲尔德::: 0.041700535
我认为 smithfieldings 是一场不错的比赛,但离晋级还有很远的距离!还不到最大值的 2%,别说 10% 了!好的,让我们尝试提升
smithfield^4 smithfield*^2 smithfield~2 metaphone:sm0flt
结果
- 史密斯菲尔德::: 2.8812196
- 史密斯菲尔德::: 0.5907072
- 史密斯菲尔德::: 0.30413133
< 10% - 未显示
- 史密斯费尔特::: 0.2729258
- 斯尼菲尔德::: 0.11489322
- 斯密特菲尔德::: 0.11489322
- 史密斯菲尔德::: 0.044836726
- smythfelt ::: 0.037172448
更糟!
并且在生产中问题更严重。在现实世界中,您可能正在处理冗长的复杂查询和全文文档。字段长度、匹配重复次数、协调因素、提升和大量查询词,所有这些因素都会影响得分。
看到第一个结果的分数比第二个高一个数量级,这真的不是什么不寻常的事情,尽管第二个结果仍然是一个有意义、有趣的结果。无法保证分数的均匀分布,因此我们不知道 10% 的数字意味着什么。并且 lucene 的评分算法往往会在使差异变小和变大方面出错。
总是不好吗?我会说是的。在我看来,总有两个更好的选择。
1 - 用好的查询控制你的结果集。如果您很好地构建了查询,那么 that 将提供结果的截断值,这不是因为分数的任意截断值,而是因为它根本不会被计分。
2 - 如果您不想那样做,那么在那个任意点截断结果真的有什么好处吗?用户非常善于识别搜索结果何时偏离了深度。用户无法找到他们想要的东西是一个严重的烦恼。只要顺序正确,显示太多结果通常不是问题。