[机器学习][源码]机器学习实战ch11 Apriori

本文深入探讨了机器学习中的无监督学习算法Apriori,介绍了关联分析的基本概念,如频繁项集、支持度和可信度,并通过Apriori算法寻找数据中的关联规则。此外,还提到了Apriori算法的工作原理,即如果一个项集非频繁,其所有超集也非频繁。文章基于《机器学习实战》一书进行阐述。
摘要由CSDN通过智能技术生成

1. ref1 从概念到案例:初学者须知的十大机器学习算法

无监督学习:Apriori,k-means,PCA

监督学习:线性回归,logistic回归,CART(分类和决策树),朴素贝叶斯,KNN

集成:Bagging随即森林,Adaboost提升


2. ref2  1)关联分析--在大规模数据集中寻找有趣关系。

关系有2种形式:1是频繁项集--经常出现在一块的物品的集合;2是关联规则--暗示两种物品之间可能存在很强的关系。

2)项集的支持度:数据集中包含该项集的记录所占的比例。

可定义最小支持度,只保留满足最小支持度的项集。

3)可信度:针对一条诸如{尿布}->{葡萄酒}的关联规则。


3. ref2  使用apriori算法找到频繁项集

apriori在拉丁语意为“来自以前”。

apriori原理:如果一个项集是非频繁集,那么它的所有超集也是非频繁的。


4. ref2 chapter11 具体实践

把代码保存于此,python3实现,详解就参考《机器学习实战》(Peter Harrington)啦...

暂时 略掉11.5节:国会投票。

from numpy import *

# 11-1 apriori算法的辅助函数
def loadDataSet():
    return [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]

# 构建集合C1--大小为1的所有候选项集的集合
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 frozenset(不可改变的), so we can use it as a key in a dict

# 该函数用于从 Ck 生成 Lk (大小为k的频繁项集),Ck:大小为k的所有候选项集  
def scanD(D, Ck, minSupport):
 #数据集(交易记录),候选项集列表,最小支持度
    ssCnt = {}
    for tid in D:#遍历数据集
        for can in Ck:#遍历候选项
            if can.issubset(tid):#判断can是否是tid的子集,如{2,3}在{0,2,3}中
                if not can in ssCnt: 
                    ssCnt[can]=1
                else: 
                    ssCnt[can] += 1

    numItems = float(len(D))#数据集大小(交易记录数目)
    retList = []#L1初始化
    supportData = {}#记录候选项中各个数据的支持度
    for key in ssCnt:
        support = ssCnt[key]/numItems#计算支持度
        if support >= minSupport:
            retList.insert(0,key)#满足条件加入L1中
        supportData[key] = support
    return retList, supportData #retList即Lk,supportData:Ck中所有项的支持度
'''
e:
cd workspaces/pythonwp
cd ch11
python
import apriori

dataSet=apriori.loadDataSet()
dataSet
C1=list( apriori.createC1(dataSet) )
C1
D=list( map(set,dataSet) ) #构建 集合表示的数据集D
D 
L1,suppData0=apriori.scanD(D,C1,0.5)
L1
'''


# 11-2 Apriori算法 -- 发现频繁项集

#create Ck(Ck:大小为k的所有候选项集)
#用L k-1 (大小为k-1的所有频繁集) 生成 Ck(大小为k的所有候选集)
def aprioriGen(Lkk,k): 
	#Lkk 表示 L k-1 (大小为k-1的所有频繁集)	
	retList=[]
	lenLkk=len(Lkk)
	for i in range(lenLkk):
		for j in range(i+1,lenLkk):	   
			L1=list(Lkk[i])[:k-2]; L2=list(Lkk[j])[:k-2] 
			#要求L1、L2的前k-2个元素都相同,只有第k-1个元素不同。如此,将L1、L2取并集,得到k个元素。
			L1.sort(); L2.sort()
			if L1==L2:
				retList.append(Lkk[i] | Lkk[j])
	return retList

#主函数
def apriori(dataSet,minSupport=0.5):
	C1=list ( createC1(dataSet) ) # 11-1,大小为1的所有候选项集的集合
	D=list ( map(set,dataSet) ) #构建 集合表示的数据集D
	L1, supportData=scanD(D,C1,minSupport) #从 C1(大小为1的所有候选集) 生成 L1(大小为1的频繁项集)
	L=[L1]
	k=2

   #每一步循环: L k-1 --> Ck --> Lk 
	while( len(L[k-2]) > 0 ):
		Ck=apriorGen(L[k-2],k) # L[0]=L1,L[1]=L2,L[2]=L3... 则L[k-2]=L k-1,是 大小为k-1的所有频繁集。 
							   # apriorGen(L[k-2],k)就是 用L k-1(大小为k-1的所有频繁集) 生成 Ck(大小为k的所有候选集)
		Lk,supK=scanD(D,Ck,minSupport) #从 Ck(大小为k的所有候选集) 生成 Lk(大小为k的频繁项集)
		supportData.update(supK) #将supK 添加到 supportData
		L.append(Lk) #将Lk 添加到 频繁项集L
		k += 1

	return L,supportData
