python实现关联算法_关联分析:Apriori算法的python实现

关联分析

关联分析:关联分析是在大规模数据集中有目的的寻找关系的任务。

关联分析要寻找的关系:频繁项集、关联规则。

支持度:数据集中包含该项集的记录所占的比例。例如商品购买记录集合中,购买铅笔的订单占总订单数10%,则{铅笔}项集的支持度为10%。即$$P({铅笔})=0.1$$

置信度或可信度:定义为条件概率。例如对于{尿布}-->{葡萄酒}的关联规则,这条规则的可信度被定义为“支持度({尿布,葡萄酒})/支持度({尿布})”,即“购买尿布的客户中购买葡萄酒的概率”。

频繁项集:经常一起出现的项目的集合,定义为支持度大于某一阈值的集合。$$P(某集合)>c$$

关联规则:置信度大于一定阈值的关系。例如对于{尿布}-->{葡萄酒}这一关系,如果购买尿布的客户中购买葡萄酒的概率大于一定阈值,则这一关系被称为关联规则。

注意:关联规则是单向的。

Apriori原理

仍然以购买商品为例,对于有$N$件商品的超市,顾客所有可能的数据组合共$$\sum_{i=1}^NC_N^i = (1+1)^N-1=2^N-1$$种组合,如果要遍历需要很长时间。

Apriori基于这样一个原理,如果集合A不是频繁项集,那么所有以集合A为子集的集合均不是频繁项集。

使用Apriori算法发现频繁项集

Apriori算法的两个输入参数是数据集和最小支持度(阈值)。其流程如下:

1)生成单个物品的所有项集,遍历所有交易记录,筛选出单个商品的频繁项集。

2)对于包含k件商品的频繁项集,两两组合生成k+1项项集,删除非频繁项集,获得k+1频繁项集直到算法收敛。

3)返回频繁项集列表。

下面是代码实现:

#生成一项候选集

def Creat_C1(item_set):

"""

item_set是订单的集合,即由各个订单中购买商品类型的集合组成的集合。

"""

C1=[]

for i in item_set:

for j in i:

if {j} not in C1:

C1.append(frozenset({j}))

return C1

#计算候选集集的支持度并选出k项频繁集

def Fre_Support_cal(D,Ck,minSupport):

"""

输入:

D:数据集合

Ck:k项候选集

minSupport:最小支持度

输出:

Freq_listk:k项频繁集

support_data_dictk:k项频繁集的支持度

"""

support_count_dictk={}

for raw in D:

for item_set in Ck:

if item_set.issubset(raw):

if item_set not in support_count_dictk:

support_count_dictk[item_set] = 1

else:

support_count_dictk[item_set] += 1

num_all = len(D)

support_data_dictk={}

Freq_listk = []

for key in support_count_dictk:

support = support_count_dictk[key]/num_all

support_data_dictk[key] = support

if support >= minSupport:

Freq_listk.append(key)

return Freq_listk,support_data_dictk

#由k-1项频繁集生成k项候选集

def Creat_Ck(Freq_listk_1,k):

Ck = []

for i in range(len(Freq_listk_1)):

for j in range(i+1,len(Freq_listk_1)):

if len(Freq_listk_1[i]-Freq_listk_1[j])==1:

if frozenset(Freq_listk_1[i]|Freq_listk_1[j]) not in Ck:

Ck.append(frozenset(Freq_listk_1[i]|Freq_listk_1[j]))

return Ck

#生成频繁集

def apriori(dataset,minSupport):

C1 = Creat_C1(dataset)

Freq_list1,support_data_dict1= Fre_Support_cal(dataset,C1,minSupport)

k = 2

Freq_listk_1=Freq_list1

Freq_list = []

support_data_dict = {}

Freq_list.extend(Freq_list1)

support_data_dict.update(support_data_dict1)

while k<= len(dataset):

Ck= Creat_Ck(Freq_listk_1,k)

Freq_listk,support_data_dictk = Fre_Support_cal(dataset,Ck,minSupport)

Freq_list.extend(Freq_listk)

support_data_dict.update(support_data_dictk)

k+=1

Freq_listk_1=Freq_listk

return Freq_list,support_data_dict

#测试代码

dataset = [[1, 3, 4],[2, 3, 5],[1, 2, 3, 5],[2, 5]]

Fre_list,support_dict = apriori(dataset,0.5)

Fre_list,support_dict

([frozenset({1}),

frozenset({3}),

frozenset({2}),

frozenset({5}),

frozenset({1, 3}),

frozenset({2, 3}),

frozenset({3, 5}),

frozenset({2, 5}),

frozenset({2, 3, 5})],

{frozenset({1}): 0.5,

frozenset({3}): 0.75,

frozenset({4}): 0.25,

frozenset({2}): 0.75,

frozenset({5}): 0.75,

frozenset({1, 3}): 0.5,

frozenset({2, 3}): 0.5,

frozenset({3, 5}): 0.5,

frozenset({2, 5}): 0.75,

frozenset({1, 2}): 0.25,

frozenset({1, 5}): 0.25,

frozenset({2, 3, 5}): 0.5,

frozenset({1, 2, 3}): 0.25,

frozenset({1, 3, 5}): 0.25})

