是否有一种最佳/有效的方法来比较多行的相似性/差异性?

时间:2017-08-14 15:14:02

标签: mysql sql database database-design

我试图将一个值列表与另一个值进行比较 - 目标是计算项目之间的总差异/相似度,并根据几个标准对项目进行评级,使其与彼此之间的相似程度,以摇摆为单位来自默认值(0)。

Criteria值仅在-8和+8之间变化(如果未指定则为NULL)。例如:

        Colour:     Flavour:    Temperature:
Item A:     -4              2               5
Item B:     3               0               3 
Item C:     2               -3              1

因此,计算项目A和C之间的差异:颜色(2 - -4)= -6,风味(-3 - 2)= -5,温度(1 - 5)= - 4。所以-6 + -5 + -4 =得分为15.假设ABS()用于在获得项目总分/分数之前标准化差异。我将通过省略一些数学来简化问题 - 这里的主要问题是获得每一行的得分和匹配的标准数量。

在查看我当前的解决方案之前,请先仔细考虑问题,以避免先入为主:http://sqlfiddle.com/#!9/11c0f/1

有没有更好的方法,我不知道?可能会有大约150个Criteria,并且需要按照彼此的相似性显示和排序多达几百个项目/行,这将是相当多的处理。

缓存这些昂贵查询的结果是给定的。这个问题更多的是差异/相似度计算本身 - 是否有一些深度SQL魔术可以比使用纯算术更有效地进行实际比较?如果需要,可以以另一种方式存储数据以便于处理。

还有一个问题 - 并非所有项目都将具有所有条件,如果没有适用,该字段将为NULL。

我故意省略了这个问题正文中的任何SQL,以避免预先观察观众的意见。我目前正在使用MySQL,但如果另一个系统提供了一种有效的方法来处理这个问题,那么这完全是可以改变的。

提前感谢您的体验和见解。

1 个答案:

答案 0 :(得分:0)

考虑将相似度计算封装到带有两个参数的函数中。假设此函数名为public override void LoadFailed(UIWebView webView, NSError error) { if (error.Code == -999) { // Show some alert or just ignore the error } } ,则可能的解决方案是:

similarity()

如果合适,您可以在select item_1, item_2, sum(sim) as similarity from ( select a.item_name as item_1, b.item_name as item_2, similarity(a.criteria_value, b.criteria_value) as sim from ourdata as a inner join ourdata as b on b.item_name > a.item_name and b.attribute_name = a.attribute_name ) as x group by item_1, item_2; 表而不是items_attributes表上运行此功能 - 我不清楚为什么它们的行数不同。