'''
from importlib import reload
reload(apriori)
L,supportData=apriori.apriori(dataSet)
L[0] #L1
L[1] #L2
L[2] #L3
L[3] #L4
apriori.aprioriGen(L[0],2) #用L1生成C2(所有大小为2的候选集合)

L,supportData=apriori.apriori(dataSet,minSupport=0.7)
L   
'''   


# 11-3 关联规则生成函数
#主函数
def generateRules(L,supportData,minConf = 0.7):
    # 频繁项集列表,包含频繁项集支持数据的字典,最小可信度

    bigRuleList = [] #包含可信度的规则列表

    for i in range(1,len(L)): #len(L)=4   对频繁集 L[1],L[2],L[3],L[4]进行循环 (L[0]是只有1个元素的频繁项集,忽略)
 
        for freqSet in L[i]:  #L[i]中的每个频繁项
          
            H1 = [frozenset([item]) for item  in freqSet]  # H1:只包含 单个元素集合 的列表,如freqSet = {0,1,2},则 H1=[{0},{1},{2}]
           
            if( i > 1 ):  #频繁项中多于2个元素   L[2],L[3],L[4]中的项
                rulesFromConseq(freqSet,H1,supportData,bigRuleList,minConf)
            else:         #频繁项中只有2个元素   L[1]中的项
                calcConf(freqSet,H1,supportData,bigRuleList,minConf)

    return bigRuleList


#计算规则的可信度 + 满足最小可信度要求的规则
def calcConf(freqSet,H,supportData,br1,minConf=0.7):
           #频繁项集, 可以出现在规则右边的元素列表H, .., br1:前面通过检查的bigRuleList, .. 
   
    prunedH = [] #保存满足最小可信度要求的规则列表
   
    for conseq in H: #遍历H中的所有项集 并 计算可信度
        conf = supportData[freqSet]/supportData[freqSet-conseq]
        if conf >= minConf:
            print (freqSet-conseq,'-->',conseq,'conf:',conf)

            br1.append((freqSet-conseq,conseq,conf)) #填充br1,即bigRuleList
            prunedH.append(conseq)

    return prunedH


#从最初的项集中生成更多的关联规则
def rulesFromConseq(freqSet,H,supportData,br1,minConf=0.7):
                 # 频繁项集, 可以出现在规则右边的元素列表H, .., .., ..
   
    m = len(H[0]) # H中的频繁集大小m

    if( len(freqSet) > (m+1) ):
        Hmp1 = aprioriGen(H,m+1)  #用H (大小为m的频繁集) 生成 Hmp1(大小为m+1的所有候选集)
        Hmp1 = calcConf(freqSet,Hmp1,supportData,br1,minConf)

        if(len(Hmp1) > 1):
            rulesFromConseq(freqSet,Hmp1,supportData,br1,minConf)

'''
# 为了更好地理解10-3,逐步运行如下代码 并 查看中间结果

dataSet=apriori.loadDataSet()
L,suppData = apriori.apriori(dataSet,minSupport=0.5)

supportData=suppData
bigRuleList = []
minConf=0.5

#-- L[1] --
freqSet=frozenset({1,3}) # 2,3   3,5   2,5   1,3
H1 = [frozenset([item]) for item  in freqSet] 
apriori.calcConf(freqSet,H1,supportData,bigRuleList,minConf)

#-- L[2] --   
# freqSet=frozenset({2,3,5})作为例子运行一次,查看中间结果
freqSet=frozenset({2,3,5}) 
H1 = [frozenset([item]) for item  in freqSet] 
apriori.rulesFromConseq(freqSet,H1,supportData,bigRuleList,minConf)
m = len(H[0]) # H中的频繁集大小m

if( len(freqSet) > (m+1) ):
    Hmp1 = apriori.aprioriGen(H,m+1)
    Hmp1 = apriori.calcConf(freqSet,Hmp1,supportData,bigRuleList,minConf)

    if(len(Hmp1) > 1):
        apriori.rulesFromConseq(freqSet,Hmp1,supportData,bigRuleList,minConf)
'''

'''
# 运行书中例子
from importlib import reload
reload(apriori)

dataSet=apriori.loadDataSet()

L,suppData = apriori.apriori(dataSet,minSupport=0.5)
L[0] #L1
L[1] #L2
L[2] #L3
L[3] #L4

rules = apriori.generateRules(L,suppData,minConf=0.5)
rules  
'''   


# chapter 11.6 毒蘑菇

# load data
mushDatSet = [line.split() for line in open('mushroom.dat').readlines()]

# 运行apriori算法,找到所有支持度大于0.3的频繁项集
L,suppData = apriori.apriori(mushDatSet,minSupport=0.3) 

# 搜索包含有毒特征值2的频繁项集(因为值1,2 只在第一个特征中出现)
for item in L[1]: #大小为2的频繁项集
    if item.intersection('2'):
        print(item)

for item in L[3]: #大小为4的频繁项集
    if item.intersection('2'):
        print(item)

ref1: 算法与数学之美  从概念到案例:初学者须知的十大机器学习算法

ref2: 机器学习实战( Peter Harrington ) chapter 11



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值