博客园  :: 首页  :: 新随笔  :: 管理

使用Apriori算法进行关联分析

Posted on 2020-11-03 17:08  wsg_blog  阅读(927)  评论(0编辑  收藏  举报

Apriori算法可以实现什么:

  关联分析中最有名的例子是“尿布与啤酒”。据报道,美国中西部的一家连锁店发现,男人们会在周四购买尿布和啤酒。这样商店实际上可以将尿布与啤酒放在一块,并确保在周四全价销售从而获利,更多详细应用百度百科apriori

原理:

  Apriori关联分析算法实现起来可能会复杂一些,但是它的原理却是非常经典的简单粗暴

  关联分析是一种在大规模数据集中寻找有趣关系的任务。这些关系可以有两种形式:频繁项集或者关联规则。频繁项集(frequent item sets)是经常出现在一块的物品的集合,关联规则(association rules)暗示两种物品之间可能存在很强的关系。下面会用一个例子来说明这两种概念。下图给出了某个杂货店的交易清单。

 

频繁项集是指那些经常出现在一起的物品集合,图中的集合{葡萄酒,尿布, 豆奶}就是频繁项集的一个例子(回想一下,集合是由一对大括号“{ }”来表示的)。从下面的数据集中也可以找到诸如尿布 ➞葡萄酒的关联规则。这意味着如果有人买了尿布,那么他很可能也会买葡萄酒。使用频繁项集和关联规则,商家可以更好地理解他们的顾客。

  一个项集的支持度(support)被定义为数据集中包含该项集的记录所占的比例。从图11-1中可以得到,{豆奶}的支持度为4/5。而在5条交易记录中有3条包含{豆奶,尿布},因此{豆奶,尿布}的支持度为3/5。支持度是针对项集来说的,因此可以定义一个最小支持度,而只保留满足最小支持度的项集。
  可信度或置信度(confidence)是针对一条诸如{尿布} ➞ {葡萄酒}的关联规则来定义的。这条规则的可信度被定义为“支持度({尿布, 葡萄酒})/支持度({尿布})”。从图11-1中可以看到,由于{尿布, 葡萄酒}的支持度为3/5,尿布的支持度为4/5,所以“尿布 ➞ 葡萄酒”的可信度为3/4=0.75。这意味着对于包含“尿布”的所有记录,我们的规则对其中75%的记录都适用。

 

#Apriori接口文件
#关联分析的目标包括两项:发现 “频率集” 和发现 “关联规则”

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

'''
构建集合C1,C1是大小为1的所有候选集的集合;
Apriori算法首先构建集合C1,然后扫描数据集来判断这些只有一个元素的项集是否满足最小支持度的要求
那些满足最低要求的项集构成集合L1.而L1中的元素相互构成C2,C2再进一步过滤变成L2; 
'''
def createC1(dataSet):
    C1=[]       #首先创建一个空列表C1,它用来存储所有不重复的项值
    for transaction in dataSet:
        for item in transaction:
            if not [item] in C1:    #添加只包含该物品项的一个列表,为之后每个物品项创建只有一个整数的集合
                C1.append([item])
    C1.sort()
    return list(map(frozenset, C1))           #对C1中每个项构建一个不变集合

#三个参数分别为数据集、候选项集列表Ck以及最小支持度minSupport
def scanD(D, Ck, minSupport):
    ssCnt={}
    for tid in D:
        for can in Ck:
            if can.issubset(tid):  #can是tid的子集 返回 true
                if can not in ssCnt:
                    ssCnt[can]=1
                else:
                    ssCnt[can] += 1
    numItems = float(len(list(D)))
    retList = []
    supportData = {}
    for key in ssCnt:
        support = ssCnt[key]/numItems       #计算所有项集的支持度
        if support >= minSupport:
            retList.insert(0,key)
        supportData[key] = support
    return retList, supportData

#Apriori算法

#参数说明:频繁项集列表Lk与项集元素个数k,输出为Ck
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]  #前k-2个项相同时,将两个集合合并
            L1.sort(); L2.sort()
            if L1==L2:
                retList.append(Lk[i] | Lk[j])       #合并两个set
    return retList