从频繁项集中挖掘关联规则

对于一个 $N$ 项频繁项集,可能的频繁项集组合共:$$\sum_{i=1}^{N-1}C_N^i = 2^N-2$$种关联组合。

同样的依据Apriori原理,对于一个频繁项集$A=(X_1,X_2,\cdots,X_N)$,关系$B\longrightarrow C$,其中$B=(X_1,X_2,\cdots,X_k)$,$C=(X_{k+1},X_{k+2},\cdots,X_N)$,并未构成关联规则,即$$P(C|B)=\frac {P(BC)}{P(B)}=\frac {P(X_1,X_2,\cdots,X_N)}{P(X_1,X_2,\cdots,X_k)}P(B)$$且$$P(BC)=P(DE)$$故$$P(E|D)

对于一个N项繁项集,我们可以按照以下流程挖掘关联规则:

1)获得N项频繁集的$(N-1)\longrightarrow 1$项关系,删除不达到阈值的关系,获得关联规则。

2)对于每一$(N-k)\longrightarrow k$项关系,获得$(N-k-1)\longrightarrow (k-1)$关系,获得关联规则。

3)循环直到结束。

代码实现如下:

#关联规则

def association_rules(freq_list, support_data_dict, min_conf):

rules = []

length = len(freq_list)

for i in range(length):

for j in range(i+1,length):

if freq_list[i].issubset(freq_list[j]):

frq = support_data_dict[freq_list[j]]

conf = support_data_dict[freq_list[j]] / support_data_dict[freq_list[i]]

rule = (freq_list[i],freq_list[j]- freq_list[i], frq, conf)

if conf >= min_conf:

print(freq_list[i],"-->",freq_list[j] - freq_list[i],'frq:',frq,'conf:',conf)

rules.append(rule)

return rules

#测试代码

association_rules(Fre_list,support_dict,0.5)

frozenset({1}) --> frozenset({3}) frq: 0.5 conf: 1.0

frozenset({3}) --> frozenset({1}) frq: 0.5 conf: 0.6666666666666666

frozenset({3}) --> frozenset({2}) frq: 0.5 conf: 0.6666666666666666

frozenset({3}) --> frozenset({5}) frq: 0.5 conf: 0.6666666666666666

frozenset({3}) --> frozenset({2, 5}) frq: 0.5 conf: 0.6666666666666666

frozenset({2}) --> frozenset({3}) frq: 0.5 conf: 0.6666666666666666

frozenset({2}) --> frozenset({5}) frq: 0.75 conf: 1.0

frozenset({2}) --> frozenset({3, 5}) frq: 0.5 conf: 0.6666666666666666

frozenset({5}) --> frozenset({3}) frq: 0.5 conf: 0.6666666666666666

frozenset({5}) --> frozenset({2}) frq: 0.75 conf: 1.0

frozenset({5}) --> frozenset({2, 3}) frq: 0.5 conf: 0.6666666666666666

frozenset({2, 3}) --> frozenset({5}) frq: 0.5 conf: 1.0

frozenset({3, 5}) --> frozenset({2}) frq: 0.5 conf: 1.0

frozenset({2, 5}) --> frozenset({3}) frq: 0.5 conf: 0.6666666666666666

[(frozenset({1}), frozenset({3}), 0.5, 1.0),

(frozenset({3}), frozenset({1}), 0.5, 0.6666666666666666),

(frozenset({3}), frozenset({2}), 0.5, 0.6666666666666666),

(frozenset({3}), frozenset({5}), 0.5, 0.6666666666666666),

(frozenset({3}), frozenset({2, 5}), 0.5, 0.6666666666666666),

(frozenset({2}), frozenset({3}), 0.5, 0.6666666666666666),

(frozenset({2}), frozenset({5}), 0.75, 1.0),

(frozenset({2}), frozenset({3, 5}), 0.5, 0.6666666666666666),

(frozenset({5}), frozenset({3}), 0.5, 0.6666666666666666),

(frozenset({5}), frozenset({2}), 0.75, 1.0),

(frozenset({5}), frozenset({2, 3}), 0.5, 0.6666666666666666),

(frozenset({2, 3}), frozenset({5}), 0.5, 1.0),

(frozenset({3, 5}), frozenset({2}), 0.5, 1.0),

(frozenset({2, 5}), frozenset({3}), 0.5, 0.6666666666666666)]

你可能感兴趣的:(python实现关联算法)