使用Apriori算法进行关联分析(python2),python排序算法,summary:关联


summary:

关联分析是用于发现大数据集中元素间有趣关系的一个工具集,可以采用两种方式来量化这些有趣的关系。第一种方式是频繁项集,它会给出经常出现在一起的元素项;第二种方式是关联规则,每条关联规则意味着元素项之间“如果……那么”的关系。发现元素项间不同的组合是个十分耗时的任务,不可避免需要大量昂贵的计算资源,这就需要更智能的方法在合理时间范围内找到频繁项集。使用Apriori原理可以减少在数据库上进行检查的集合的数目。Apriori算法从单元素项集开始,通过组合满足最小支持度要求的项集来形成更大的集合。缺点:每次增加频繁集的大学,Apriori算法都会重新扫描整个数据集。准备数据:标称型或数值型数据类型都可以,因为我们只保存集合。
from numpy import *def loadDataSet():    return [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]dataSet=loadDataSet()dataSetdef createC1(dataSet): #生成只包含一个元素的项集的集合C1    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    C1=createC1(dataSet)C1D=map(set,dataSet)D#计算Ck的项集的在数据集D中的支持度support,并检查数据确保每个项集都是频繁的def scanD(D, Ck, minSupport):     """    D:Lst[frozenset]    Ck:Lst[frozenset]    minSupport:int    """    ssCnt = {} #统计Ck中的项在D中的项中出现的次数    for tid in D:        for can in Ck:            if can.issubset(tid): #如果can是tid的子集                ssCnt[can]=ssCnt.get(can,0)+1#            if can.issubset(tid):#                if not ssCnt.has_key(can): ssCnt[can]=1#                else: ssCnt[can] += 1    numItems = float(len(D)) #D中共有多少条记录    retList = []    supportData = {}    for key in ssCnt:        support = ssCnt[key]/numItems #计算支持度:数据集中包含该项集的记录所占的比例        if support >= minSupport:            retList.append(key)#            retList.insert(0,key)        supportData[key] = support    return retList, supportDataL1,suppData0=scanD(D,C1,0.5)print(L1)print(suppData0)def aprioriGen(Lk, k): #creates Ck:这里k表示一个项集中包含几个元素    """    Lk: List(frozenset)    """    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                """                判断Lk集合的前k-2个元素相同,然后将Lk[i],Lk[j]合并                这就能保证后面生成的L(k+1)集合中的项集中的元素个数为k+1                                这里k-2用于定位,举个栗子,当k=3,Lk=[{1,2},{1,3},{1,5},{2,3},{2,5},{3,5}]                此时就判断Lk[i][1]和Lk[][1]即项集的第1个元素是否相等来决定是否将它们合并                从而retList=[{1,2,3},{1,3,5},{1,2,5},{2,3,5}]                                若k=4,就判断Lk[i]和Lk[j]的前2个元素是否相等,                Lk是输入,所有项集的元素都是k-1个                因为我们要生成含有k个元素的所有项集的集合retList                所以需要前k-2个元素相等,最后一个元素不相等,这样合并起来刚好有k个元素                """    return retListdef apriori(dataSet, minSupport = 0.5):    C1 = createC1(dataSet)    D = map(set, dataSet)    L1, supportData = scanD(D, C1, minSupport)    L = [L1]    k = 2    #下面利用L(k-1)来构建L(k),并添加新支持度字典数据    while (len(L[k-2]) > 0): #当集合中项的个数大于0时        Ck = aprioriGen(L[k-2], k) #构建一个k个项组成的候选项集的列表        Lk, supK = scanD(D, Ck, minSupport)#scan DB to get Lk         supportData.update(supK) #将生成的新的支持度的字典添加进原来的包含支持度的字典中        L.append(Lk) #        k += 1 #k用于定位到相应的L的位置上,即当计算L2时定位到L[0],因为L[0]表示的是L1    return L, supportDataL,suppData=apriori(dataSet,minSupport = 0.5)print(L)print(suppData)aprioriGen(L[0], 2)L,suppData=apriori(dataSet,minSupport=0.7)print(L)print(suppData)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        i=2        for freqSet in L[i]:            H = [frozenset([item]) for item in freqSet]            if (i > 1):                rulesFromConseq(freqSet, H, supportData, bigRuleList, minConf)                """                当项集中的元素个数大于2时,调用rulesFromConseq                rulesFromConseq:                调用aprioriGen来生成conseq,便于生成不重复的关联规则                根据关联规则调用calcConf计算conf                """            else:                calcConf(freqSet, H, supportData, bigRuleList, minConf)                """                当项集中的元素个数等于2时,调用calcConf(筛选大于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 prunedHdef 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            #再对大于1个元素的频繁项集再细分计算关联规则            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 lineL,suppData=apriori(dataSet,minSupport = 0.5)rules=generateRules(L,suppData,minConf=0.7)

