1. ref1 从概念到案例:初学者须知的十大机器学习算法
无监督学习:Apriori,k-means,PCA
监督学习:线性回归,logistic回归,CART(分类和决策树),朴素贝叶斯,KNN
集成:Bagging随即森林,Adaboost提升
2. ref2 1)关联分析--在大规模数据集中寻找有趣关系。
关系有2种形式:1是频繁项集--经常出现在一块的物品的集合;2是关联规则--暗示两种物品之间可能存在很强的关系。
2)项集的支持度:数据集中包含该项集的记录所占的比例。
可定义最小支持度,只保留满足最小支持度的项集。
3)可信度:针对一条诸如{尿布}->{葡萄酒}的关联规则。
3. ref2 使用apriori算法找到频繁项集
apriori在拉丁语意为“来自以前”。
apriori原理:如果一个项集是非频繁集,那么它的所有超集也是非频繁的。
把代码保存于此,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