如何理解关联规则apriori算法

1. 什么是关联规则

关联规则是一种在大数据分析中常用的技术,它可以根据数据集中不同元素之间的共现关系,发现项之间的关系和规律,为业务提供支持和指导,是大数据分析中的重要工具之一。

关联规则中的两个概念:支持度和置信度。支持度表示某一项集合出现在样本数据中的频次;置信度表示当某一项集合出现时,另外某一项也同时出现的概率。

在大数据分析中,关联规则算法经常和Apriori算法结合使用。

2. 什么是Apriori算法

Apriori算法是一种关联规则算法的实现方式,可以从大规模数据集中发现有趣的关系。它的核心思想是利用先验知识,逐步地增加频繁项集的大小,从而找到频繁项集,再根据频繁项集推导出关联规则。

2.1 Apriori算法过程

Apriori算法的核心是通过逐层扫描数据集来获得频繁项集。具体的过程可以分为以下几个步骤:

步骤1: 第一层扫描,获取频繁项集中的每个元素的支持度。支持度是指每个元素在所有项集中出现的次数。

步骤2: 根据支持度阈值选出第一层的频繁项集。

步骤3: 根据频繁项集生成候选项集,其中每个候选项集包含两个频繁项集的元素,这些元素是由前一层的频繁项集连接而来的。

步骤4: 扫描数据集,找出候选项集中出现的项集的支持度,记为新的频繁项集,再次筛选,获取第二层频繁项集。

步骤5: 重复步骤3和步骤4,逐层向上扫描数据集,直到不再产生新的频繁项集为止。

2.2 Apriori算法代码实现

下面是Apriori算法的Python代码实现:

# Apriori算法实现

def apriori(dataset, minSupport=0.5):

# 生成第一层频繁项集

C1 = createC1(dataset)

D = 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)

# 更新支持度

supportData.update(supK)

L.append(Lk)

k += 1

return L, supportData

3. Apriori算法优化

虽然Apriori算法能够逐层挖掘频繁项集,但是在大规模数据集上,它的效率会受到很大的限制。因此,需要对Apriori算法进行优化,提高其效率。

3.1 稀疏数据结构

Apriori算法将所有的项集存储在内存中,因此它无法处理超大规模的数据集。为了解决这一问题,可以使用稀疏数据结构来存储数据集,从而节省内存空间。

3.2 剪枝技术

剪枝技术是一种常用的Apriori算法优化技术,能够削减生成的候选项集数量,提高算法效率。它的核心思想是:如果一个项集不是频繁项集,那么它的超集也不是频繁项集。

3.3 FP-Growth算法

FP-Growth算法是一种高效的关联规则挖掘算法,它将数据集转化为一颗FP-Tree(频繁项集树),通过对FP-Tree的挖掘,可以高效地找到频繁项集。相比于Apriori算法,FP-Growth算法具有更高的效率和更小的空间需求。

3.4 FP-Growth算法代码实现

下面是FP-Growth算法的Python代码实现:

# FP-Growth算法实现

class treeNode:

def __init__(self, nameValue, numOccur, parentNode):

self.name = nameValue

self.count = numOccur

self.nodeLink = None

self.parent = parentNode

self.children = {}

def inc(self, numOccur):

self.count += numOccur

def disp(self, ind=1):

print(' '*ind, self.name, ' ', self.count)

for child in self.children.values():

child.disp(ind+1)

def createTree(dataSet, minSupport=1):

headerTable = {}

for trans in dataSet:

for item in trans:

headerTable[item] = headerTable.get(item, 0) + dataSet[trans]

for k in list(headerTable.keys()):

if headerTable[k] < minSupport:

del(headerTable[k])

freqItemSet = set(headerTable.keys())

if len(freqItemSet) == 0:

return None, None

for k in headerTable:

headerTable[k] = [headerTable[k], None]

retTree = treeNode('Null Set', 1, None)

for tranSet, count in dataSet.items():

localD = {}

for item in tranSet:

if item in freqItemSet:

localD[item] = headerTable[item][0]

if len(localD) > 0:

orderedItems = [v[0] for v in sorted(localD.items(), key=lambda p: p[1], reverse=True)]

updateTree(orderedItems, retTree, headerTable, count)

return retTree, headerTable

def updateTree(items, inTree, headerTable, count):

if items[0] in inTree.children:

inTree.children[items[0]].inc(count)

else:

inTree.children[items[0]] = treeNode(items[0], count, inTree)

if headerTable[items[0]][1] == None:

headerTable[items[0]][1] = inTree.children[items[0]]

else:

updateHeader(headerTable[items[0]][1], inTree.children[items[0]])

if len(items) > 1:

updateTree(items[1::], inTree.children[items[0]], headerTable, count)

def updateHeader(nodeToTest, targetNode):

while (nodeToTest.nodeLink != None):

nodeToTest = nodeToTest.nodeLink

nodeToTest.nodeLink = targetNode

def ascendTree(leafNode, prefixPath):

if leafNode.parent != None:

prefixPath.append(leafNode.name)

ascendTree(leafNode.parent, prefixPath)

def findPrefixPath(basePat, treeNode):

condPats = {}

while treeNode != None:

prefixPath = []

ascendTree(treeNode, prefixPath)

if len(prefixPath) > 1:

condPats[frozenset(prefixPath[1:])] = treeNode.count

treeNode = treeNode.nodeLink

return condPats

def mineTree(inTree, headerTable, minSupport, preFix, freqItemList):

bigL = [v[0] for v in sorted(headerTable.items(), key=lambda p: p[1][0])]

for basePat in bigL:

newFreqSet = preFix.copy()

newFreqSet.add(basePat)

freqItemList.append(newFreqSet)

condPattBases = findPrefixPath(basePat, headerTable[basePat][1])

myCondTree, myHead = createTree(condPattBases, minSupport)

if myHead != None:

mineTree(myCondTree, myHead, minSupport, newFreqSet, freqItemList)

4. 总结

Apriori算法是一种经典的关联规则挖掘算法,通过逐层扫描数据集,从而发现数据集中的频繁项集,并根据频繁项集推导出关联规则。虽然Apriori算法在大规模数据集上存在效率问题,但是其思想和实现方式是关联规则挖掘算法中的重要组成部分,为其他算法提供了很好的借鉴和参考。

在实际应用中,可以结合稀疏数据结构、剪枝技术和FP-Growth算法等优化策略,提高关联规则挖掘的效率和精度。

后端开发标签