#参数说明:数据集dataSet,最小支持度miniSupport
def apriori(dataSet, minSupport=0.5):
    C1 = createC1(dataSet)
    D = list(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)     #扫描数据集,从Ck得到Lk
        supportData.update(supK)
        L.append(Lk)
        k += 1
    return L,supportData

#参数说明:频繁项集列表L、包含那些频繁项集支持数据的字典supportData、最小可信度阈值minConf
#返回一个包含可信度的规则列表 bigRuleList
def generateRules(L, supportData, minConf=0.7):
    bigRuleList = []
    for i in range(1, len(L)):
        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 = []
    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):
            rulesFromConseq(freqSet, Hmp1, supportData, brl, minConf)
#执行过程
python
import apriori
dataSet=apriori.loadDataSet()
dataSet
L,suppData=apriori.apriori(dataSet,minSupport=0.5)
L
rules=apriori.generateRules(L,suppData,minConf=0.6)
rules

 

示例:美国国会的议案投票分析(这个特别有趣)

代码就不贴了,感兴趣的可以去《机器学习实战》-p212-11.5示例:发现国会投票中的模式,这里贴一下部分议案关联关系的分析结果

#议案
12939    Prohibiting Federal Funding of National Public Radio
12940    Removing Troops from Afghanistan
12830    Prioritizing Payment of Public Debt
12857    Calling for a Balanced Budget Constitutional Amendment
12988    Terminating the Home Affordable Modification Program
12040    Repealing Business Transaction Reporting Requirements
12465    Repealing the Health Care Bill
11451    Science and Technology Funding
11364    Credit Default Swap Regulations
11820    "Whistleblower Protection" for Offshore Oil Workers
12452    Treaty with Russia to Reduce and Limit Offensive Arms
11318    Derivatives Regulation Modifications
11414    Repealing "Don't Ask, Don't Tell" After Military Review and Certification
11719    Unemployment Benefits Extension
11205    Prohibiting 2010- 2011 Congressional Cost-of-Living Pay Increase
12747    Prohibiting Use of Federal Funds For Planned Parenthood
12792    Reducing Federal Funding of the US Institute of Peace
12827    Prohibiting the Use of Federal Funds for NASCAR Sponsorships
12445    Mine Safety Act
12049    2010-2011 Defense Authorizations


12939禁止国家公共广播电台的联邦资助
12940从阿富汗撤军
12830优先偿还公共债务
12857号召平衡预算宪法修正案
12988终止房屋可负担的改装计划
12040废除业务交易报告要求
12465废除《医疗保健法案》
11451科技经费
11364信用违约掉期规定
11820为海上石油工人提供“举报人保护”
12452与俄罗斯减少和限制进攻性武器条约
11318衍生产品法规修改
11414在军事审查和认证后废除“不问,不说”
11719失业救济金扩展
11205禁止2010-2011年国会生活费用加薪
12747禁止将联邦资金用于计划生育
12792减少美国和平研究所的联邦资助
12827禁止将联邦资金用于NASCAR赞助
12445矿山安全法
12049 2010-2011年国防授权

 

#关联分析结果,分析出了特多的关联关系...这里只取了一部分
Repealing "Don't Ask, Don't Tell" After Military Review and Certification -- Yea
           -------->
Democratic
confidence: 0.961538

Prohibiting Use of Federal Funds For Planned Parenthood -- Nay
           -------->
Democratic
confidence: 0.951351

Mine Safety Act -- Yea
           -------->
Democratic
confidence: 0.981308

Prohibiting Use of Federal Funds For Planned Parenthood -- Nay
           -------->
Repealing the Health Care Bill -- Nay
confidence: 0.962162

Prohibiting Federal Funding of National Public Radio -- Yea
           -------->
Repealing the Health Care Bill -- Yea
confidence: 1.000000

Mine Safety Act -- Yea
           -------->
Science and Technology Funding -- Yea
confidence: 0.962617

Prohibiting Federal Funding of National Public Radio -- Yea
           -------->
Terminating the Home Affordable Modification Program -- Yea
confidence: 0.973684