算法介绍

算法利用Apriori原理,第1步,得到频繁集(计算支持度);第2步,从频繁集中挖掘关联规则(计算可信度)。

支持度support:数据集中包含该项集的记录占总记录的比例,即用于度量一个集合在原始数据种出现的频率可信度confidence:一条规则P→H的可信度的计算公式为 support({P,H})/support({P})频繁集frequent item sets:是指经常出现在一块的物品的集合关联规则association rules:是指两个物品间可能存在很强的关系

Apriori原理是指,一个项集是频繁的,那么这个项集的子集也是频繁的;反过来,一个项集是非频繁的,那么包含这个项集的超级也是非频繁的。利用Apriori原理可以减少在数据库上进行检查的集合的数目。

应用于购物(比如关联分析中著名的例子是啤酒与尿布,说的是美国中西部的一家连锁店发现,男人们会在周四购买尿布和啤酒),还可以应用于搜索引擎中的查询词之间的关联规则。

示例:发现毒蘑菇的相似特征

mushroom.dat的前几行如下:

1 3 9 13 23 25 34 36 38 40 52 54 59 63 67 76 85 86 90 93 98 107 113
2 3 9 14 23 26 34 36 39 40 52 55 59 63 67 76 85 86 90 93 99 108 114
2 4 9 15 23 27 34 36 39 41 52 55 59 63 67 76 85 86 90 93 99 108 115
1 3 10 15 23 25 34 36 38 41 52 54 59 63 67 76 85 86 90 93 98 107 113
2 3 9 16 24 28 34 37 39 40 53 54 59 63 67 76 85 86 90 94 99 109 114

第1个特征的值为1和2分别表示有毒和无毒 。下一个特征是蘑菇伞的形状,有六种可能的值,分别用整数3-8表示。

为了找到毒蘑菇中存在的公共特征,可以运用Apriori算法来寻找包含特征值为2的频繁项集。

mushDatSet=[line.split() for line in open(‘mushroom.dat‘).readlines()]L,suppData=apriori.apriori(mushDatSet,minSupport=0.3)for item in L[1]:    if item.intersection(‘2‘):print(item) #查看与特征值2相交的item
结果如下:
frozenset([‘2‘, ‘59‘])frozenset([‘39‘, ‘2‘])frozenset([‘2‘, ‘67‘])frozenset([‘2‘, ‘34‘])frozenset([‘2‘, ‘23‘])frozenset([‘2‘, ‘86‘])frozenset([‘76‘, ‘2‘])frozenset([‘90‘, ‘2‘])frozenset([‘2‘, ‘53‘])frozenset([‘93‘, ‘2‘])frozenset([‘63‘, ‘2‘])frozenset([‘2‘, ‘28‘])frozenset([‘2‘, ‘85‘])frozenset([‘2‘, ‘36‘])

接下来你需要观察这些特征,以便了解毒蘑菇的哪些方面,如果看到其中任何一个特征就不要吃这些蘑菇了。
当然,尽管上述这些特征在毒蘑菇中很普遍,但是没有这些特征并不意味着该蘑菇就是无毒可食用的。

示例:发现国会投票中的模式(略)

需要注册自己的key,故略去。

注:

python中frozenset类型,是指被“冰冻”的集合,就是说它们是不可改变的,用户不能修改它们。frozenset和set的还有个区别是frozenset可以作为字典的键值使用。python中的List.append(obj),List.extend(obj),List.insert(index,obj)之间的区别是,append是在列表末尾添加一个新元素obj,extend是在列表末尾添加obj中的所有元素,inset是在特定的位置添加一个新元素。参照该页面了解votesmart包。有一个组织(致力于将政府数据公开化的组织)是智能投票工程Project Vote Smart,它提供了一个公共的API,可以方便我们从votesmart.org获取数据。第一,安装python-votesmart,第二,获得API key(需要在http://votesmart.org/share/api/register申请自己的key),这样就可以使用votesmartAPI了。python中set集合运算

使用Apriori算法进行关联分析(python2)

评论关闭