Apriori算法(原理步骤、Python实现、apyori库实现)

本文使用的源码以及数据集Data-Mining/Apriori at Stellaris.github.io · Stellaris123/Data-Mining

Apriori

​ Apriori 算法采用的策略是将数管来拿规则挖掘任务分为①产生频繁项集、②产生规则,两主要步骤。

详细步骤

一、产生频繁项集:从数据中发现满足最小支持度阈值的所有项集。

(1)确定数据集 D D D 中所包含的项集,并具体到每一个独立数据点(生成候选一项集)

(2)将候选集中每个项目单独进行扫描,根据支持度公式进行计算支持度,并筛掉不满足设定的最小支持度阈值的项。

(3)从 k − 1 k-1 k1项集生成候选 k k k 项集:判断 k − 1 k-1 k1 项集中每两个的项中是否满足两个项的 k − 2 k-2 k2 前缀是相同的,要是相同就表示可以构造(这是通过一个项满足支持则其子项也一定满足支持得出)。

(4)将候选 k k k 项集进行筛选,产生 k k k 项集。

(5)重复 3~4 步骤直到项集小于等于 1。

二、从产生的频繁项集中找出满足最小置信度阈值的规则。

(1)对于每个频繁项集,产生其所有的非空子集。

(2)对于每个非空子集,根据置信度公式进计算置信度,并筛掉不满足设定的最小置信度阈值的项。

(3)循环1~2步骤,直到挖出所有关联规则。

支持度和置信度

公式定义

S u p p o r t ( A ∩ B ) = S u p p o r t _ c o u n t ( A ∩ B ) s u m = A , B 同 时 发 生 的 事 物 个 数 所 有 事 物 个 数 C o n f i d e n c e ( A ⇒ B ) = P ( A ∣ B ) = S u p p o r t ( A ∩ B ) S u p p o r t ( A ) = S u p p o r t _ c o u n t ( A ∩ B ) S u p p o r t _ c o u n t ( A ) = A , B 同 时 发 生 的 事 物 个 数 发 生 A 的 事 物 个 数 Support(A\cap B)=\frac{Support\_count(A\cap B)}{sum}=\frac{A,B同时发生的事物个数}{所有事物个数} \\ Confidence(A\Rightarrow B)=P(A|B)=\frac{Support(A\cap B)}{Support(A)}=\frac{Support\_count(A\cap B)}{Support\_count(A)}=\frac{A,B同时发生的事物个数}{发生A的事物个数} Support(AB)=sumSupport_count(AB)=A,BConfidence(AB)=P(AB)=Support(A)Support(AB)=Support_count(A)Support_count(AB)=AA,B

数据例子

存在以下 9 9 9 条购物记录:1为选购,0为未选购。

abcde
01010
01100
11110
11000
01100
11000
11101
11100
10101

(1)支持度( A ∩ B A\cap B AB为例)

S u p p o r t _ c o u n t ( A ∩ B ) = 5 Support\_count(A\cap B) = 5 Support_count(AB)=5 s u m = 9 sum=9 sum=9,所以 S u p p o r t ( A ∩ B ) = S u p p o r t _ c o u n t ( A ∩ B ) s u m = 5 9 Support(A\cap B)=\frac{Support\_count(A\cap B)}{sum}=\frac{5}{9} Support(AB)=sumSupport_count(AB)=95

(2)置信度( A ⇒ B A\Rightarrow B AB为例)

S u p p o r t _ c o u n t ( A ∩ B ) = 5 Support\_count(A\cap B)=5 Support_count(AB)=5 S u p p o r t _ c o u n t ( A ) = 6 Support\_count(A)=6 Support_count(A)=6,所以 C o n f i d e n c e ( A ⇒ B ) = ⋯ = 5 6 Confidence(A\Rightarrow B)=\cdots=\frac{5}{6} Confidence(AB)==65

基于 Python 实现

Apriori类