Repealing the Health Care Bill -- Yea
           -------->
Terminating the Home Affordable Modification Program -- Yea
confidence: 0.963265

Repealing the Health Care Bill -- Nay
           -------->
Democratic
confidence: 0.978836

Unemployment Benefits Extension -- Yea
           -------->
"Whistleblower Protection" for Offshore Oil Workers -- Yea
confidence: 0.962963

Prohibiting Federal Funding of National Public Radio -- Yea
           -------->
Prohibiting Use of Federal Funds For Planned Parenthood -- Yea
confidence: 0.964912

Prohibiting Use of Federal Funds For Planned Parenthood -- Yea
           -------->
Terminating the Home Affordable Modification Program -- Yea
confidence: 0.950000

Repealing "Don't Ask, Don't Tell" After Military Review and Certification -- Nay
           -------->
Prohibiting 2010- 2011 Congressional Cost-of-Living Pay Increase -- Yea
confidence: 0.953608

Prohibiting Use of Federal Funds For Planned Parenthood -- Yea
           -------->
Republican
confidence: 0.954167

Science and Technology Funding -- Yea
           -------->
"Whistleblower Protection" for Offshore Oil Workers -- Yea
confidence: 0.961832

Mine Safety Act -- Nay
           -------->
Prohibiting 2010- 2011 Congressional Cost-of-Living Pay Increase -- Yea
confidence: 0.963351

Repealing the Health Care Bill -- Yea
           -------->
Republican
confidence: 0.983673

Mine Safety Act -- Yea
           -------->
"Whistleblower Protection" for Offshore Oil Workers -- Yea
confidence: 0.985981

Repealing the Health Care Bill -- Nay
           -------->
Prohibiting Federal Funding of National Public Radio -- Nay
confidence: 0.962963

Mine Safety Act -- Yea
           -------->
Unemployment Benefits Extension -- Yea
confidence: 0.957944

Prohibiting Federal Funding of National Public Radio -- Yea
           -------->
Republican
confidence: 0.995614
在军事审查和认证后废除“不问,不说”-是的
-------->
民主党
信心:0.961538

禁止将联邦资金用于计划生育--------->
民主党
置信度:0.951351

矿山安全法-是的
-------->
民主党
信心:0.981308

禁止将联邦资金用于计划生育--------->
废除《医疗保健法案》
信心:0.962162

禁止国家公共广播电台的联邦资助-是的
-------->
废除《医疗保健法案》
置信度:1.000000

矿山安全法-是的
-------->
科技资助-是的
信心:0.962617

禁止国家公共广播电台的联邦资助-是的
-------->
终止房屋可负担的改装计划-是的
信心:0.973684

废除《医疗保健法案》
-------->
终止房屋可负担的改装计划-是的
信心:0.963265

废除《医疗保健法案》
-------->
民主的
置信度:0.978836

失业救济金延伸-是的
-------->
为海上石油工人提供“举报人保护”-是的
信心:0.962963

禁止国家公共广播电台的联邦资助-是的
-------->
禁止将联邦资金用于计划生育-是的
信心:0.964912

禁止将联邦资金用于计划生育-是的
-------->
终止房屋可负担的改装计划-是的
置信度:0.950000

在军事审查和认证后废除“不问,不说”的方法
-------->
禁止2010-2011年国会生活费用加薪-是的
信心:0.953608

禁止将联邦资金用于计划生育-是的
-------->
共和党人
信心:0.954167

科技资助-是的
-------->
为海上石油工人提供“举报人保护”-是的
置信度:0.961832

矿山安全法--------->
禁止2010-2011年国会生活费用加薪-是的
置信度:0.963351

废除《医疗保健法案》
-------->
共和党人
信心:0.983673

矿山安全法-是的
-------->
为海上石油工人提供“举报人保护”-是的
信心:0.985981

废除《医疗保健法案》
-------->
禁止联邦资助国家公共广播电台-奈
信心:0.962963

矿山安全法-是的
-------->
失业救济金延伸-是的
信心:0.957944

禁止国家公共广播电台的联邦资助-是的
-------->
共和党人
信心:0.995614