机器学习-关联之FP-Growth算法原理及实战
生活随笔
收集整理的這篇文章主要介紹了
机器学习-关联之FP-Growth算法原理及实战
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
FP-Growth
- 簡介
- FP-Growth算法是一種發(fā)現(xiàn)數(shù)據(jù)集中頻繁模式的有效方法,它在Apriori算法的原理的基礎上,采用FP(Frequent Pattern,頻繁模式)樹數(shù)據(jù)結構對原始數(shù)據(jù)進行壓縮,大大加快了計算速度。FP-Growth算法把數(shù)據(jù)集中的事物映射到一棵FP-Tree上,再根據(jù)這棵樹找到頻繁項集,FP-Tree的構建過程只需要掃描兩次數(shù)據(jù)集,特別是在大型數(shù)據(jù)集上具有很高的效率。
- 原理
- FP-Growth算法的基本過程分為兩個步驟:構建FP樹和挖掘頻繁項集。FP樹構建通過兩次數(shù)據(jù)掃描,將原始數(shù)據(jù)中的事物壓縮到一個FP樹,該FP樹類似于前綴樹,相同前綴的路徑可以共用,從而達到壓縮數(shù)據(jù)的目的。接著通過FP樹找出每個項的條件模式基、條件FP樹,遞歸的挖掘條件FP樹得到所有的頻繁項集。算法的主要計算“瓶頸”在FP-Tree的遞歸挖掘上,這里介紹FP-Growth算法主要步驟。
- FP樹的數(shù)據(jù)結構
- FP-Growth算法將數(shù)據(jù)存儲在一種稱為FP樹的緊湊數(shù)據(jù)結構中。一棵FP樹看上去與計算機科學中的其他樹的結構類似,但是它通過鏈接來連接相似元素,被連起來的元素項可以看出一個鏈表。
- 與搜索樹不同的是,一個元素項可以在一棵FP樹中出現(xiàn)多次。FP樹會存儲項集的出現(xiàn)頻率,而每個項集會以路徑的方式存儲在樹中。存在相似元素的集合會共享樹的一部分,只有當集合之間完全不同時,樹才會分叉。樹節(jié)點上給出集合中的單個元素及其在序列中的出現(xiàn)次數(shù),路徑會給出該序列的出現(xiàn)次數(shù)。
- 構建FP樹
- FP通過鏈接來連接相似元素,被連起來的元素可以看做一個鏈表。將事物數(shù)據(jù)表中的各個事物對應的數(shù)據(jù)項按照支持度排序后,把每個事物中的數(shù)據(jù)項按降序依次插入一棵以NULL為根節(jié)點的樹中,同時在每個節(jié)點處記錄該節(jié)點出現(xiàn)的支持度。構建FP樹需要兩次掃描數(shù)據(jù)集,第一次用來統(tǒng)計各元素項的出現(xiàn)頻率,第二次掃描只考慮頻繁項集,FP樹具體構建過程如下。
- 1.遍歷數(shù)據(jù)集,統(tǒng)計各元素項出現(xiàn)次數(shù),創(chuàng)建頭指針表。
- 2.移除頭指針表中不滿足最小值尺度的元素項。
- 3.第二次遍歷數(shù)據(jù)集,創(chuàng)建FP樹。對每個數(shù)據(jù)集中的項集進行如下操作。
- a.初始化空FP樹。
- b.對每個項集進行過濾和重排序。
- c.使用這個項集更新FP樹,從FP樹的根節(jié)點開始進行。
- 如果當前項集的第一個元素項存在于FP樹當前節(jié)點的子節(jié)點中,則更新這個子節(jié)點的計數(shù)值。
- 否則,創(chuàng)建新的子節(jié)點,更新頭指針表。
- 對當前項集的其余元素項和當前元素項的對應子節(jié)點遞歸c過程。
- FP通過鏈接來連接相似元素,被連起來的元素可以看做一個鏈表。將事物數(shù)據(jù)表中的各個事物對應的數(shù)據(jù)項按照支持度排序后,把每個事物中的數(shù)據(jù)項按降序依次插入一棵以NULL為根節(jié)點的樹中,同時在每個節(jié)點處記錄該節(jié)點出現(xiàn)的支持度。構建FP樹需要兩次掃描數(shù)據(jù)集,第一次用來統(tǒng)計各元素項的出現(xiàn)頻率,第二次掃描只考慮頻繁項集,FP樹具體構建過程如下。
- 從FP樹中挖掘頻繁項集
- 有了FP樹,就可以抽取頻繁項集了。這里的思路與Apriori算法大致類似,首先從單元素項集合開始,然后在此基礎上逐步構建更大的集合。從FP樹中抽取頻繁項集的基本步驟如下。
- 1.從FP樹中獲得條件模式基
- 從頭指針表最下面的頻繁元素項開始,構造每個元素項的條件模式基。條件模式基是以所查找元素項為結尾的路徑集合,這里每一條路徑都是該元素項的前綴路徑。條件模式基的頻繁度為該路徑上該元素項的頻繁度計數(shù)。
- 2.利用條件模式基,構建一個條件FP樹
- 對于每一個頻繁項,都需要創(chuàng)建一棵條件FP樹。使用剛才創(chuàng)建的條件模式基作為輸入,累加每個條件模式基上的元素項頻繁度,過濾低于閾值的元素項,采用同樣的建樹代碼構建FP樹。遞歸發(fā)現(xiàn)頻繁項、條件模式基和另外的條件樹。
- 3.迭代重復步驟1和2,直到樹包含一個元素項,這樣就獲得了所有的頻繁項集。
- 1.從FP樹中獲得條件模式基
- 有了FP樹,就可以抽取頻繁項集了。這里的思路與Apriori算法大致類似,首先從單元素項集合開始,然后在此基礎上逐步構建更大的集合。從FP樹中抽取頻繁項集的基本步驟如下。
- 實戰(zhàn)
- 使用FP-Growth算法提取頻繁項集
- 提取文本事物數(shù)據(jù)的頻繁項集
- 代碼
- class treeNode:"""定義FP樹數(shù)據(jù)結構"""def __init__(self, nameValue, numOccur, parentNode):# 節(jié)點元素名稱self.name = nameValue# 出現(xiàn)次數(shù)self.count = numOccur# 指向下一個相似節(jié)點self.nodeLink = None# 指向父節(jié)點self.parent = parentNode# 指向子節(jié)點,子節(jié)點元素名稱為鍵,指向子節(jié)點指針為值self.children = {}def inc(self, numOccur):"""增加節(jié)點的出現(xiàn)次數(shù):param numOccur::return:"""self.count += numOccurdef disp(self, ind=1):"""輸出節(jié)點和子節(jié)點的FP樹結構:param ind::return:"""print(' ' * ind, self.name, ' ', self.count)for child in self.children.values():child.disp(ind + 1)def createTree(dataSet, minSup=1):"""建樹:param dataSet::param minSup::return:"""headerTable = {}for trans in dataSet:for item in trans:headerTable[item] = headerTable.get(item, 0) + dataSet[trans]for k in list(headerTable):if headerTable[k] < minSup:del (headerTable[k])freqItemSet = set(headerTable.keys())if len(freqItemSet) == 0:return None, Nonefor 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, headerTabledef updateTree(items, inTree, headerTable, count):"""使用頻繁項集使FP樹生長:param items::param inTree::param headerTable::param count::return:"""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] is 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):"""更新頭指針表,確保節(jié)點鏈接指向樹中該元素項的每一個實例:param nodeToTest::param targetNode::return:"""while nodeToTest.nodeLink is not None:nodeToTest = nodeToTest.nodeLinknodeToTest.nodeLink = targetNode# 挖掘頻繁項集def ascendTree(leafNode, prefixPath):if leafNode.parent is not None:prefixPath.append(leafNode.name)ascendTree(leafNode.parent, prefixPath)def findPrefixPath(basePat, treeNode):condPats = {}while treeNode is not None:prefixPath = []ascendTree(treeNode, prefixPath)if len(prefixPath) > 1:condPats[frozenset(prefixPath[1:])] = treeNode.counttreeNode = treeNode.nodeLinkreturn condPatsdef mineTree(inTree, headerTable, minSup, preFix, freqItemList):"""遞歸查找頻繁項集:param inTree::param headerTable::param minSup::param preFix::param freqItemList::return:"""bigL = [v[0] for v in sorted(headerTable.items(), key=lambda p: str(p[1]))]for basePat in bigL:newFreqSet = preFix.copy()newFreqSet.add(basePat)freqItemList.append(newFreqSet)condPathBases = findPrefixPath(basePat, headerTable[basePat][1])myCondTree, myHead = createTree(condPathBases, minSup)if myHead is not None:print('conditional tree for:', newFreqSet)mineTree(myCondTree, myHead, minSup, newFreqSet, freqItemList)# 生成數(shù)據(jù)集def loadSimpDat():simData = [['r', 'z', 'h', 'j', 'p'],['z', 'y', 'x', 'w', 'v', 'u', 't', 's'],['z'],['r', 'x', 'n', 'o', 's'],['y', 'r', 'x', 'z', 'q', 't', 'p'],['y', 'z', 'x', 'e', 'q', 's', 't', 'm']]return simDatadef createInitSet(dataSet):retDict = {}for trans in dataSet:retDict[frozenset(trans)] = 1return retDictif __name__ == '__main__':minSup = 3simDat = loadSimpDat()initSet = createInitSet(simDat)myFPtree, myHeaderTab = createTree(initSet, minSup)myFPtree.disp()myFreqList = []mineTree(myFPtree, myHeaderTab, minSup, set([]), myFreqList)print(myFreqList)
- 補充說明
- 參考書《Python3數(shù)據(jù)分析與機器學習實戰(zhàn)》
- 具體數(shù)據(jù)集和代碼可以查看我的GitHub,歡迎star或者fork
總結
以上是生活随笔為你收集整理的机器学习-关联之FP-Growth算法原理及实战的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Jupyter Notebook导入自定
- 下一篇: 词性标注与命名实体识别