关联规则(Association Rules)学习

关联规则(Association Rules)是反映一个事物与其他事物之间的相互依存性和关联性,是数据挖掘的一个重要技术,用于从大量数据中挖掘出有价值的数据项之间的相关关系。

常见的购物篮分析

该过程通过发现顾客放人其购物篮中的不同商品之间的联系,分析顾客的购买习惯。通过了解哪些商品频繁地被顾客同时购买,这种关联的发现可以帮助零售商制定营销策略。其他的应用还包括价目表设计、商品促销、商品的排放和基于购买模式的顾客划分。

可从数据库中关联分析出形如“由于某些事件的发生而引起另外一些事件的发生”之类的规则
频繁项集评估标准

常用的频繁项集的评估标准有支持度,置信度和提升度三个

    支持度:几个关联的数据在数据集中出现的次数占总数据集的比重

    置信度:一个数据出现后,另一个数据出现的概率,或者说数据的条件概率。

    提升度:表示含有Y的条件下,同时含有X的概率,与X总体发生的概率之比

 
Apriori算法----发现频繁项集的一种方法

原理:如果一个项集是频繁项集,则它的所有子集都是频繁项集

           如果一个集合不是频繁项集,则它的所有父集(超集)都不是频繁项集

关联分析的目标:

    发现频繁项集:发现满足最小支持度的所有项集
    发现关联规则:从频繁项集中提取所有高置信度的规则

Apriori算法采用了迭代的方法

    先搜索出候选1项集及对应的支持度,剪枝去掉低于支持度的1项集,得到频繁1项集。
    对剩下的频繁1项集进行连接,得到候选的频繁2项集,筛选去掉低于支持度的候选频繁2项集,得到真正的频繁二项集,
    以此类推,迭代下去,直到无法找到频繁k+1项集为止,对应的频繁k项集的集合即为算法的输出结果

下图来自博客:https://www.cnblogs.com/pinard/p/6293298.html

算法流程

输入:数据集合D,支持度阈值αα

输出:最大的频繁k项集

1)扫描整个数据集,得到所有出现过的数据,作为候选频繁1项集。k=1,频繁0项集为空集。

2)挖掘频繁k项集

a) 扫描数据计算候选频繁k项集的支持度

b) 去除候选频繁k项集中支持度低于阈值的数据集,得到频繁k项集。如果得到的频繁k项集为空,则直接返回频繁k-1项集的集合作为算法结果,算法结束。如果得到的频繁k项集只有一项,则直接返回频繁k项集的集合作为算法结果,算法结束。

c) 基于频繁k项集,连接生成候选频繁k+1项集。

