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

时间:2011-03-05 10:30:29

标签: mysql apriori

数据库:

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

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

例如,购买支持(T,黄油) - >买(T,果酱)= 50%

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

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

2 个答案:

答案 0 :(得分:1)

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

例如,如果您有包含多个项目的交易,并且您希望找到“jam”支持“milk”和“bread”一起出现,那么最好使用像Apriori这样的算法,或者更快的算法像FPGrowth。

答案 1 :(得分:0)

我提供的样本数据达到66%? " butter"有3笔交易,其中只有2笔" jam"。

我使用了以下测试表。

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');

以下是我尝试回答的问题。内部选择查找包含" butter"的所有交易。对于每个这样的交易,它还设置一个标志(buy_jam),说明该交易是否还包括" jam"。 (有条款不包括包含" jam"但不包括" butter")的交易。
在外部选择中,我基本上计算所有行(计数对应于包括黄油的交易数量),并将果酱标记相加,其对应于包括黄油和果酱的交易数量。

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)

让我知道这对你有用。

修改
以下查询将给出相同的结果,但更容易阅读。但是,如果事务表非常大,并且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';