前言:
这种算法在实际应用中还是非常广泛,目标是找到一起出现的物品。比如男生去吃饭,推荐完菜肴后,关联推荐一下对应的酒水。女生去吃饭,推荐一下对应的果汁。 也经常用于流量分析,以及医药行业。
算法实际应用中,需要灵活应用。比如某个事件出现的概率极其低,频繁项关联就会关联不到。
但是在某个时间点,或者特定事件组合中出现概率极其高。
目录:
- 算法简介
- 频繁项集生成
- 关联规则生成
- 投票中规则发现
一 算法简介
apriori”, 拉丁语来自于以前。基本概念
1.1 频繁项集
是经常集合在一起出现的物品的集合
1.2 关联规则
某两种规则之间存在很强的联系
1.3 支持度
定义为数据集中包括该记录所占比例
1.3 可信度或者置信度
针对一条记录x->另一条记录y的关联规则定义而来
二 频繁项集生成
说明:
k: 代表当前项有k个元素
频繁项集
: 候选项集
主要原理:
如果某个项集合是频繁的,那么它所有的子集也是
SCan: (生成满足频繁度的候选子集)
对数据中的每个记录tran
对每个候选集
检查can是否是tran 的子集
如果是: 则增加can的计数值
对每个候选集
如果该支持度不小于最小值,则保留该项集
返回频繁集列表
Apriori 完整算法
当集合中项的候选项大于0
构建一个k个项组成的候选项集的列表
检查数据以确认每个项集都是频繁的
保留频繁项,并构建一个k+1的候选集的列表
三 关联规则
若某条规则不满足最小置信度要求,则所有的子集也不满足.
对每个单独的平反集元素,从上到下递推出规则
# -*- coding: utf-8 -*-
"""
Created on Tue Dec 17 14:32:25 2019
@author: chengxf2
"""
"""
加载数据集
Args
None
return
数据集
"""
import numpy as np
"""
加载数据集
Args
None: 这些数据集每一个样本之间是没有时序关系的
return
dataList: 数据集
"""
def LoadDataSet():
dataList =[[1,3,4],
[2,3,5],
[1,2,3,5],
[2,5]]
return dataList
"""
创建一个空列表C1,存储不重复的项值
Args
dataSet: 数据集
return
C1: 子数据集
"""
def CreateC1(dataSet):
C1 = []
for tran in dataSet:
for item in tran:
if not [item] in C1:
C1.append([item])
C1.sort()
return list(map(frozenset, C1))
"""
数据集扫描,返回支持度support,发现频繁项集
每个子集必须是频繁项
Args
D: 数据集
C1: 候选项集列表CK
最小支持度: minSupport
return
Lk: 频繁项
"""
def SCan(D, Ck,minSupport):
ssCnt ={}
##检查当前的交易
for tid in D:
for key in Ck: ##候选子集
if key.issubset(tid):
if key not in ssCnt:
ssCnt[key] =1
else:
ssCnt[key]+=1
#检测频繁度
num = len(D)
Lk = []
supportData ={}
for key in ssCnt:
support = ssCnt[key]/num
if support>= minSupport:
Lk.insert(0, key)
supportData[key]=support
# print("\n supportData :\n ",supportData)
return Lk, supportData
"""
产生一个集合,该集合的子集都是由频繁项组成,元素长度为K
Arg
Lk: 频繁项集列表
k: 项集元素个数
输出
Ck: 产生一个集合,该集合的子集都是由频繁项组成
"""
def ApriorGen(Lk, k):
ckList = []
n = len(Lk)
#print("in Lk ",list(Lk), "\t n: ",n,"\t :k ",k)
for i in range(n):
L1 = list(Lk[i])[:k-2]
#print("L1:::: \t",L1)
L1.sort()
for j in range(i+1, n):
L2 = list(Lk[j])[:k-2]
L2.sort()
if L1 == L2:
ckList.append(Lk[i]|Lk[j])
return ckList
"""
完整的算法
Args
dataSet: 数据集
minSupport: 最小支持度
return
L: 频繁项,suppportData:支持度
"""
def Apriori(dataSet, minSupport=0.6):
C1 = CreateC1(dataSet) ##创建子集
D = list(map(set,dataSet))
L1, supportData = SCan(D, C1, minSupport) ##产生候选集
# print("\n ======= L1 =========== \n",L1)
L = [L1]
k=2
while (len(L[k-2])>0):
ck = ApriorGen(L[k-2],k) ##产生候选子集
# print("\n ck===> \t \n ",k,ck)
Lk,supK = SCan(D, ck, minSupport) ##产生候选子集Lk
supportData.update(supK) ##更新支持度
L.append(Lk)
k+=1
return L, supportData
"""
关联规则生成
Args
L:频繁项
supportData: 支持度
minConf: 最小支持度
return
bigRuleList: 最大支持度
"""
def GenerateRule(L, supportData, minConf=0.5):
bigRuleList = []
n = len(L)
print("\n *****关联规则生成************\t ")
for i in range(1, n):
print("\n i: ",i,"\t 频繁项集合 ",L[i])
for freqSet in L[i]: ##检查每个频繁集
H1 =[frozenset([item]) for item in freqSet] ##生成对应的子集
if(i>1):
print("\n H1: ",H1,"\t, freqSet \t",freqSet)
RulesFromConseq(freqSet, H1, supportData, bigRuleList, minConf)
else:
CalcConf(freqSet, H1, supportData, bigRuleList, minConf)
return bigRuleList
"""
计算支持度
y =h
p(y|x)=P(x,y)/p(x)
x= freqSet-y
Args
freqSet: 频繁集例如 {23}
H: 频繁集合中每个元素的集合[2,3]
supportData: P(23) 的支持度
br1: 关联度集合
minconf: 最小置信度
"""
def CalcConf(freqSet, H, supportData, br1, minconf):
prunedH = []
for h in H:
conf = supportData[freqSet]/supportData[freqSet-h]
if conf>=minconf:
br1.append([freqSet-h, h,conf])
prunedH.append(h)
return prunedH
""""
生成一个基本的规则
Args
freqSet: 频繁集例如 {123}
H: 频繁集合中每个元素的集合[1,2,3]
supportData: P(23) 的支持度
br1: 关联度集合
minconf: 最小置信度
"""
def RulesFromConseq(freqSet, H, supportData, br1, minconf= 0.5):
m = len(H[0])
print("\n m: ",m,"\t freSetNum: ",len(freqSet))
if (len(freqSet)> (m+1)): ##防止为NULL
H1 = ApriorGen(H,m+1) ##产生一个频繁集合的增广集合
H1 = CalcConf(freqSet, H1, supportData, br1, minconf)
if (len(H1)>1):
RulesFromConseq(freqSet, H1,supportData, br1,minconf)
def Test():
dataSet = LoadDataSet()
L, supportData = Apriori(dataSet,0.5)
print("\n L: \n",L)
print("\n supportData: \n",supportData)
print("\n **************End******************\n")
#print("\n :::L:::::::\n ",L, "\n supportData::::::\n ",supportData)
rule= GenerateRule(L, supportData)
print("\n *********规则生成结束***********\n")
print("\n rule, ",rule)
# print("\n C1:",C1)
Test()
参考文档:
《机器学习与应用》
来源:CSDN
作者:chengxf2
链接:https://blog.csdn.net/chengxf2/article/details/103599977