好吧,我有一个存储两个键的关系,一个产品ID和一个属性Id。我想弄清楚哪种产品与给定产品最相似。 (属性实际上是数字,但它使示例更加混乱,因此它们已被更改为字母以简化视觉表示。)
Prod_att
Product | Attributes
1 | A
1 | B
1 | C
2 | A
2 | B
2 | D
3 | A
3 | E
4 | A
最初看起来相当简单,只需选择产品所具有的属性,然后计算每个产品共享的属性数。然后将结果与产品的属性数量进行比较,我可以看到两种产品的相似程度。这适用于相对于其比较产品具有大量属性的产品,但是当产品具有非常少的属性时会出现问题。例如,产品3几乎可以与其他所有产品相关联(因为A很常见)。
SELECT Product, count(Attributes)
FROM Prod_att
WHERE Attributes IN
(SELECT Attributes
FROM prod_att
WHERE Product = 1)
GROUP BY Product
;
有关如何修复此问题或改进当前查询的任何建议? 谢谢!
*编辑:产品4将为所有产品返回count()= 1。我想展示产品3更相似,因为它具有更少的不同属性。
答案 0 :(得分:2)
试试这个
SELECT
a_product_id,
COALESCE( b_product_id, 'no_matchs_found' ) AS closest_product_match
FROM (
SELECT
*,
@row_num := IF(@prev_value=A_product_id,@row_num+1,1) AS row_num,
@prev_value := a_product_id
FROM
(SELECT @prev_value := 0) r
JOIN (
SELECT
a.product_id as a_product_id,
b.product_id as b_product_id,
count( distinct b.Attributes ),
count( distinct b2.Attributes ) as total_products
FROM
products a
LEFT JOIN products b ON ( a.Attributes = b.Attributes AND a.product_id <> b.product_id )
LEFT JOIN products b2 ON ( b2.product_id = b.product_id )
/*WHERE */
/* a.product_id = 3 */
GROUP BY
a.product_id,
b.product_id
ORDER BY
1, 3 desc, 4
) t
) t2
WHERE
row_num = 1
以上query
获取所有产品的closest matches
,您可以在最里面的查询中添加product_id
,以获取特定product_id
的结果,I已使用LEFT JOIN
,以便即使product
没有匹配项,也会显示
希望这有帮助
答案 1 :(得分:0)
试试"Lower bound of Wilson score confidence interval for a Bernoulli parameter"。当你有一个小n时,这明确地处理统计信心的问题。它看起来像是很多数学,但实际上这是你需要做的最小数学量才能做到这一点。该网站解释得非常好。
这假设可以从正/负评分到匹配/不匹配属性的问题。
以下是积极和消极评分和95%CL的例子:
SELECT widget_id, ((positive + 1.9208) / (positive + negative) -
1.96 * SQRT((positive * negative) / (positive + negative) + 0.9604) /
(positive + negative)) / (1 + 3.8416 / (positive + negative))
AS ci_lower_bound FROM widgets WHERE positive + negative > 0
ORDER BY ci_lower_bound DESC;
答案 2 :(得分:0)
您可以编写一个小视图,它将为您提供两个产品之间的总共享属性。
create view vw_shared_attributes as
select a.product,
b.product 'product_match',
count(*) 'shared_attributes'
from your_table a
inner join test b on b.attribute = a.attribute and b.product <> a.product
group by a.product, b.product
然后使用该视图选择最匹配。
select product,
(select top 1 s.product_match from vw_shared_attributes s where t.product = s.product order by s.shared_attributes desc)
from your_table t
group by product