精华内容
下载资源
问答
  • 关联分析学习算法篇Apriori

    千次阅读 2018-09-02 22:19:02
    早些时候写过关于购物篮分析的文章,其中提到了C5.0和Apriori算法,没有仔细说说这算法的含义,昨天写了一下关联分析的理论部分,今天说说关联分析算法之一的Apriori算法,很多时候大家都说,数据分析师更多的是会用...

    小白学数据分析----->关联分析学习算法篇Apriori

    早些时候写过关于购物篮分析的文章,其中提到了C5.0和Apriori算法,没有仔细说说这算法的含义,昨天写了一下关联分析的理论部分,今天说说关联分析算法之一的Apriori算法,很多时候大家都说,数据分析师更多的是会用就可以了,不必纠结于那些长篇累牍的理论,其实我觉得还是有点必要的,你未必要去设计算法,但是如果你掌握和熟知一个算法,这对于你如何驾驭和使用这个算法是很有帮助的,此外每个算法都有使用的局限性,比如空间和时间复杂度,使用条件约束。最典型的就是我们难道一份原始数据,然后经过数据处理要进行算法模拟分析,但是此时你会出现一个问题,我需要处理哪些数据,如何处理?而这就需要你对你所使用的算法必须熟悉,比如能够操作的数据格式,类型。比如GRI算法要求使用的数据必须是事实表的方式存储,这样的算法特点必须建立在对于算法的了解把握层次上。

    Apriori算法

    其名字是因为算法基于先验知识(prior knowledge).根据前一次找到的频繁项来生成本次的频繁项。Apriori是关联分析中核心的算法。

    Apriori算法的特点

    只能处理分类变量,无法处理数值型变量;

    数据存储可以是交易数据格式(事务表),或者是事实表方式(表格数据);

    算法核心在于提升关联规则产生的效率而设计的。

    Apriori的思想

    正如我们之前所提到的,我们希望置信度和支持度要满足我们的阈值范围才算是有效的规则,实际过程中我们往往会面临大量的数据,如果只是简单的搜索,会出现很多的规则,相当大的一部分是无效的规则,效率很低,那么Apriori就是通过产生频繁项集,然后再依据频繁项集产生规则,进而提升效率。

    以上所说的代表了Apriori算法的两个步骤:产生频繁项集和依据频繁项集产生规则。

    那么什么是频繁项集?

    频繁项集就是对包含项目A的项目集C,其支持度大于等于指定的支持度,则C(A)为频繁项集,包含一个项目的频繁项集称为频繁1-项集,即L1。

    为什么确定频繁项集?

    刚才说了,必须支持度大于我们指定的支持度,这也就是说能够确定后面生成的规则是在普遍代表性上的项目集生成的,因为支持度本身的高低就代表了我们关联分析结果是否具有普遍性。

    怎么寻找频繁项集?

    这里不再讲述,直接说一个例子大家就都明白了。例子来源于Fast Algorithms for Mining Association Rules

    Apriori寻找频繁项集的过程是一个不断迭代的过程,每次都是两个步骤,产生候选集Ck(可能成为频繁项集的项目组合);基于候选集Ck计算支持度,确定Lk。

    Apriori的寻找策略就是从包含少量的项目开始逐渐向多个项目的项目集搜索。

    数据如下:

    我们看到,数据库存储的数据格式,会员100购买了 1 3 4三种商品,那么对应的集合形式如右边的图所示。那么基于候选集C1,我们得到频繁项集L1,如下图所示,在此表格中{4}的支持度为1,而我们设定的支持度为2。支持度大于或者等于指定的支持度的最小阈值就成为L1了,这里{4}没有成为L1的一员。因此,我们认定包含4的其他项集都不可能是频繁项集,后续就不再对其进行判断了。

     

     

    此时我们看到L1是符合最低支持度的标准的,那么下一次迭代我们依据L1产生C2(4就不再被考虑了),此时的候选集如右图所示C2(依据L1*L1的组合方式)确立。C2的每个集合得到的支持度对应在我们原始数据组合的计数,如下图左所示。

     

    此时,第二次迭代发现了{1 2} {1 5}的支持度只有1,低于阈值,故而舍弃,那么在随后的迭代中,如果出现{1 2} {1 5}的组合形式将不被考虑。

     

    如上图,由L2得到候选集C3,那么这次迭代中的{1 2 3} { 1 3 5}哪去了?如刚才所言,{1 2} {1 5}的组合形式将不被考虑,因为这两个项集不可能成为频繁项集L3,此时L4不能构成候选集L4,即停止。

    如果用一句化解释上述的过程,就是不断通过Lk的自身连接,形成候选集,然后在进行剪枝,除掉无用的部分。

    根据频繁项集产生简单关联规则

    Apriori的关联规则是在频繁项集基础上产生的,进而这可以保证这些规则的支持度达到指定的水平,具有普遍性和令人信服的水平。

    以上就是Apriori的算法基本原理,留了两个例子,可以加深理解。

    例子1:

    例子2:

     

     

     

    展开全文
  • 关联分析算法

    千次阅读 2014-10-16 11:14:33
    关联分析算法
    关联分析算法
        关联分析算法的应用非常广泛,它可以在大规模数据集中找出一组有关联的数据。例如:商品分析中,我们可以分析出哪些商品之间有购买的关联,也就是买了其中一个商品之后,顾客就很有可能买另外一个商品。
        频繁项集是指那些经常出现在一起的物品集合,那么如何评价这里的频繁程度呢?我们用支持度和可信度(置信度)来评价。一个项集的支持度指数据集中包含该项集的记录所占的比例,置信度为一个关联规则中这个关联成立的概率。举例来说:

    从图中可以看出:
    • 项集{豆奶}的支持度为4/5,项集{豆奶,尿布}的支持度为3/5,项集{尿布,葡萄酒}的支持度为3/5,项集{尿布}的支持度为4/5, 这样看来一个项集支持度的计算方法一目了然;
    • 关联规则{尿布->葡萄酒}的可信度等于:支持度({尿布,葡萄酒})/支持度({尿布})=3/4。

        但是,当物品的数据量增大的时候,使用上述遍历的方法是可以找到所有的可信度较高的关联规则,但是需要遍历的次数也是非常庞大的。此时出现了Apriori算法。
       需要注意的是,Apriori算法的作用只是发现一个数据集中哪些项集是频繁的。关联分析的目标处理发现频繁项集之外,还需要从它们中间获得关联规则。不过对于关联分析而言,发现频繁项集是主要的工作,之后的关联规则则计算每个规则的可信度即可。
        Apriori算法的原理:如果某个项集是频繁的,那么它的所有子集也是频繁的;如果某个项集不是频繁的,那么它的所有子集也是非频繁的。利用这样的原理,我们便可以大幅度减少计算项集的个数。因为如果能推断出该项集不是频繁的,那么就没有必要计算其支持度和可信度了。《机器学习实战》中给出了一个很好的图示来解释Apriori的作用:

        Apriori算法是发现频繁项集的一种方法。该算法的输入参数有两个:数据集和最小支持度。最小支持度一定要有,因为大于最小支持度的项集才能被认为是频繁项集。
         Apriori算法的过程:首先,我们会生成所有单个物品的项集列表,接着扫描交易记录来查看哪些项集满足最小支持度的要求,哪些不满足最小支持度的集合会被去掉,对剩下来的集合进行组合以生成包含两个元素的项集。接下来,再重新扫描交易记录,去掉不满足要求的项集。重复该过程直到生成了一个包含所有元素的项集。
        在找到了数据集中所有的频繁项集之后,我们需要从这些频繁项集中发现关联规则。就一个频繁项集中就可以产生好多个规则,所以如何减小需要计算规则的数量也是很重要的。这里我们可以借鉴Apriori的思想,如果某条规则不满足最小可信度的要求,那么该规则的所有子集也不会满足最小可信度的要求。
        比如,在频繁项集{0, 1, 2, 3}中,我们发现0,1,2->3规则不满足最小支持度的要求,那么我们就可以知道1,2->0,3, 01->23, 02->13, 0->123, 1->023, 2->013都不是关联的规则了。这样就减小了很多规则的判断。

        
        




    展开全文
  • 关联分析概念 关联分析是从大量数据中发现项集之间有趣的关联和相关联系。 •定义: 1、事务:每一条交易称为一个事务,如上图包含5个事务。 2、项:交易的每一个物品称为一个项,例如豆奶,啤酒等。  3、项...

    •1.关联分析概念

    关联分析是从大量数据中发现项集之间有趣的关联和相关联系。

     

    •定义:
    1、事务:每一条交易称为一个事务,如上图包含5个事务。
    2、项:交易的每一个物品称为一个项,例如豆奶,啤酒等。 
    3、项集:包含零个或多个项的集合叫做项集,例如{尿布,啤酒}。
    4、k−项集:包含k个项的项集叫做k-项集,例如 {豆奶,橙汁}叫做2-项集。
    5、支持度计数:一个项集出现在几个事务当中,它的支持度计数就是几。例如{尿布, 啤酒}出现在事务002、003和005中,所以           它的支持度计数是3。
    6、支持度:支持度计数除于总的事务数。例如上例中总的事务数为5,{尿布, 啤酒}的支持度计数为3,所以它的支持度是                       3÷5=60%,说明有60%的人同时买了尿布, 啤酒。

    7、频繁项集:支持度大于或等于某个阈值的项集就叫做频繁项集。例如阈值设为50%时,因为{尿布,啤酒}的支持度是60%,所以        它是频繁项集。
    8、前件和后件:对于规则{尿布}→{啤酒},{Diaper}叫做前件,{啤酒}叫做后件。
    9、置信度:对于规则{尿布}→{啤酒},{尿布,啤酒}的支持度计数除于{尿布}的支持度计数,为这个规则的置信度。

           例如规则{尿布}→{啤酒}的置信度为3÷3=100%。说明买了尿布的人100%也买了 啤酒。

    10、强关联规则:大于或等于最小支持度阈值和最小置信度阈值的规则叫做强关联规则。

    •频繁项集(frequent item sets)是经常出现在一块儿的物品的集合.

    •关联规则(association rules)暗示两种物品之间可能存在很强的关系。

    •1)支持度

    •Surpport(A->B)= P(AB)  ,支持度表示事件A 和事件B 同时出现的概率。

    •2)置信度

    •Confidence(A->B) = P(B/A) = P(AB)/ P(A) ,置信度表示 A 事件出现时,B 事件出现的概率。

    •关联分析的最终目标就是要找出强关联规则。

     

    •2.Apriori算法原理

    •Apriori算法是一种最有影响的挖掘布尔关联规则频繁项集的算法。算法的名字基于这样的事实:算法使用频繁项集性质的先验知识,正如我们将看到的。Apriori使用一种称作逐层搜索的迭代方法,k-项集用于探索(k+1)-项集。首先,找出频繁1-项集的集合。该集合记作L1。L1 用于找频繁2-项集的集合L2,而L2 用于找L3,如此下去,直到不能找到频繁k-项集。找每个Lk需要一次数据库扫描。

     

    先验定理:如果一个项集是频繁的,则它的所有子集一定也是频繁的。

    如图所示,假定{c,d,e}是频繁项集。显而易见,任何包含项集{c,d,e}的事务一定包含它的子集{c,d},{c,e},{d,e},{c},{d}和{e}。这样,如果{c,d,e}是频繁的,则它的所有子集一定也是频繁的。

    如果项集{a,b}是非频繁的,则它的所有超集也一定是非频繁的。即一旦发现{a,b}是非频繁的,则整个包含{a,b}超集的子图可以被立即剪枝。这种基于支持度度量修剪指数搜索空间的策略称为基于支持度的剪枝。 


    这种剪枝策略依赖于支持度度量的一个关键性质,即一个项集的支持度绝不会超过它的子集的支持度。这个性质也称支持度度量的反单调性

    参考博客有很详细的例子。

    Apriori算法 
    优点:易编码实现。’ 
    缺点:在大数据集上可能较慢。 
    适用数据类型:数值型或者标称型数据。

    3.算法实现:

    #coding=gbk
    # apriori算法的实现
    def load_dataset(): #定义数据集
        return [[1,3,4],[2,3,5],[1,2,3,5],[2,5]]
    
    def create_C1(dataSet): #得到数据集中的每个数据,且进行排序
        C1 =[]
        for transantion in dataSet:
            for item in transantion:
                if not [item] in C1:
                    C1.append([item])   #储存 I1, I2,。。需要使其不重复
        C1.sort()
        #use frozen set so we can use it as a key in a dict
        #应该输出 1,2,3,4,5
        return list(map(frozenset, C1))  #  将C1中的每个集合映射为frozenset,之后可以作为字典的键,
    
    dataSet = load_dataset()
    ck = create_C1(dataSet)
    print(ck)        # 输出:[frozenset({1}), frozenset({2}), frozenset({3}), frozenset({4}), frozenset({5})]
    
    #测试代码
    # # map(function, sequence)
    # c2 = [[2,4],[5,8],[3]]
    # c2.sort()
    # a = list(map(frozenset, c2))
    # print(a)    #[frozenset({2, 4}), frozenset({3}), frozenset({8, 5})]
    # print(a[0]) # frozenset({2, 4})
    
    # Apriori算法首先构建集合 C1 ,然后扫描数据集判断这些只有一个元素的项集是否满足最小支持度的要求。那些满足最低要求的项集构成集合 L1 。
    # 而 L1 中的元素相互组合构成 C2 , C2 再进一步过滤变为 L2 。
    
    #该函数使 C1 生成L1,ck为全部的数据项
    def scanD(D, Ck, minSupport):   #参数D 为数据集, Ck为候选项列表, 最小支持度
        ssCnt= {}       #存储数据项1,2,。。及其出现的次数
        
        for tid in D:       #遍历数据集
            for can in Ck:  #遍历候选项 1,2,3,4,5,
                if can.issubset(tid):   #判断候选项是否含数据集中的各项
                    if not can in ssCnt:
                        ssCnt[can] =1
                    else:
                        ssCnt[can]+=1   #有则进行加一操作,   1,2,3,4,5 的数据项的个数, 为了计算支持度
        numItems = float(len(D))    #计算数据集大小
        retList = []        #使L1 初始化, 保存大于最小支持度的数据项
        supportData = {}    #使用字典记录支持度
        for key in ssCnt:
            support = ssCnt[key]/ numItems  #求得支持度
            if support >= minSupport:       #如果支持度大于用户给的最小支持度, 对小于的数据项进行去除。
                retList.insert(0,  key) #保存到列表中
            else:
                supportData[key]= support   #输出去除项的支持度
        return retList, supportData
    
    #测试:
    r, s = scanD(dataSet, ck, 0.5)
    print(r)    #[frozenset({1}), frozenset({3}), frozenset({2}), frozenset({5})]
    print(s)    #{frozenset({4}): 0.25}

    数据集为:总共有4 分

    1, 3, 4
    2, 3, 5
    1, 2, 3, 5
    2, 5
    C1 出现次数
    1) 2
    2) 3
    3) 3
    4) 1
    5) 3

    4)的支持度为 1/4 为 0.25  < 0.5  = minSupport  ,所以将其舍去

    整个Apriori算法的伪代码如下:

    当集合中项的个数大于0时:
        构建一个k个项组成的候选项集的列表
        检查数据以确认每个项集都是频繁的
        保留频繁项集并构建k+1项组成的候选项集的列表(向上合并)

    #Apriori 算法实现
    # 输入参数为 频繁项集列表 Lk 与  项集元素个数 k , 输出为 Ck 
    def aprioriGen(Lk, k):  
        retList = []
        lenLk = len(Lk) 
        for i in range(lenLk):
            for j in range(i+1, lenLk): #两两组合遍历 (1,2,3,5)
                L1 = list(Lk[i])[:k-2]  
                L2 = list(Lk[j])[:k-2]  #用列表储存 k-2 项的项集
                L1.sort(); L2.sort()
                if L1 == L2:
                    retList.append(Lk[i] | Lk[j])   #若2个集合的前 k-2 个项相同时, 则将两个集合合并
        return retList
    
    def apriori(dataSet, minSupport =0.5):
        C1 = create_C1(dataSet)
        D = list(map(set, dataSet))
        L1, supportData = scanD(D, C1, minSupport)  #生成L1
        L =[L1]
        k =2 
        while (len(L[k-2]) > 0):        #创建 包含更多的项集的列表, 直到下一个项集为空 ,终止循环。 
            Ck = aprioriGen(L[k-2], k)
            Lk, supk = scanD(D, Ck, minSupport) #再次在数据库上扫描一遍
            supportData.update(supk)
            L.append(Lk)        #在1 -项集上增加 2-项集 
            k +=1
        return L, supportData 
    
    a= [1,2,3]
    a.append([[12],[13],[16]])
    print(a)    #[1, 2, 3, [[12], [13], [16]]]
    
    #apriori 测试
    print('------apriori test -------')
    dataSet = load_dataset()
    L, supportData = apriori(dataSet)
    
    print(L)#[[frozenset({1}), frozenset({3}), frozenset({2}), frozenset({5})], [frozenset({3, 5}), frozenset({1, 3}), 
    # frozenset({2, 5}), frozenset({2, 3})], [frozenset({2, 3, 5})], []]
    
    print(L[0]) #  [frozenset({1}), frozenset({3}), frozenset({2}), frozenset({5})]
    print(L[1]) #  [frozenset({3, 5}), frozenset({1, 3}), frozenset({2, 5}), frozenset({2, 3})]
    print(L[2]) #[frozenset({2, 3, 5})]
    print(L[3]) # [] 频繁项集为空, 所以的出频繁项集 为{2,3,5} 
    
    #查看全部项集的支持度
    print(supportData)  # 部分输出:{frozenset({5}): 0.75, frozenset({3}): 0.75, frozenset({2, 3, 5}): 0.5,

    函数 aprioriGen() 的输入参数为频繁项集列表 Lk 与项集元素个数 k ,输出为 Ck 。举例来说,该函数以{0}、{1}、{2}作为输入,会生成{0,1}、{0,2}以及{1,2}。要完成这一点,首先创建一个空列表,然后计算 Lk 中的元素数目。通过循环来比较 Lk 中的每一个元素与其他元素,紧接着,取列表中的两个集合进行比较。如果这两个集合的前面 k-2 个元素都相等,那么就将这两个集合合成一个大小为 k 的集合 。这里使用集合的并操作来完成。

    apriori函数首先创建 C1 然后读入数据集将其转化为 D (集合列表)来完 
    成。程序中使用 map 函数将 set() 映射到 dataSet 列表中的每一项。scanD() 函数来创建 L1 ,并将 L1 放入列表 L 中。 L 会包含 L1 、 L2 、 L3 …。现在有了 L1 ,后面会继续找 L2 , L3 …,这可以通过 while 循环来完成,它创建包含更大项集的更大列表,直到下一个大的项集为空。Lk 列表被添加到 L ,同时增加 k 的值,增大项集个数,重复上述过程。最后,当 Lk 为空时,程序返回 L 并退出。

    参考blog

    从频繁项中挖掘关联规则

    #从频繁项集中挖掘关联规则
    
    #产生关联规则
    #参数为 L 为频繁项集, supportData 为全部项集的支持度, mincof 设置最小的置信度为 0.7
    def generateRules(L, supportData, minconf = 0.7):
        bigRuleList = []    #存储所有的关联规则
        for i in range(1,len(L)):   #只获取2 个或更多项集
            for freqSet in L[i]:
                #遍历L 中每一个频繁项集,对每个项集创建值包含单个元素的 列表 
                H1 = [frozenset([item]) for item in freqSet]
                #如果频繁项集数目超过2 个, 就对其进行进一步的合并
                if (i>1 ):
                    rulesFromConseq(freqSet, H1, supportData, bigRuleList, minconf)
                else:
                    #第一层时, 后件数为1
                    calcConf(freqSet, H1, supportData, bigRuleList, minconf)
        return bigRuleList
        
    #生成候选规则集合: 计算规则的置信度,以及找到满足最小置信度的规则
    def calcConf(freqSet, H1, supportData, brl, minconf=0.7):
        #针对项集只有2 个元素时, 计算置信度
        prunedH = []    #返回一个满足最小置信度的规则列表
        for conseq in H1:       #遍历H 中的所有项集, 并计算它们的置信度
            conf =  supportData[freqSet] / supportData[freqSet-conseq]  #计算置信度
            if conf >= minconf:     ##满足最小置信度要求, 则打印
                print(freqSet-conseq, '-->', conseq,'conf:', conf)
                brl.append((freqSet - conseq, conseq, conf))
                prunedH.append(conseq)
        return prunedH
        
    #进行合并
    def rulesFromConseq(freqSet, H1, supportData, brl, minconf = 0.7):
        #参数:freqSet是频繁项, H 是可以出现在规则右边的列表  
        m = len(H1[0])
        if (len(freqSet) > (m+1)):  #如果 频繁项集元素数目大于单个集合的元素数      
            Hmp1 = aprioriGen(H1, m+1)  #  合并具有相同部分的集合
            Hmp1 = calcConf(freqSet, Hmp1, supportData, brl, minconf)   #计算置信度
            if (len(Hmp1) > 1):
                #使用递归进一步组合
                rulesFromConseq(freqSet, Hmp1, supportData, brl, minconf)
    
    #测试关联规则输出  
    print()
    print('-------generateRules test-------')      
    rules = generateRules(L, supportData, minconf=0.5)    
    print(rules)
    # -------generateRules test-------
    # frozenset({5}) --> frozenset({3}) conf: 0.6666666666666666
    # frozenset({3}) --> frozenset({5}) conf: 0.6666666666666666
    # frozenset({3}) --> frozenset({1}) conf: 0.6666666666666666
    # frozenset({1}) --> frozenset({3}) conf: 1.0
    # frozenset({5}) --> frozenset({2}) conf: 1.0
    # frozenset({2}) --> frozenset({5}) conf: 1.0
    # frozenset({3}) --> frozenset({2}) conf: 0.6666666666666666
    # frozenset({2}) --> frozenset({3}) conf: 0.6666666666666666
    # frozenset({5}) --> frozenset({2, 3}) conf: 0.6666666666666666
    # frozenset({3}) --> frozenset({2, 5}) conf: 0.6666666666666666
    # frozenset({2}) --> frozenset({3, 5}) conf: 0.6666666666666666
    # [(frozenset({5}), frozenset({3}), 0.6666666666666666),。。。。。。。

     

    4.FP-growth 算法原理:

    相比于apriori 算法, FP-growth 算法可高效发现 频繁项集 。

    FP-growth 算法例子可查看。

    python代码参考

     

    参考:https://blog.csdn.net/zhazhayaonuli/article/details/53322541

              https://www.cnblogs.com/qwertWZ/p/4510857.html

     

    项目推荐:

    2000多G的计算机各行业电子资源分享(持续更新)

    2020年微信小程序全栈项目之喵喵交友【附课件和源码】

    Spring Boot开发小而美的个人博客【附课件和源码】

    Java微服务实战296集大型视频-谷粒商城【附代码和课件】

    Java开发微服务畅购商城实战【全357集大项目】-附代码和课件

    最全最详细数据结构与算法视频-【附课件和源码】

    在这里插入图片描述

     

    展开全文
  • 数据挖掘十大算法(四):Apriori(关联分析算法

    万次阅读 多人点赞 2018-08-29 21:38:50
    同样的该算法也是在一堆数据集中寻找数据之间的某种关联,这里主要介绍的是叫做Apriori的‘一个先验’算法,通过该算法我们可以对数据集做关联分析——在大规模的数据中寻找有趣关系的任务,本文主要介绍使用Apriori...

    终于到了机器学习实战的第十一章了,这也是继K-均值后的第二个无监督学习算法了。同样的该算法也是在一堆数据集中寻找数据之间的某种关联,这里主要介绍的是叫做Apriori‘一个先验’算法,通过该算法我们可以对数据集做关联分析——在大规模的数据中寻找有趣关系的任务,本文主要介绍使用Apriori算法发现数据的(频繁项集、关联规则)。

    这些关系可以有两种形式:频繁项集、关联规则

            频繁项集:经常出现在一块的物品的集合

            关联规则:暗示两种物品之间可能存在很强的关系

    一个具体的例子:

    频繁项集是指那些经常出现在一起的物品,例如上图的{葡萄酒、尿布、豆奶},从上面的数据集中也可以找到尿布->葡萄酒的关联规则,这意味着有人买了尿布,那很有可能他也会购买葡萄酒。那如何定义和表示频繁项集和关联规则呢?这里引入支持度和可信度(置信度)。

    支持度:一个项集的支持度被定义为数据集中包含该项集的记录所占的比例,上图中,豆奶的支持度为4/5,(豆奶、尿布)为3/5。支持度是针对项集来说的,因此可以定义一个最小支持度,只保留最小支持度的项集。

    可信度(置信度):针对如{尿布}->{葡萄酒}这样的关联规则来定义的。计算为 支持度{尿布,葡萄酒}/支持度{尿布},其中{尿布,葡萄酒}的支持度为3/5,{尿布}的支持度为4/5,所以“尿布->葡萄酒”的可行度为3/4=0.75,这意味着尿布的记录中,我们的规则有75%都适用。

    有了可以量化的计算方式,我们却还不能立刻运算,这是因为如果我们直接运算所有的数据,运算量极其的大,很难实现,这里说明一下,假设我们只有 4 种商品:商品0,商品1,商品 2,商品3. 那么如何得可能被一起购买的商品的组合?

    上图显示了物品之间所有可能的组合,从上往下一个集合是 Ø,表示不包含任何物品的空集,物品集合之间的连线表明两个或者更多集合可以组合形成一个更大的集合。我们的目标是找到经常在一起购买的物品集合。这里使用集合的支持度来度量其出现的频率。一个集合出现的支持度是指有多少比例的交易记录包含该集合。例如,对于上图,要计算 0,3 的支持度,直接的想法是遍历每条记录,统计包含有 0 和 3 的记录的数量,使用该数量除以总记录数,就可以得到支持度。而这只是针对单个集合 0,3. 要获得每种可能集合的支持度就需要多次重复上述过程。对于上图,虽然仅有4中物品,也需要遍历数据15次。随着物品数目的增加,遍历次数会急剧增加,对于包含 N 种物品的数据集共有 2^N−1 种项集组合。为了降低计算时间,研究人员发现了 Apriori 原理,可以帮我们减少感兴趣的频繁项集的数目。

    Apriori 的原理:如果某个项集是频繁项集,那么它所有的子集也是频繁的。即如果 {0,1} 是频繁的,那么 {0}, {1} 也一定是频繁的。

    这个原理直观上没有什么用,但是反过来看就有用了,也就是说如果一个项集是非频繁的,那么它的所有超集也是非频繁的。如下图所示:

    频繁项集:

    主要步骤:

        首先会生成所有单个物品的项集列表
        扫描交易记录来查看哪些项集满足最小支持度要求,那些不满足最小支持度的集合会被去掉
        对剩下的集合进行组合以生成包含两个元素的项集
        接下来重新扫描交易记录,去掉不满足最小支持度的项集,重复进行直到所有项集都被去掉

    代码(代码中有详细注释):

    from numpy import *
    
    # 构造数据
    def loadDataSet():
        return [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]
    
    # 将所有元素转换为frozenset型字典,存放到列表中
    def createC1(dataSet):
        C1 = []
        for transaction in dataSet:
            for item in transaction:
                if not [item] in C1:
                    C1.append([item])
        C1.sort()
        # 使用frozenset是为了后面可以将这些值作为字典的键
        return list(map(frozenset, C1))  # frozenset一种不可变的集合,set可变集合
    
    # 过滤掉不符合支持度的集合
    # 返回 频繁项集列表retList 所有元素的支持度字典
    def scanD(D, Ck, minSupport):
        ssCnt = {}
        for tid in D:
            for can in Ck:
                if can.issubset(tid):   # 判断can是否是tid的《子集》 (这里使用子集的方式来判断两者的关系)
                    if can not in ssCnt:    # 统计该值在整个记录中满足子集的次数(以字典的形式记录,frozenset为键)
                        ssCnt[can] = 1
                    else:
                        ssCnt[can] += 1
        numItems = float(len(D))
        retList = []        # 重新记录满足条件的数据值(即支持度大于阈值的数据)
        supportData = {}    # 每个数据值的支持度
        for key in ssCnt:
            support = ssCnt[key] / numItems
            if support >= minSupport:
                retList.insert(0, key)
            supportData[key] = support
        return retList, supportData # 排除不符合支持度元素后的元素 每个元素支持度
    
    # 生成所有可以组合的集合
    # 频繁项集列表Lk 项集元素个数k  [frozenset({2, 3}), frozenset({3, 5})] -> [frozenset({2, 3, 5})]
    def aprioriGen(Lk, k):
        retList = []
        lenLk = len(Lk)
        for i in range(lenLk): # 两层循环比较Lk中的每个元素与其它元素
            for j in range(i+1, lenLk):
                L1 = list(Lk[i])[:k-2]  # 将集合转为list后取值
                L2 = list(Lk[j])[:k-2]
                L1.sort(); L2.sort()        # 这里说明一下:该函数每次比较两个list的前k-2个元素,如果相同则求并集得到k个元素的集合
                if L1==L2:
                    retList.append(Lk[i] | Lk[j]) # 求并集
        return retList  # 返回频繁项集列表Ck
    
    # 封装所有步骤的函数
    # 返回 所有满足大于阈值的组合 集合支持度列表
    def apriori(dataSet, minSupport = 0.5):
        D = list(map(set, dataSet)) # 转换列表记录为字典  [{1, 3, 4}, {2, 3, 5}, {1, 2, 3, 5}, {2, 5}]
        C1 = createC1(dataSet)      # 将每个元素转会为frozenset字典    [frozenset({1}), frozenset({2}), frozenset({3}), frozenset({4}), frozenset({5})]
        L1, supportData = scanD(D, C1, minSupport)  # 过滤数据
        L = [L1]
        k = 2
        while (len(L[k-2]) > 0):    # 若仍有满足支持度的集合则继续做关联分析
            Ck = aprioriGen(L[k-2], k)  # Ck候选频繁项集
            Lk, supK = scanD(D, Ck, minSupport) # Lk频繁项集
            supportData.update(supK)    # 更新字典(把新出现的集合:支持度加入到supportData中)
            L.append(Lk)
            k += 1  # 每次新组合的元素都只增加了一个,所以k也+1(k表示元素个数)
        return L, supportData
    
    dataSet = loadDataSet()
    L,suppData = apriori(dataSet)
    print(L)
    print(suppData)

    返回频繁项集与支持度

    上面代码获取数据的频繁项集,下面通过其他函数来获得关联规则。

    关联规则:

    # 获取关联规则的封装函数
    def generateRules(L, supportData, minConf=0.7):  # supportData 是一个字典
        bigRuleList = []
        for i in range(1, len(L)):  # 从为2个元素的集合开始
            for freqSet in L[i]:
                # 只包含单个元素的集合列表
                H1 = [frozenset([item]) for item in freqSet]    # frozenset({2, 3}) 转换为 [frozenset({2}), frozenset({3})]
                # 如果集合元素大于2个,则需要处理才能获得规则
                if (i > 1):
                    rulesFromConseq(freqSet, H1, supportData, bigRuleList, minConf) # 集合元素 集合拆分后的列表 。。。
                else:
                    calcConf(freqSet, H1, supportData, bigRuleList, minConf)
        return bigRuleList
    
    # 对规则进行评估 获得满足最小可信度的关联规则
    def calcConf(freqSet, H, supportData, brl, minConf=0.7):
        prunedH = []  # 创建一个新的列表去返回
        for conseq in H:
            conf = supportData[freqSet]/supportData[freqSet-conseq]  # 计算置信度
            if conf >= minConf:
                print(freqSet-conseq,'-->',conseq,'conf:',conf)
                brl.append((freqSet-conseq, conseq, conf))
                prunedH.append(conseq)
        return prunedH
    
    # 生成候选规则集合
    def rulesFromConseq(freqSet, H, supportData, brl, minConf=0.7):
        m = len(H[0])
        if (len(freqSet) > (m + 1)): # 尝试进一步合并
            Hmp1 = aprioriGen(H, m+1) # 将单个集合元素两两合并
            Hmp1 = calcConf(freqSet, Hmp1, supportData, brl, minConf)
            if (len(Hmp1) > 1):    #need at least two sets to merge
                rulesFromConseq(freqSet, Hmp1, supportData, brl, minConf)
    
    dataSet = loadDataSet()
    L,suppData = apriori(dataSet,minSupport=0.5)
    rules = generateRules(L,suppData,minConf=0.7)
    # rules = generateRules(L,suppData,minConf=0.5)
    print(rules)

    返回关联规则:

    上面的函数稍微有点复杂,因为使用的数据结构有点多,可能会搞混,所以下面说明一下函数意义。(由于我个人叙述可能不太清楚,所以这里引用作者的原话我觉得更好理解一点,稍微有点详细):

    以上便是引用作者对这三个函数的详细描述,在函数中的具体代码,我也有相关的注释,慢慢来应该能够理解的。

    下面对一个毒蘑菇的例子进行运算,检查一下在实际数据中的反应:

    第一个特征表示有毒或者可以使用。如果有毒则为2,可以食用为1。下一个特征蘑菇形状,有3-8六种可能,下面我们找出毒蘑菇中存在的公共特征:

    mushDatSet = [line.split() for line in open('mushroom.dat').readlines()]
    L,suppData = apriori(mushDatSet,minSupport=0.3)
    print(L)
    for item in L[1]:   # 只查看两个元素的集合
        if(item.intersection('2')): # intersection交集(选出毒蘑菇)
            print(item)

    输出了频繁项集和与毒蘑菇相关的特征:

    以上为Apriori算法构建模型的全部内容,该算法不仅适用于零售行业,同样适用于相同技术的其他行业,如网站流量分析以及医药行业等。

     

    参考书籍:《机器学习实战》

    展开全文
  • 关联分析之Apriori算法

    千次阅读 2017-11-08 14:03:41
    本文demo源码、实验数据:传送门引言如题,关联分析这个词语对于初学者而言或许比较陌生。但是我若将关联分析换成另一个短语“尿布与啤酒”大家就会很熟悉了。据报道,美国中西部的一家连锁店发现,男人们会在周四...
  • 数据关联规则分析算法

    千次阅读 2018-01-29 18:33:14
    数据关联规则(Associaton Rules,AR)是...1、基于Apriori算法关联分析 Apriori算法是关联规则分析中较为典型的频繁项集算法。 原理步骤: (1)对数据中每一项数据进行频率次数统计; (2)构成候选项集C1,计
  • Apriori算法--关联分析算法(一)

    万次阅读 多人点赞 2017-10-16 15:49:49
    在实际生产生活我们经常会遇到一些“关联分析”(Association Analyse)的任务。举几个实际例子。1.人们的购物清单里面的各个商品有没有什么关联呢?就像下面这个购物清单写的那样子,右边是各个顾客所买的东西。 有...
  • 使用最基础的Apriori算法。 import os import pandas as pd import numpy as np import sys from operator import itemgetter from collections import defaultdict 一、加载数据并观察 # 文件的后缀就是.data,...
  • 关联分析算法介绍以及案例实现

    千次阅读 2020-05-10 14:31:19
    关联分析又称关联挖掘:发现存在于大量数据集中的关联性或相关性,进行智能推荐。 事务 相当于用户的篮子,篮子里面可能是1项集,也可能是4项集。 项集 篮子里所有的物品构成一个集合。在关联分析中,包含0个或者多...
  • Apriori(关联分析算法

    千次阅读 2020-06-29 08:53:53
    同样的该算法也是在一堆数据集中寻找数据之间的某种关联,这里主要介绍的是叫做Apriori的‘一个先验’算法,通过该算法我们可以对数据集做关联分析——在大规模的数据中寻找有趣关系的任务,本文主要介绍使用Apriori...
  • 关联分析的Apriori算法 in Python

    千次阅读 2016-02-22 20:37:14
    关联分析的Apriori算法 in Python
  • 关联分析——Apriori算法

    千次阅读 2015-10-09 16:37:17
    关联分析:百度百科定义:又称关联挖掘,就是在交易数据、关系数据或其他信息载体中,查找存在于项目集合或对象集合之间的频繁模式、关联、相关性或因果结构。或者说,关联分析是发现交易数据库中不同商品(项)之间...
  • 一、关联分析的基本概念 关联分析(Association Analysis):在大规模数据集中寻找有趣的关系。 频繁项集(Frequent Item Sets):经常出现在一块的物品的集合。 关联规则(Association Rules):暗示两个物品...
  • 一个实例带你搞懂Apriori关联分析算法

    千次阅读 多人点赞 2020-05-31 16:13:01
    关联分析算法 关联分析是一种在大规模数据集中寻找有趣关系的任务。这些关系可以有两种形式:频繁项集或者关联规则。 附算法分析以及详细代码示例
  • Python --深入浅出Apriori关联分析算法(一) 这次呢,我们会在上次的基础上,讲讲如何分析物品的关联规则得出关联结果,以及给出用apyori这个库运行得出关联结果的代码。 一. 基础知识 上次我们介绍了几个关联分析...
  • Apriori算法关联分析与pyhon实现

    千次阅读 2014-11-05 22:23:56
    Apriori算法关联分析与pyhon实现,关联规则里面最基本算法 Apriori算法,关联规则生成。
  • 关联分析与FP-growth算法

    千次阅读 2016-04-12 19:18:09
    关联分析与FP-growth算法
  • Python关联分析之——Apriori算法

    万次阅读 2017-12-01 09:18:19
    使用Apriori算法进行关联分析Apriori原理 如果某个项集是频繁的,那么它的所有子集也是频繁的。即如果{0,1}是频繁的,则{0},{1}也是频繁的。 这个原理直观上并没有什么帮助,但如果反过来看,就有用了。 ...
  • 关联分析(一)--Apriori算法

    千次阅读 2018-12-29 13:52:41
    关联分析分为非时序关联分析和时序关联分析,其中非时序关联分析采用Apriori算法,利用先验知识产生频繁项集以及关联规则,而时序关联分析采用GSP算法。 Apriori算法 其名字是因为算法基于先验知识(prior ...
  • 典型关联分析(CCA)算法原理

    万次阅读 2015-07-24 16:13:43
    典型关联分析(CCA)算法原理、问题的提出、算法实现
  • Apriori算法实现关联分析

    千次阅读 2017-01-22 14:55:56
    摘要: 主要是讲解一些数据挖掘中频繁模式挖掘的Apriori算法原理应用实践 当我们买东西的时候,我们会发现物品展示方式是不同,购物以后优惠券...这种从大规模数据集中寻找物品间的隐含关系被称为关联分析或者关联规
  • 推荐算法-关联分析(关联规则)

    千次阅读 2018-06-16 09:58:51
    转载自 推荐算法-关联分析(关联规则)关联分析又称关联挖掘,就是在交易数据、关系数据或其他信息载体中,查找存在于项目集合或对象集合之间的频繁模式、关联、相关性或因果结构。或者说,关联分析是发现交易...
  • 关联分析是数据挖掘中的一种常用算法。它包括频繁项集挖掘和关联规则挖掘两个阶段。 频繁模式的挖掘有Apriori算法,还有FP-growth算法。下面的代码是利用Apriori算法挖掘频繁模式,然后找出关联规则的python实现。#...
  • 使用Apriori算法进行关联分析

    千次阅读 2020-07-31 08:38:42
    3.Apriori算法关联分析 4.代码实现 5.参考文章   通过组合交叉变量制定风控策略时有两种方法:一是通过决策树分箱进行变量交叉,可以见文章一个函数实现自动化风控策略挖掘;二是通过apriori算法进行关联分析。  ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 193,336
精华内容 77,334
关键字:

关联分析的经典算法