3) 令k=k+1,转入步骤2。
代码实现

    # Apriori算法
    """
    由于Apriori算法假定项集中的项是按字典序排序的,而集合本身是无序的,所以我们在必要时需要进行set和list的转换;
    由于要使用字典(support_data)记录项集的支持度,需要用项集作为key,而可变集合无法作为字典的key,因此在合适时机应将项集转为固定集合frozenset。
    支持度
    置信度
    """
     
     
    class apriori_algorithm:
     
        # 算法初始化
        def __init__(self, minSupport, dataSet):
            self.minSupport = minSupport  # 最小支持度
            self.dataSet = dataSet  # 数据集
     
        # 加载数据集
        def loaddata(self):
            return [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]
     
        # 生成单个物品的项集列表
        def generateC1(self, dataSet):
            C1 = []  # 用于存放生成的单个物品的项集列表
            # 遍历数据集
            for data in dataSet:
                for item in data:
                    if [item] not in C1:
                        C1.append([item])
            C1.sort()
            return C1
     
        # 遍历数据集,和Ck对比,计数
        def generateLk_by_Ck(self, dataSet, Ck, minSupport, support_data):
            """
               Generate Lk by executing a delete policy from Ck.
               Args:
                   data_set: 数据集
                   Ck: A set which contains all all frequent candidate k-itemsets.
                   min_support: The minimum support.
                   support_data: A dictionary. The key is frequent itemset and the value is support.
               Returns:
                   Lk: A set which contains all all frequent k-itemsets.
               """
            D = map(set, dataSet)
            C = map(frozenset, Ck)
            C1 = list(C)  # 关于map对象的遍历,在内循环中遍历完最后一个元素后,再次访问时会放回空列表,所以外循环第二次进入的时候是空的,需要将其转为list处理
            countData = dict()
            for d in D:  # set遍历
                for c in C1:
                    if c.issubset(d):  # 子集判断,并非元素判断
                        if c not in countData.keys():  # 将集合作为字典的键使用,c为[]型
                            countData[c] = 1
     
                        else:
                            countData[c] += 1
     
            numItems = float(len(list(dataSet)))
            returnList = []
            supportData = dict()
            # 遍历前面得到的计数字典
            for key in countData:
                support = countData[key] / numItems
                if support >= minSupport:
                    returnList.insert(0, key)  # insert() 函数用于将指定对象插入列表的指定位置
                    support_data[key] = support
     
            return returnList
     
        def generate_L(self, dataSet, k, min_support):
            """
               Generate all frequent itemsets.
               Args:
                   data_set:数据集
                   k: 频繁项集中含有的最多的元素
                   min_support: 最小支持度
               Returns:
                   L: 出现的所有频繁项集
                   support_data: 每个频繁项集对应的支持度
               """
            support_data = {}
            C1 = self.generateC1(dataSet)
            L1 = self.generateLk_by_Ck(dataSet, C1, min_support, support_data)
            Lksub1 = L1.copy()
     
            L = []
            L.append(Lksub1)
     
            for i in range(2, k + 1):
                Ci = self.generateCK(Lksub1, i)
                Li = self.generateLk_by_Ck(dataSet, Ci, min_support, support_data)
                Lksub1 = Li.copy()
                L.append(Lksub1)
            return L, support_data
     
        # generateCK 候选频繁项集产生   参数 Lk频繁项集,k:项集元素个数
        def generateCK(self, Lk, k):
            Ck = set()
            len_Lk = len(list(Lk))
            list_Lk = list(Lk)
            for i in range(len_Lk):
                for j in range(1, len_Lk):
                    l1 = list(list_Lk[i])
                    l2 = list(list_Lk[j])
                    l1.sort()
                    l2.sort()
                    if l1[0:k - 2] == l2[0:k - 2]:
                        Ck_item = list_Lk[i] | list_Lk[j]
                        if self.isCk(Ck_item, list_Lk):
                            Ck.add(Ck_item)
                        # Ck.add(Ck_item)
            return Ck
     
        # 频繁项集判断
     
        def isCk(self, Ck_item, list_Lk):
            for item in Ck_item:
                sub_Ck = Ck_item - frozenset([item])
                if sub_Ck not in list_Lk:
                    return False
            return True
     
        # 生成关联规则
        def generate_big_rules(self, L, support_data, min_conf):
            """
            Generate big rules from frequent itemsets.
            Args:
                L: 所有频繁项集的列表
                support_data: 每个频繁项集对应的支持度
                min_conf: 最小可信度
            """
            big_rule_list = []
            sub_set_list = []
            for i in range(0, len(L)):
                for freq_set in L[i]:
                    for sub_set in sub_set_list:
                        if sub_set.issubset(freq_set):
                            conf = support_data[freq_set] / support_data[freq_set - sub_set]
                            big_rule = (freq_set - sub_set, sub_set, conf)
     
                            if conf >= min_conf and big_rule not in big_rule_list:
                                print(freq_set - sub_set, " => ", sub_set, "conf: ", conf)
                                big_rule_list.append(big_rule)
                    sub_set_list.append(freq_set)
            return big_rule_list
     
     
    if __name__ == '__main__':
        minS = 0.5
        dataSet = [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]
        apriori = apriori_algorithm(minSupport=minS, dataSet=dataSet)
     
        L, support_data = apriori.generate_L(dataSet, 3, minS)
     
        print(L)
        print(support_data)
        big_rule_list = apriori.generate_big_rules(L, support_data, 0.7)

结果:

    所有的频繁项集L:
     
    [[frozenset({5}), frozenset({2}), frozenset({3}), frozenset({1})], [frozenset({2, 5}), frozenset({2, 3}), frozenset({3, 5}), frozenset({1, 3})], [frozenset({2, 3, 5})]]
    所有频繁项集对应的支持度:
     
    {frozenset({1}): 0.5, frozenset({3}): 0.75, frozenset({2}): 0.75, frozenset({5}): 0.75, frozenset({1, 3}): 0.5, frozenset({3, 5}): 0.5, frozenset({2, 3}): 0.5, frozenset({2, 5}): 0.75, frozenset({2, 3, 5}): 0.5}
    生成关联规则:
     
    frozenset({2})  =>  frozenset({5}) conf:  1.0
    frozenset({5})  =>  frozenset({2}) conf:  1.0
    frozenset({1})  =>  frozenset({3}) conf:  1.0
    frozenset({2, 3})  =>  frozenset({5}) conf:  1.0
    frozenset({3, 5})  =>  frozenset({2}) conf:  1.0

参考文献:

https://www.jianshu.com/p/469dff109fae,

https://www.cnblogs.com/pinard/p/6293298.html,

https://www.cnblogs.com/llhthinker/p/6719779.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值