是否可以在 mysql 语句中运行先验关联规则?

Posted

技术标签:

【中文标题】是否可以在 mysql 语句中运行先验关联规则?【英文标题】:Is it possible to run apriori association rule in mysql statement? 【发布时间】:2011-03-05 10:30:28 【问题描述】:

数据库:

Transacation#   Items List
T1              butter
T1              jam
T2              butter
T3              bread
T3              ice cream
T4              butter
T4              jam

在上表中, 是否可以在mysql语句中运行先验关联规则?

比如buys(T, butter)的支持-->buys(T, jam) = 50%

因为有 4 笔交易,T1、T4 满足“支持”规则。

我可以用一条sql语句来找出这样的结果吗?

【问题讨论】:

我不明白你是如何得到 50% 的。你能写一个你想要计算的算法吗?如果您愿意,可以使用伪代码。 【参考方案1】:

是的,您可以使用 SQL 来查找单个项目的支持。但是如果你想找到包含多个项目的项目集,那就很难了。

例如,如果您的交易包含多个项目,并且您想找到“牛奶”和“面包”一起出现的“果酱”的支持,那么最好使用 Apriori 之类的算法,或者更快的算法比如FPGrowth。

【讨论】:

【参考方案2】:

您提供的样本数据达到了 66%? “黄油”有 3 笔交易,其中只有 2 笔交易包含“果酱”。

我使用了下面的测试表。

create table transactions(
   trans_no     varchar(5)  not null
  ,item         varchar(20) not null
  ,primary key(trans_no, item)
);

insert into transactions(trans_no, item)
values ('T1', 'butter')
      ,('T1', 'jam')
      ,('T2', 'butter')
      ,('T3', 'bread')
      ,('T3', 'ice cream')
      ,('T4', 'butter')
      ,('T4', 'jam');

以下是我尝试的答案。内部选择查找所有包含“黄油”的交易。对于每个这样的交易,它还设置一个标志(bought_jam),说明该交易是否还包括“jam”。 (having 子句不包括包含“jam”但不包含“butter”的交易)。 在外层选择中,我基本上对所有行进行计数(计数对应于包括黄油在内的事务数),并对 jam flag 求和,对应于包括黄油和 jam 的事务数。

select sum(bought_jam) as jams_bought
      ,count(*) as num_trans
      ,100 * sum(bought_jam) / count(*) as correlation_pct
  from (select trans_no
              ,max(case when item = 'jam' then 1 else 0 end) as bought_jam
          from transactions
         where item in('butter', 'jam')
         group 
            by trans_no
        having min(case when item = 'butter' then item end) = 'butter'
       ) butter_trans;

上面的查询给出以下结果:

+-------------+-----------+-----------------+
| jams_bought | num_trans | correlation_pct |
+-------------+-----------+-----------------+
|           2 |         3 |         66.6667 |
+-------------+-----------+-----------------+
1 row in set (0.00 sec)

让我知道这对你有什么影响。

编辑: 以下查询将给出相同的结果,但更容易阅读。但是,如果 transactions 表非常大,并且 item = x 的选择性不是很高(返回很多行),那么这个查询几乎肯定会变慢。

select count(t2.trans_no) as jams_bought
      ,count(*) as num_trans
      ,count(t2.trans_no) / count(*) as correlation_pct
  from transactions t1
  left join transactions t2 on(t2.trans_no = t1.trans_no and t2.item = 'jam')
 where t1.item = 'butter';

【讨论】:

以上是关于是否可以在 mysql 语句中运行先验关联规则?的主要内容,如果未能解决你的问题,请参考以下文章

R中使用先验函数的关联规则

r 关联规则先验

如何为关联规则分析使用一个热编码数据帧(先验)

我们如何才能找到对规则的先验支持和信心?

关联规则——Apriori算法

如何在垃圾邮件过滤中嵌入带有朴素贝叶斯分类器的关联规则?