class Apriori:
    """
    ---类名---
     Apriori
    ---数据成员---
     MIN_Support:    最小支持度
     MIN_Confidence: 最小置信度
     K_ItemSet:      k项集
     K_ItemSupprot:  k项集支持度
     rules:          规则
    ---方法---
     __init__(): 设置最小支持度和最小置信度(默认为0.5,0.5)
     init:       初始化,方便对象生成和调用不在一起
     get_candidate_one_set(): 获得候选第一项集
     get_k_itemset():     获得 k 项集
     sieve_itmeset():     筛选项集
     get_rules():         获取规则
     one_confidence():    计算并筛选规则
     more_confidence():   递归规则
     display_k_itemset(): 显示 k 项集
     display_rules():     显示规则
     run(): 运行入口
    """
    # 对象生成初始化
    def __init__(self, MIN_Support = 0.5, MIN_Confidence = 0.5):
        self.MIN_Support = MIN_Support
        self.MIN_Confidence = MIN_Confidence
        self.K_ItemSet = []
        self.K_ItemSupprot = []
        self.rules = []
    # 初始化
    def init(self):
        self.K_ItemSet = []
        self.K_ItemSupprot = []
        self.rules = []
    # 获得候选一项集
    def get_candidate_one_set(self, dataSet):
        one_set = []
        # 遍历添加
        for lst in dataSet:
            for item in lst:
                if not [item] in one_set:
                    one_set.append([item])
        # 排序
        one_set.sort()
        # 将列表冻结
        return list(map(frozenset, one_set))
    # 获得 K 项集
    def get_k_itemset(self, k_next, K):
        k_itemset = [] #K-项集
        # 两两组合
        for i in range(0,len(k_next)):
            for j in range(i+1,len(k_next)):
                # 判断前 k-2 项是否相同
                L1 = list(k_next[i])[:K-2]
                L2 = list(k_next[j])[:K-2]
                if L1==L2:
                    k_itemset.append(k_next[i]|k_next[j])
        return k_itemset
    # 筛选项集
    def sieve_itmeset(self, Data, itmeset):
        item_frequency = {}
        for item in Data:
            for element in itmeset:
                if element.issubset(item):
                    if not element in item_frequency:
                        item_frequency[element] = 1
                    else:
                        item_frequency[element] += 1
        
        numItems = float(len(Data)) #数据集中总的项集个数
        
        sieve_k_itemset = [] #频繁项集
        sieve_k_itemSupprot={} #项集中各项支持度
        for key in item_frequency:
            support = item_frequency[key]/numItems #支持度计算:元素出现次数 / 总项集数
            if support>=self.MIN_Support:  #满足最小支持度添加到频繁项集列表中
                sieve_k_itemset.insert(0, key)
                sieve_k_itemSupprot[key] = support
        return sieve_k_itemset, sieve_k_itemSupprot
    # 运行入口
    def run(self, dataSet):
        self.init()
        # 获取候选一项集
        candidate_one_set = self.get_candidate_one_set(dataSet)
        # 转换为字典
        Data = list(map(set, dataSet))
        # 过滤候选一项集
        sieve_one_set, self.K_ItemSupprot = self.sieve_itmeset(Data, candidate_one_set)
        # k=1的列表
        self.K_ItemSet = [[0], sieve_one_set]
        # 一直筛选直到小于等于 1 为止。
        K = 2
        while(len(self.K_ItemSet[K-1]) > 1):
            # 从 k-1 中构造候选 k 项集
            candidate_k_itemset = self.get_k_itemset(self.K_ItemSet[K-1], K)
            # 过滤候选 k 项集,并获取 k 项集支持度
            sieve_k_itemset, sieve_k_itemSupprot = self.sieve_itmeset(Data, candidate_k_itemset)
            
            # 更新项集
            self.K_ItemSupprot.update(sieve_k_itemSupprot)
            self.K_ItemSet.append(sieve_k_itemset)
            K += 1
        self.get_rules()
    # 获取规则
    def get_rules(self):
        self.rules = []
        # 将每一个分项集构造出关系
        for i in range(2, len(self.K_ItemSet)):
            for k_itemset in self.K_ItemSet[i]:
                fz_k_itemset = [frozenset([x]) for x in k_itemset]
                #print(fz_k_itemset)
                if(i > 2):
                    self.more_confidence(k_itemset,fz_k_itemset)
                else:
                    self.one_confidence(k_itemset,fz_k_itemset)
    # 计算并筛选规则
    def one_confidence(self, itemset, fz_k_itemset):
        #存储 fz_k_itemset 项中强关联规则
        item_realted = []
        for item in fz_k_itemset:
            # 计算置信度
            conf = self.K_ItemSupprot[itemset]/self.K_ItemSupprot[itemset - item]
            # 判断是否满足最小置信度
            if conf >= self.MIN_Confidence:
                self.rules.append((itemset - item, item, conf))
                item_realted.append(item)
        return item_realted                                                                                                                                      
    # 递归规则
    def more_confidence(self, itemset, fz_k_itemset):        
        if (len(itemset) > len(fz_k_itemset[0])+1):
            itemset_reunion = self.get_k_itemset(fz_k_itemset, len(fz_k_itemset[0]) + 1)
            # 计算置信度并过滤
            itemset_reunion_filtered = self.one_confidence(itemset, itemset_reunion)
            # 若存在强关联规则,递归组合计算置信度
            if(len(itemset_reunion_filtered) > 1):
                self.more_confidence(itemset, itemset_reunion_filtered)
    # 显示 k 项集
    def display_k_itemset(self):
        for k_itemset in self.K_ItemSet:
            print(k_itemset)
    # 显示规则
    def display_rules(self):
        for rule in self.rules:
            print(str(rule[0]) + " ---> " + str(rule[1]) + " Confidence:" + str(rule[2]))

调用

apriori = Apriori(MIN_Support=0.4, MIN_Confidence=0.5)
apriori.run(dataSet)
apriori.display_rules()
apriori.display_k_itemset()

基于 apyori 实现

from apyori import apriori
pd.DataFrame(apriori(transactions=dataSet, min_support=0.5, min_confidence=0.6))

附录(关于数据预处理)

​ 存在一张表,如下:(第一行是列号,忽略)

在这里插入图片描述

可以使用下面这个方法将这个 e x c e l excel excel 转化为需要的列表:

import numpy as np
import pandas as pd
data = pd.read_excel("./menu_orders.xls")

df = pd.DataFrame(list(map(lambda x:pd.Series(1, index = x[pd.notnull(x)]), data.values))).fillna(0)
#df = df[sorted(df.columns)]

dataSet = []
for i in range(0,df.shape[0]):
    dataSet.append([x for x in df.columns if df[x][i]])
print(dataSet)

执行结果:

[['b', 'd'], ['b', 'c'], ['a', 'b', 'c', 'd'], ['a', 'b'], ['b', 'c'], ['a', 'b'], ['a', 'b', 'c', 'e'], ['a', 'b', 'c'], ['a', 'c', 'e']]
  • 4
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值