zoukankan      html  css  js  c++  java
  • Apriori算法的原理与python 实现。

    前言:这是一个老故事, 但每次看总是能从中想到点什么.在一家超市里,有一个有趣的现象:尿布和啤酒赫然摆在一起出售。但是这个奇怪的举措却使尿布和啤酒的销量双双增加了。这不是一个笑话,而是发生在美国沃尔玛连锁店超市的真实案例,并一直为商家所津津乐道。原来,美国的妇女们经常会嘱咐她们的丈夫下班以后要为孩子买尿布。而丈夫在买完尿布之后又要顺手买回自己爱喝的啤酒,因此啤酒和尿布在一起购买的机会还是很多的。 是什么让沃尔玛发现了尿布和啤酒之间的关系呢?正是商家通过对超市一年多原始交易数字进行详细的分析,才发现了这对神奇的组合。 无独有偶。美国密执安州有一家名为"阿汉"的小餐馆有个异常奇特的做法:经常光顾该餐馆的顾客, 只要愿意,便可报上自己的常住地址,在客户登记簿上注册,开一个"户头",以后顾客每次到这里来就餐,餐馆都会如实地在其户头上记下用餐款额。每年的9月30日,餐馆便会按客户登记簿上的记载算出每位顾客从上年9月30日以来在餐馆的消费总额,然后再按餐馆纯利10%的比例算出每位顾客应得的利润分发给顾客,这样,餐馆自然就常常门庭若市。阿汉餐馆给顾客分红的方法虽然损失了一部分纯利,但却使顾客感到自己与餐馆的利润息息相关,自己也是餐馆的一员。这样一来,餐馆密切了与消费者的关系,吸引了许多回头客。 这种让食客成为"股东"的做法其实也是一种"组合"式的生意之道,不同的是前者是明显的"物质组合",而后者是隐蔽的"人员组合",两者都是以消费者心甘情愿地付出而给老板带来了滚滚利润,何乐而不为呢?

    上面的例子我们不讨论他的经营之道,我们来挖掘其中用到的技术思想。

    一:关联分析

    我们一般去网点或者店里购物,一般都会有这样的购物清单吧。

    有的人说,这种有什么用?那再来看看这个:

    这是我随便找的一家网店的超值搭配。你会说这有什么联系吗?

    假如,我是这个店长,我分析了我店里的历史数据,看见衣服1和裤子2被同一个顾客购买的可能性很大。那我是不是可以在我的店里搭配这两个套餐,同时也可以在给点击衣服1的人推荐我的裤子2,说不定,这个人看上了裤子2,又感觉与衣服1搭配还挺合适的,那么就会把这两件都买下来,商家在这次的购物行为中就赚了一笔。

    那可能,你会问,小的数据集我可能很快就分析出来了,假如我的店很大,有很多物品。类似于天猫超市那样的,我怎样才能找到他们的关联项呢?不会让我穷尽所有操作吧。那么下面我们来介绍Apriori帮助店长解决这个繁琐的问题。

    二 :Apriori算法

    先介绍两个概念:

    支持度:用于表示给定数据集的频繁程度。公式: 分子为X与Y同

            时出现的概率,N为整个数据的个数。

    置信度:Y在包含X的事物中出现的频繁程度。公式:

    项集:一个购物篮中任意的商品组合就是一个项集(包括单独的一个,但是项集不能出现重复的商品)

    频繁项集:出现的项集大于一个人为设置的阀值,我们称之为频繁项集。

    三:算法过程

        先通过偏离数据库得到一个项集(也就是一个商品),然后计算他的支持度,如果小于某一个阀值则删除,大于则保留,然后组合求2两个项的项集的支持度。低于阀值则去掉,高于阀值则保留。用上面的用以上步骤重复处理新得到的频繁项集合, 直到没有频繁项集合产生。其中候选项集产生的过程被分为连接与剪技两个部分。 采用这种方式, 使得所有的频繁项集既不会遗漏又不会重复。 为提高频繁项集逐层产生的效率, Apriori算法利用了两个重要的性质用于压缩搜索空间。

    性质 1  k维数据项目集 X是频繁项目集的必要条件是它的所有 k-1维子集均是频繁项目集。

    性质 2  若 k维项目集 X中有 (k-1)维子集不是频繁项集, 则 X不是频繁项集

    四:算法的python实现

    本算法和数据来自机器学习实战。

    '''
    Created on Mar 24, 2011
    Ch 11 code
    @author: Peter
    '''
    from numpy import *

    def loadDataSet():
    return [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]

    def createC1(dataSet):
    C1 = []
    for transaction in dataSet:
    for item in transaction:
    if not [item] in C1:
    C1.append([item])

    C1.sort()
    return map(frozenset, C1)#use frozen set so we
    #can use it as a key in a dict

    def scanD(D, Ck, minSupport):
    ssCnt = {}
    for tid in D:
    for can in Ck:
    if can.issubset(tid):
    if not ssCnt.has_key(can): 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

    def aprioriGen(Lk, k): #creates Ck
    retList = []
    lenLk = len(Lk)
    for i in range(lenLk):
    for j in range(i+1, lenLk):
    L1 = list(Lk[i])[:k-2]; L2 = list(Lk[j])[:k-2]
    L1.sort(); L2.sort()
    if L1==L2: #if first k-2 elements are equal
    retList.append(Lk[i] | Lk[j]) #set union
    return retList

    def apriori(dataSet, minSupport = 0.5):
    C1 = createC1(dataSet)
    D = map(set, dataSet)
    L1, supportData = scanD(D, C1, minSupport)
    L = [L1]
    k = 2
    while (len(L[k-2]) > 0):
    Ck = aprioriGen(L[k-2], k)
    Lk, supK = scanD(D, Ck, minSupport)#scan DB to get Lk
    supportData.update(supK)
    L.append(Lk)
    k += 1
    return L, supportData

    def generateRules(L, supportData, minConf=0.7): #supportData is a dict coming from scanD
    bigRuleList = []
    for i in range(1, len(L)):#only get the sets with two or more items
    for freqSet in L[i]:
    H1 = [frozenset([item]) for item in freqSet]
    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 = [] #create new list to return
    for conseq in H:
    conf = supportData[freqSet]/supportData[freqSet-conseq] #calc confidence
    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)): #try further merging
    Hmp1 = aprioriGen(H, m+1)#create Hm+1 new candidates
    Hmp1 = calcConf(freqSet, Hmp1, supportData, brl, minConf)
    if (len(Hmp1) > 1): #need at least two sets to merge
    rulesFromConseq(freqSet, Hmp1, supportData, brl, minConf)

    def pntRules(ruleList, itemMeaning):
    for ruleTup in ruleList:
    for item in ruleTup[0]:
    print itemMeaning[item]
    print " -------->"
    for
    item in ruleTup[1]:
    print itemMeaning[item]
    print "confidence: %f" % ruleTup[2]
    print #print a blank line

    因为Apriori算法比较简单,也没什么好说的,有时会要结合具体硬件进行改进,也可以通过数据的存储形式进行改变。

    在这里说一下,那个阿汉餐馆为每个人开个账户我们是不是可以根据他的消费习惯,给他推荐一些相似的餐品。这就用到我们的推荐算法了,哈哈。

  • 相关阅读:
    怎么查看京东店铺的品牌ID
    PPT编辑的时候很卡,放映的时候不卡,咋回事?
    codevs 1702素数判定2
    codevs 2530大质数
    codevs 1488GangGang的烦恼
    codevs 2851 菜菜买气球
    hdu 5653 Bomber Man wants to bomb an Array
    poj 3661 Running
    poj 1651 Multiplication Puzzle
    hdu 2476 String Painter
  • 原文地址:https://www.cnblogs.com/xiaohuahua108/p/6259639.html
Copyright © 2011-2022 走看看