本文根據最近學習機器學習書籍網絡文章的情況,特将一些學習心得做了總結,詳情如下.如有不當之處,請各位大拿多多指點,在此謝過。
一、概述
1、背景故事
日常生活中,當我們去商店去購物的時候,實際上都包含了機器學習的當下和未來的場景應用,這包括物品的展示方式、購物之後的優惠券的提供、使用者忠誠度計劃等等。這些其實都離不開對大量資料的分析。商店希望從顧客身上獲得更多的利潤,是以必然使用各種技術來達到這一目的。
忠誠度計劃是指顧客可以利用會員卡獲得一定的購物折扣,利用這一計劃,商店可以了解顧客購買的物品。當然,即使不使用會員卡,商店也可以檢視到顧客購買物品時所使用信用卡的信用記錄。即使顧客不使用信用卡而用現金支付代替,商店也可以檢視到顧客購買物品的組合。
通過檢視哪些商品一起購買,商店可以了解顧客的購物行為。這種從大量資料海洋中提取的資訊可以用于指定商品定價、市場促銷、存貨管理等環節。從大規模資料海洋中尋找物品之間隐含的關系被稱為關聯分析(Associationanalysis)或關聯規則分析(AssociationRuleLearning)。這裡的主要問題在于,尋找物品的不同組合是一項艱巨的任務,所需要的計算代價很高,蠻力搜尋不能解決這一問題,需要使用更智能的方法在合理的實際範圍内找到頻繁項集。這裡先讨論關聯分析,然後梳理Apriori算法原理。
2、相關概念及分析
關聯分析是一種在大規模資料集中尋找有趣關系的任務。這些關系可以分為兩種:頻繁項集或關聯規則。頻繁項集是經常一塊出現的物品的集合。關聯規則是暗示兩種物品可能存在很強的關系。我們可以通過下圖給出商店的交易清單,對頻繁項集和關聯規則的概念進行進一步分析。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICdzFWRoRXdvN1LclHdpZXYyd2LcBzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX9EEVPRzZE1kMjpXTmZEWjZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DNzgjNwMzM4ADNyEDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
通過上圖,結合頻繁項集的概念,我們知道{豆奶,尿布,葡萄酒}是頻繁項集的一個例子,因為頻繁項集是指經常一塊出現的物品的集合。當然,通過下面的資料集也可以找到諸如尿布-->葡萄酒之間的關聯規則。這意味着顧客購買了尿布也很可能會購買葡萄酒。使用頻繁項集和關聯規則可以使商店更好地了解顧客的購物行為。
當我們面對大量資料進行頻繁項集或關聯規則歸類時,可能會面臨些疑問:怎麼樣才算有趣?這個有趣的定義誰來決定?當尋找頻繁項集時,頻繁(Frequent)的定義是什麼?這裡我們從支援度和可信度的角度來解答。
支援度(Support)是指資料集中包含該項集中的記錄所占的比例。從11-1圖中,我們可以知道{豆奶}的支援度是4/5。{豆奶,尿布}的支援度是3/5,因為5條記錄中有3條包含{豆奶,尿布}。支援度是針對項集而言的,是以可以定義一個最小支援度,隻保留滿足最小支援度的項集。
可信度或置信度(confidence)是針對一條諸如{尿布}-→{葡萄酒}的關聯規則而定義的。這條規則的可信度被定義為“支援度{尿布,葡萄酒}/支援度{尿布}”。從圖11-1中可知,由于{尿布,葡萄酒}的支援度是3/5,,{尿布}的支援度是4/5,是以“尿布-->葡萄酒”的可信度是3/4,即0.75。這就說明,對于包含“尿布”的所有記錄中,我們的規則對于其中的75%的記錄都是有效的。
支援度和可信度是用來量化關聯分析是否成功的方法。倘若需要找到支援度大于0.8的所有項集,如何進行?一種傳統的方法是生成一個物品的所有可能組合清單,然後對每一種組合統計出其出現的頻繁度,但當商品梳理龐大時,效率極其低下,那麼,有一中叫做APriori算法原理,可以減少關聯規則學習時所需要的計算量。
3、Apriori算法的一般流程
- 收集資料: 使用任意方法。
- 準備資料: 任何資料類型都可以,因為這裡指儲存集合。
- 分析資料: 使用任何方法。
- 訓練算法: 使用Apriori算法來找到頻繁項集。
- 測試算法: 不需要測試過程。
- 使用算法: 用于發現頻繁項集以及物品之間的關聯規則。
4、Apriori的相關特性
- 優點: 易編碼實作。
- 缺點: 在大資料集上可能很慢。
- 适用資料類型:數值型或者标稱型資料。
二、Apriori算法原理
假設在一家經營商品種類不多的商店中,店主對于一起被購買的商品組合很感興趣。這裡有四種商品:商品0、商品1、商品2、商品3。那麼所有可能被一起購買的商品組合總計有哪些?這些商品組合可能隻包含一種商品,比如商品1,也可能包含兩種、三種或者所有四種的組合。當然,這裡我們并不關心顧客購買了3件商品0或者10件商品1的情況,而是更關注顧客購買一種或多種商品的組合。下圖11-2給出了物品組合的所有可能。
圖中物品編号代替物品本身。目标已經很清楚就是找到一起購買的物品組合。前面的方法是通過集合的支援度來度量其出現的頻率,具體計算過程如下:
一個集合的支援度是指有多少比例的交易記錄包含該集合。如何對一個給定集合,例如{0,3},來計算其支援度?周遊每一條記錄并查找包含0和3,如果記錄确實同時包含0和3,則增加總計數值。在掃描完所有資料之後,使用統計得到的總數除以總的交易記錄數即可得到其對應支援度。這裡還隻是針對集合{0,3}的支援度計算,如果要對每種可能集合的支援度計算,需要重複上面過程很多次。在圖11-2中,即使隻是針對隻有4種物品的集合,也需要周遊15次(2^N-1=2^4-1=15),顯然随着物品數目的增加周遊次數也在急劇增加。
為了降低計算的時間,相關人員發現了一種叫做Apriori算法原理。Aprirori原理可以幫助我們減少可能感興趣的項集。Apriori原理是講如果某個項集是頻繁的,則它的所有項集也是頻繁的。以圖11-2為例,如果{{1,2}是頻繁的,那麼{1}和{2}一定也是頻繁的。反之,如果一個項集是非頻繁的,則它的所有超集也是非頻繁的,如圖11-3所示。
這裡已知{2,3}是非頻繁的,是以{0,2,3}、{1,2,3}、{0,1,2,3}也是非頻繁的。換句話講,通過計算{2,3}的支援度我們得知其是非頻繁的,則後續的{0,2,3}、{1,2,3}、{0,1,2,3}就不必再計算對應支援度,因為它們已經不符合我們是要求。是以,使用Apriori算法原理可以避免項集數目指數級增加,進而在合理的時間内找到頻繁項集。
三、使用Apriori算法發現頻繁項集
前面提到,關聯分析的目标有兩個:發現頻繁項集和發現關聯規則。首先發現頻繁項集,然後再找到關聯規則。
Apriori算法是發現頻繁項集的一種方法。Apriori算法的兩個輸入參數分别是最小支援度和資料集。該算法首先會生成單個物品的項集清單。接着掃描交易記錄檢視哪些項集滿足最小支援度的要求,過濾掉不滿足最小支援度的集合。然後,對剩下的集合進行組合以生成包含兩個元素的項集。接着,再重複掃描交易記錄,過濾掉不滿足最小支援度的集合。該過程重複進行直到過濾掉所有項集。
1、 生成候選項集
建立一個用于建構初始集合的函數,也會建立一個通過掃描資料集以尋找交易記錄子集的函數,資料掃描僞代碼如下:
對資料集中的每條交易記錄tran
對每個候選項集can:
檢查下can是否是tran的子集: 如果是,則增加can 的計數值
對每個候選項集can:
如果其支援度不低于最小值,則保留該項集
傳回所有頻繁項集清單
輔助函數如下:
#加載資料集
def loadDataSet():
return [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]
#生成所有單個物品的項集清單
def createC1(dataSet):
C1 = []
for transaction in dataSet:
for item in transaction:
if not [item] in C1:
C1.append([item])
#對C1排序
C1.sort()
#use frozen set so we can use it as a key in a dict
list(map(frozenset,C1))
return list(map(frozenset, C1))
def scanD(D, Ck, minSupport):
ssCnt = {}
for tid in D:
for can in Ck:
if can.issubset(tid):
if not can in ssCnt: ssCnt[can]=1
else: ssCnt[can] += 1
numItems = float(len(D))
retList = []
supportData = {}
for key in ssCnt:
support = ssCnt[key]/numItems
if support >= minSupport:
retList.insert(0,key)
supportData[key] = support
return retList, supportData
執行
c =list(map(frozenset,c))
c
得到:
[frozenset({1}), frozenset({2}), frozenset({3})]
執行
d[c[0]] = 1
d[c[0]]
得到1
2、Apriori算法完整版
整個Apriori算法的僞代碼如下:
當集合中項的數目大于0時
建構一個k個項目組成的候選項集的清單
檢查資料以确認每個項集都是頻繁的
保留頻繁項集并建構k+1項組成的候選項集的清單
實作過程如下:
#creates Ck
def aprioriGen(Lk, k):
retList = []
lenLk = len(Lk)
for i in range(lenLk):
for j in range(i+1, lenLk):
#如果這兩個集合的前面k-2個元素都相等,那麼就将這兩個集合合成一個大小為k的集合
L1 = list(Lk[i])[:k-2]; L2 = list(Lk[j])[:k-2]
L1.sort(); L2.sort()
if L1==L2: #if first k-2 elements are equal
#set union
retList.append(Lk[i] | Lk[j])
return retList
def apriori(dataSet, minSupport = 0.5):
#生成所有單個物品的項集清單
C1 = createC1(dataSet)
D = list(map(set, dataSet))
L1, supportData = scanD(D, C1, minSupport)
L = [L1]
k = 2
#疊代L,直到L[k-1]為空
while (len(L[k-2]) > 0):
Ck = aprioriGen(L[k-2], k)
Lk, supK = scanD(D, Ck, minSupport)#scan DB to get Lk
supportData.update(supK)
L.append(Lk)
k += 1
return L, supportData
執行
dataSet =loadDataSet()
dataSet
得到
[[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]
執行
C1 =createC1(dataSet)
C1
得到
[frozenset({1}),
frozenset({2}),
frozenset({3}),
frozenset({4}),
frozenset({5})]
執行
D = list(map(set,dataSet))
D
得到
[{1, 3, 4}, {2, 3, 5}, {1, 2, 3, 5}, {2, 5}]
執行
L1, suppData0 =scanD(D,C1,0.5)
L1
得到
[frozenset({5}), frozenset({2}), frozenset({3}), frozenset({1})]
執行
suppData0
得到
{frozenset({1}): 0.5,
frozenset({3}): 0.75,
frozenset({2}): 0.75,
frozenset({5}): 0.75}
3、從頻繁項集中挖掘關聯規則
上面介紹了用于尋找頻繁項集的Apriori的算法,現在要解決的問題是如何找出關聯規則。
要找到關聯規則,首先要從一個頻繁項集開始。集合中的元素是不重複的,但我們想知道基于這些元素能否獲得其他内容。某個元素或某個元素集合可能會推導出另外一個元素。在上面提到的商店的例子中,若有一個頻繁項集{豆奶,莴苣},則就可能有一條關聯規則“豆奶”-->“莴苣”。這也就是說,從統計上來講,如果這個顧客購買了豆奶,那他同時會有很大的機率取購買莴苣。但是反過來不一定成立。也就是說,即使“豆奶”-->“莴苣”統計上顯著,但“莴苣”-->“豆奶”統計不一定成立。
前面已經講了頻繁項集的量化定義,即滿足最小支援度要求。同樣,對應關聯規則而言,也有其對應的量化名額,即可信度。一條規則X-→Y的可信度定義為support(X|Y)/support(X)。Python下,“|”表示集合的并操作,數學上集合并的符号是U。這裡X|Y是指所有出現在集合X或集合Y中的元素。
前面已經計算出了所有頻繁項集的支援度,接下來計算可信度。
一條頻繁項集可以産生多少條關聯規則呢?
下圖11-4所示,給出的是項集{0,1,2,3}産生的所有關聯規則。為了得到感興趣的規則,先生成一個可能的規則清單,然後,測試每條規則的可信度。若可信度不滿足最小要求,則去掉該條規則。
與上面提到的頻繁項集生成一樣,可以為每個頻繁項集生成多個關聯規則。通過減少關聯規則的數目且確定問題的可解性,可以大大減少計算工作量。如果某條規則不滿足最小可信度的要求,則該條規則的所有子集也不會滿足最小可信度的要求。以圖11-4為例,假如規則0,1,2-→3不滿足最小可信度要求,則可知任何左部為{0,1,2}子集的規則也不會滿足最小可信度要求。如圖11-4中陰影部分所示。即
12 -> 03
,
02-> 13
,
01 -> 23
,
2-> 013
,
1 -> 023
,
0-> 123
都不滿足最小可信度要求。
可以從一個頻繁項集開始,建構一個規則清單,其中規則右部隻包含一個元素,然後對這些規則進行測試。接下來合并剩餘所有規則來建構一個新的規則清單,其中規則右部包含兩個元素,這種方法被稱為分級法。
實作過程
#supportData is a dict coming from scanD
def generateRules(L, supportData, minConf=0.7):
bigRuleList = []
#only get the sets with two or more items
for i in range(1, len(L)):
for freqSet in L[i]:
H1 = [frozenset([item]) for item in freqSet]
if (i > 1):
rulesFromConseq(freqSet, H1, supportData, bigRuleList, minConf)
else:
calcConf(freqSet, H1, supportData, bigRuleList, minConf)
return bigRuleList
def calcConf(freqSet, H, supportData, brl, minConf=0.7):
#create new list to return
#存儲滿足最小可信度的規則的後件集合,以便之後再次合并時使用
prunedH = []
#對候選項集H進行疊代,選擇出符合最小可信度的關聯規則
for conseq in H:
conf = supportData[freqSet]/supportData[freqSet-conseq] #calc confidence
print(freqSet - conseq,freqSet,supportData[freqSet-conseq],supportData[freqSet])
if conf >= minConf:
print(freqSet-conseq,'-->',conseq,'conf:',conf)
brl.append((freqSet-conseq, conseq, conf))
prunedH.append(conseq)
return prunedH
def rulesFromConseq(freqSet, H, supportData, brl, minConf=0.7):
#擷取候選項集項數
m = len(H[0])
#try further merging
if (len(freqSet) > (m + 1)):
#create Hm+1 new candidates
Hmp1 = aprioriGen(H, m+1)
#得出滿足最小可信度的候選關聯規則
Hmp1 = calcConf(freqSet, Hmp1, supportData, brl, minConf)
if (len(Hmp1) > 1): #need at least two sets to merge
rulesFromConseq(freqSet, Hmp1, supportData, brl, minConf)
執行
dataSet =loadDataSet()
L, suppData =apriori(dataSet, minSupport = 0.5)
rulues =generateRules(L, suppData, minConf = 0.7)
得到
frozenset({3}) frozenset({2, 3}) 0.75 0.5
frozenset({2}) frozenset({2, 3}) 0.75 0.5
frozenset({5}) frozenset({3, 5}) 0.75 0.5
frozenset({3}) frozenset({3, 5}) 0.75 0.5
frozenset({5}) frozenset({2, 5}) 0.75 0.75
frozenset({5}) --> frozenset({2}) conf: 1.0
frozenset({2}) frozenset({2, 5}) 0.75 0.75
frozenset({2}) --> frozenset({5}) conf: 1.0
frozenset({3}) frozenset({1, 3}) 0.75 0.5
frozenset({1}) frozenset({1, 3}) 0.5 0.5
frozenset({1}) --> frozenset({3}) conf: 1.0
frozenset({5}) frozenset({2, 3, 5}) 0.75 0.5
frozenset({3}) frozenset({2, 3, 5}) 0.75 0.5
frozenset({2}) frozenset({2, 3, 5}) 0.75 0.5
執行rulues得到
[(frozenset({5}),frozenset({2}), 1.0),
(frozenset({2}), frozenset({5}), 1.0),
(frozenset({1}), frozenset({3}), 1.0)]
執行
rules = generateRules(L, suppData, minConf = 0.5)
得到
frozenset({3}) frozenset({2, 3}) 0.75 0.5
frozenset({3}) --> frozenset({2}) conf: 0.6666666666666666
frozenset({2}) frozenset({2, 3}) 0.75 0.5
frozenset({2}) --> frozenset({3}) conf: 0.6666666666666666
frozenset({5}) frozenset({3, 5}) 0.75 0.5
frozenset({5}) --> frozenset({3}) conf: 0.6666666666666666
frozenset({3}) frozenset({3, 5}) 0.75 0.5
frozenset({3}) --> frozenset({5}) conf: 0.6666666666666666
frozenset({5}) frozenset({2, 5}) 0.75 0.75
frozenset({5}) --> frozenset({2}) conf: 1.0
frozenset({2}) frozenset({2, 5}) 0.75 0.75
frozenset({2}) --> frozenset({5}) conf: 1.0
frozenset({3}) frozenset({1, 3}) 0.75 0.5
frozenset({3}) --> frozenset({1}) conf: 0.6666666666666666
frozenset({1}) frozenset({1, 3}) 0.5 0.5
frozenset({1}) --> frozenset({3}) conf: 1.0
frozenset({5}) frozenset({2, 3, 5}) 0.75 0.5
frozenset({5}) --> frozenset({2, 3}) conf: 0.6666666666666666
frozenset({3}) frozenset({2, 3, 5}) 0.75 0.5
frozenset({3}) --> frozenset({2, 5}) conf: 0.6666666666666666
frozenset({2}) frozenset({2, 3, 5}) 0.75 0.5
frozenset({2}) --> frozenset({3, 5}) conf: 0.6666666666666666
執行rulues
得到
[(frozenset({3}), frozenset({2}), 0.6666666666666666),
(frozenset({2}), frozenset({3}), 0.6666666666666666),
(frozenset({5}), frozenset({3}), 0.6666666666666666),
(frozenset({3}), frozenset({5}), 0.6666666666666666),
(frozenset({5}), frozenset({2}), 1.0),
(frozenset({2}), frozenset({5}), 1.0),
(frozenset({3}), frozenset({1}), 0.6666666666666666),
(frozenset({1}), frozenset({3}), 1.0),
(frozenset({5}), frozenset({2, 3}), 0.6666666666666666),
(frozenset({3}), frozenset({2, 5}), 0.6666666666666666),
(frozenset({2}), frozenset({3, 5}), 0.6666666666666666)]
四、發現毒蘑菇案例
1、項目背景
有一個關于肋形蘑菇的23種特征的資料集,每一個特征都包含一個标稱資料值。RobertoBayardo對蘑菇資料集進行了解析,将每個蘑菇樣本轉換成一個特征集合。其中,枚舉了每個特征的所有可能值,
若某個樣本包含特征,則該特征對應的整數值被包含在資料集中。第一個特征表示有毒或可食。若樣本有毒,則值為2;可食則值為1。下一個特征是蘑菇傘的形狀,有6種可能值,分别用3-8整數來表示。
2、樣本形式
3、模型實作
為了找到蘑菇中存在的公共特征,可以運作Apriori算法來尋找包含特征值為2的頻繁項集。
mushDataSet =[ line.split() for line in open('mushroom.dat').readlines()]
在資料集上運作Apriori算法
L , suppData =apriori(mushDataSet , minSupport = 0.3)
在結果中搜尋包含有毒特征值2的頻繁項集
for item in L[1]:
ifitem.intersection('2'):print(item)
得到結果
frozenset({'2', '28'})
frozenset({'53', '2'})
frozenset({'23', '2'})
frozenset({'34', '2'})
frozenset({'36', '2'})
frozenset({'59', '2'})
frozenset({'63', '2'})
frozenset({'2', '67'})
frozenset({'76', '2'})
frozenset({'85', '2'})
frozenset({'2', '86'})
frozenset({'2', '90'})
frozenset({'2', '93'})
frozenset({'2', '39'})
也可以對更大的項集進行重複上述過程
for item in L[3]:
ifitem.intersection('2'):print(item)
得到
frozenset({'2', '28', '34', '39'})
frozenset({'2', '28', '86', '34'})
frozenset({'2', '28', '34', '90'})
frozenset({'2', '28', '34', '63'})
frozenset({'2', '28', '34', '85'})
frozenset({'2', '28', '59', '39'})
frozenset({'2', '28', '59', '34'})
frozenset({'2', '28', '86', '59'})
frozenset({'2', '28', '59', '90'})
frozenset({'2', '28', '59', '63'})
frozenset({'2', '28', '59', '85'})
frozenset({'2', '28', '63', '39'})
frozenset({'2', '28', '86', '63'})
frozenset({'2', '28', '63', '85'})
frozenset({'2', '28', '85', '39'})
frozenset({'2', '28', '86', '85'})
frozenset({'2', '28', '85', '90'})
frozenset({'2', '28', '86', '90'})
frozenset({'2', '28', '86', '39'})
frozenset({'2', '28', '39', '90'})
frozenset({'2', '28', '34', '53'})
frozenset({'2', '34', '53', '39'})
frozenset({'2', '34', '53', '85'})
frozenset({'2', '86', '34', '53'})
frozenset({'2', '34', '53', '90'})
frozenset({'2', '86', '53', '85'})
frozenset({'2', '53', '85', '90'})
frozenset({'2', '53', '85', '39'})
frozenset({'2', '28', '53', '85'})
frozenset({'2', '86', '53', '90'})
frozenset({'2', '86', '53', '39'})
frozenset({'2', '53', '39', '90'})
frozenset({'2', '28', '86', '53'})
frozenset({'2', '28', '53', '90'})
frozenset({'2', '28', '53', '39'})
frozenset({'36', '2', '23', '85'})
frozenset({'36', '2', '86', '23'})
frozenset({'36', '2', '23', '93'})
frozenset({'36', '2', '23', '63'})
frozenset({'2', '23', '63', '85'})
frozenset({'2', '86', '23', '63'})
frozenset({'2', '86', '23', '85'})
frozenset({'2', '23', '85', '90'})
frozenset({'2', '23', '85', '93'})
frozenset({'2', '86', '23', '39'})
frozenset({'2', '86', '23', '90'})
frozenset({'2', '23', '39', '93'})
frozenset({'2', '86', '23', '93'})
frozenset({'2', '90', '23', '93'})
frozenset({'2', '34', '39', '23'})
frozenset({'36', '2', '34', '23'})
frozenset({'36', '2', '34', '85'})
frozenset({'36', '2', '86', '34'})
frozenset({'36', '2', '34', '90'})
frozenset({'36', '2', '34', '93'})
frozenset({'2', '34', '63', '23'})
frozenset({'36', '2', '34', '63'})
frozenset({'2', '34', '63', '85'})
frozenset({'2', '86', '34', '63'})
frozenset({'2', '34', '63', '90'})
frozenset({'2', '34', '63', '93'})
frozenset({'2', '67', '34', '39'})
frozenset({'2', '34', '76', '85'})
frozenset({'2', '86', '34', '76'})
frozenset({'2', '34', '85', '23'})
frozenset({'2', '67', '34', '85'})
frozenset({'2', '86', '34', '85'})
frozenset({'2', '34', '85', '90'})
frozenset({'2', '34', '85', '93'})
frozenset({'2', '86', '34', '39'})
frozenset({'2', '86', '34', '23'})
frozenset({'67', '2', '86', '34'})
frozenset({'2', '34', '39', '90'})
frozenset({'2', '34', '23', '90'})
frozenset({'2', '86', '34', '90'})
frozenset({'2', '34', '39', '93'})
frozenset({'2', '34', '23', '93'})
frozenset({'2', '86', '34', '93'})
frozenset({'2', '90', '34', '93'})
frozenset({'36', '2', '86', '39'})
frozenset({'36', '2', '39', '90'})
frozenset({'36', '2', '86', '90'})
frozenset({'36', '2', '39', '93'})
frozenset({'36', '2', '86', '93'})
frozenset({'36', '2', '90', '93'})
frozenset({'2', '59', '39', '23'})
frozenset({'2', '59', '39', '34'})
frozenset({'2', '59', '23', '34'})
frozenset({'36', '2', '59', '23'})
frozenset({'36', '2', '59', '34'})
frozenset({'36', '2', '59', '85'})
frozenset({'36', '2', '86', '59'})
frozenset({'36', '2', '59', '90'})
frozenset({'36', '2', '59', '93'})
frozenset({'2', '59', '63', '23'})
frozenset({'2', '59', '63', '34'})
frozenset({'36', '2', '59', '63'})
frozenset({'2', '59', '63', '85'})
frozenset({'2', '86', '59', '63'})
frozenset({'2', '59', '63', '90'})
frozenset({'2', '59', '63', '93'})
frozenset({'2', '59', '85', '23'})
frozenset({'2', '59', '85', '34'})
frozenset({'2', '86', '59', '85'})
frozenset({'2', '59', '85', '90'})
frozenset({'2', '59', '85', '93'})
frozenset({'2', '86', '59', '39'})
frozenset({'2', '86', '59', '23'})
frozenset({'2', '86', '59', '34'})
frozenset({'2', '59', '39', '90'})
frozenset({'2', '59', '23', '90'})
frozenset({'2', '59', '34', '90'})
frozenset({'2', '86', '59', '90'})
frozenset({'2', '59', '39', '93'})
frozenset({'2', '59', '23', '93'})
frozenset({'2', '59', '34', '93'})
frozenset({'2', '86', '59', '93'})
frozenset({'2', '90', '59', '93'})
frozenset({'36', '2', '63', '85'})
frozenset({'36', '2', '86', '63'})
frozenset({'36', '2', '63', '90'})
frozenset({'36', '2', '63', '93'})
frozenset({'2', '86', '63', '85'})
frozenset({'2', '63', '85', '90'})
frozenset({'2', '63', '85', '93'})
frozenset({'2', '86', '63', '39'})
frozenset({'2', '63', '39', '90'})
frozenset({'2', '86', '63', '90'})
frozenset({'2', '63', '39', '93'})
frozenset({'2', '86', '63', '93'})
frozenset({'2', '90', '63', '93'})
frozenset({'2', '86', '76', '85'})
frozenset({'2', '86', '76', '39'})
frozenset({'36', '2', '85', '39'})
frozenset({'2', '67', '85', '39'})
frozenset({'2', '86', '85', '39'})
frozenset({'36', '2', '86', '85'})
frozenset({'67', '2', '86', '85'})
frozenset({'2', '85', '39', '90'})
frozenset({'36', '2', '85', '90'})
frozenset({'2', '86', '85', '90'})
frozenset({'2', '85', '39', '93'})
frozenset({'36', '2', '85', '93'})
frozenset({'2', '86', '85', '93'})
frozenset({'2', '90', '85', '93'})
frozenset({'67', '2', '86', '39'})
frozenset({'2', '90', '86', '93'})
frozenset({'2', '86', '39', '90'})
frozenset({'2', '86', '39', '93'})
frozenset({'2', '90', '39', '93'})
frozenset({'36', '2', '23', '39'})
frozenset({'2', '23', '63', '39'})
frozenset({'2', '23', '85', '39'})
frozenset({'36', '2', '34', '39'})
frozenset({'2', '34', '63', '39'})
frozenset({'2', '34', '76', '39'})
frozenset({'2', '34', '85', '39'})
frozenset({'36', '2', '59', '39'})
frozenset({'2', '59', '63', '39'})
frozenset({'2', '59', '85', '39'})
frozenset({'36', '2', '63', '39'})
frozenset({'2', '63', '85', '39'})
frozenset({'2', '76', '85', '39'})
五、小結
關聯分析是用于發現大資料集中元素間有趣關系的一種工具集,可以采用兩種方式來量化這些有趣的關系。第一種方式是使用頻繁項集,它會給出經常在一起出現的元素項。第二種方式是關聯規則,每條關聯規則意味着元素項之間的“如果...那麼...”關系。
發現元素項間不同的組合是十分耗時的工作任務,這就需要占用大量的計算資源,是以采用更智能的方法在合理的時間範圍内找到頻繁項集為其解決之道。而Apriori算法正是實作此目标的一種方法,它可以使用自身原理減少在資料庫上進行檢查的集合數目。Apriori原理是:如果一個元素項是不頻繁的,則所有包含該元素的超集也是不頻繁的。Apriori算法從單元素項集開始,通過組合滿足最小支援度要求的項集形式來形成更大的集合。支援度用來度量一個集合在原始資料中出現的頻率。
每次增加頻繁項集的大小,Apriori算法都會重新掃描整個資料集。當資料集很大時,就會顯著降低發現頻繁項集的速度。