关联规则Apriori算法
參考《【機器學習實戰-python3】使用Apriori算法進行關聯 分析》,《 使用Apriori進行關聯分析(一)》,《使用Apriori進行關聯分析(二)》,《關于apriori算法中置信度、支持度怎么理解的問題》
文章目錄
- 1. 頻繁項集(frequent item sets)
- 1.1 頻繁項集的支持度(support)和閾值
- 1.2 頻繁項集的特點
- 1.3 頻繁項集支持度計算方法
- 2. 關聯規則挖掘(association rules)
- 2.1 關聯規則的置信度(confidence)
- 2.2 關聯規則置信度的計算過程
- 3. 為什么需要置信度和支持度同時確定關聯規則
關聯規則的目的在于分析出經常出現在一起的物品的集合之間的關系。Apriori算法本質由兩部分組成,分別是
接下來分別對這幾個名詞進行講解,同時串通整個Apriori算法。
1. 頻繁項集(frequent item sets)
假設下表為一個超市的交易記錄,其中交易ID可以看作每個前來購物的顧客,商品列表就是每個顧客購買的商品。
| 0 | P1, P2, P5 |
| 1 | P2, P4 |
| 2 | P2, P3 |
| 3 | P1, P2, P4 |
| 4 | P1, P3 |
| 5 | P2, P3 |
| 6 | P1, P3 |
| 7 | P1, P2, P3, P5 |
| 8 | P1, P2, P3 |
單是肉眼去觀察的話,似乎顧客經常購買P1, P2這樣的組合。這種的購物中出現的經常的組合,就是我們要找的頻繁項集了。項集可以由一個商品組成,也可以由多個商品組成。比如{P1}是一個項集,{P1, P2}也是一個項集。
現實生活中的數據肯定比這更加龐大,因此需要使用算法來幫助我們篩選出來哪些是頻繁項集。
1.1 頻繁項集的支持度(support)和閾值
一個項集的支持度被定義為數據集中包含該項集的記錄所占的比例,比如在上表中,9個顧客中有4個購買了P1商品和P2商品,項集{P1, P2}的支持度就是4/9=0.444/9=0.444/9=0.44,支持項就是4項.
通常來說,我們會手動設置支持度的閾值。比如設置閾值為50%,這樣支持度小于該閾值的時候,就認為該項集并不頻繁,也就沒有挖掘關聯規則的意義,因此不會進行后續的計算。
1.2 頻繁項集的特點
頻繁項集擁有如下特點:**如果某個項集是頻繁的,那么它的所有子集也是頻繁的。**比如項集{P1, P2}是頻繁的,那么項集{P1}和{P2}也是頻繁的。該原理倒過來推并不成立,也就是說當我們 只發現{P1}和{P2}是頻繁的的時候,是無法推出項集{P1, P2}是頻繁的,因為有可能他們的頻繁是依靠和別的商品一起購買組合而成的。該原理可以用下圖表示
已知陰影項集{2,3}是非頻繁的。利用這個知識,我們就知道項集{0,2,3} ,{1,2,3}以及{0,1,2,3}也是非頻繁的。該特點的最大用處是幫助我們減少計算,一旦計算出了{2,3}的支持度,知道它是非頻繁的之后,就不需要再計算{0,2,3}、{1,2,3}和{0,1,2,3}的支持度,因為我們知道這些集合不會滿足我們的要求。使用該原理就可以避免項集數目的指數增長,從而在合理時間內計算出頻繁項集。
1.3 頻繁項集支持度計算方法
頻繁項集的計算方法并不復雜,主要就是三步的不斷循環。
具體代碼如下
def loadDataSet():return [[1,2,5],[2,4],[2,3],[1,2,4],[1,3],[2,3],[1,3],[1,2,3,5],[1,2,3]] #1.構建候選1項集C1 def createC1(dataSet):C1 = []for transaction in dataSet:for item in transaction:if not [item] in C1:C1.append([item])C1.sort()return list(map(frozenset, C1))#將候選集Ck轉換為頻繁項集Lk #D:原始數據集 #Cn: 候選集項Ck #minSupport:支持度的最小值 def scanD(D, Ck, minSupport):#候選集計數ssCnt = {}for tid in D:for can in Ck:if can.issubset(tid):if can not in ssCnt.keys(): ssCnt[can] = 1else: ssCnt[can] += 1numItems = float(len(D))Lk= [] # 候選集項Cn生成的頻繁項集LksupportData = {} #候選集項Cn的支持度字典#計算候選項集的支持度, supportData key:候選項, value:支持度for key in ssCnt:support = ssCnt[key] / numItemsif support >= minSupport:Lk.append(key)supportData[key] = supportreturn Lk, supportData#連接操作,將頻繁Lk-1項集通過拼接轉換為候選k項集 def aprioriGen(Lk_1, k):Ck = []lenLk = len(Lk_1)for i in range(lenLk):L1 = list(Lk_1[i])[:k - 2]L1.sort()for j in range(i + 1, lenLk):#前k-2個項相同時,將兩個集合合并L2 = list(Lk_1[j])[:k - 2]L2.sort()if L1 == L2:Ck.append(Lk_1[i] | Lk_1[j])return Ckdef apriori(dataSet, minSupport = 0.5):C1 = createC1(dataSet)L1, supportData = scanD(dataSet, C1, minSupport)L = [L1]k = 2while (len(L[k-2]) > 0):Lk_1 = L[k-2]Ck = aprioriGen(Lk_1, k)print("ck:",Ck)Lk, supK = scanD(dataSet, Ck, minSupport)supportData.update(supK)print("lk:", Lk)L.append(Lk)k += 1return L, supportDatadataset = loadDataSet() L, supportData = apriori(dataset, minSupport=0.2)最終輸出如下,其中ck就是頻繁項候選集,lk就是經過閾值篩選后得到的新的頻繁項候選集。該結果與上圖一致。
ck: [frozenset({1, 2}), frozenset({1, 5}), frozenset({1, 4}), frozenset({1, 3}), frozenset({2, 5}), frozenset({2, 4}), frozenset({2, 3}), frozenset({4, 5}), frozenset({3, 5}), frozenset({3, 4})] lk: [frozenset({1, 2}), frozenset({1, 5}), frozenset({2, 5}), frozenset({2, 4}), frozenset({2, 3}), frozenset({1, 3})] ck: [frozenset({1, 2, 5}), frozenset({1, 2, 3}), frozenset({1, 3, 5}), frozenset({2, 4, 5}), frozenset({2, 3, 5}), frozenset({2, 3, 4})] lk: [frozenset({1, 2, 5}), frozenset({1, 2, 3})] ck: [frozenset({1, 2, 3, 5})] lk: []需要注意的是,在上述代碼的aprioriGen方法中,假定購買商品是有順序的,可以通過頻繁2項集{P1,P2},{P1,P3}推導出頻繁項{P1,P2,P3},但是不能通過頻繁2項集{P3,P4},{P1,P3}推導出頻繁項{P1,P3,P4}。如果去掉假設,則需要修改aprioriGen的代碼:
#將頻繁Lk-1項集轉換為候選k項集 def aprioriGen(Lk_1, k):Ck = []lenLk = len(Lk_1)for i in range(lenLk):L1 = Lk_1[i]for j in range(i + 1, lenLk):L2 = Lk_1[j]if len(L1 & L2) == k - 2:L1_2 = L1 | L2if L1_2 not in Ck:Ck.append(L1 | L2)return Ck2. 關聯規則挖掘(association rules)
2.1 關聯規則的置信度(confidence)
我們的目的是根據頻繁項集挖掘出關聯規則。關聯規則的意思就是通過某個項集可以推導出另一個項集。比如一個頻繁項集{P1, P2, P3},就可以推導出六個可能的關聯規則。其中置信度最高的就是最有可能的關聯規則。
- {P1} → {P2, P3}
- {P2} → {P1, P3}
- {P3} → {P1, P2}
- {P1, P2} → {P3}
- {P2, P3} → {P1}
- {P1, P3} → {P2}
箭頭左邊的集合稱為“前件”,右邊集合稱為“后件”,根據前件會有較大概率推導出后件,這個概率就是之前提到的置信度(confidence)。需要注意的是,如果A→B成立,B→A不一定成立。
一個具有N個元素的頻繁項集,共有M個可能的關聯規則:
M=∑N?1i=1CNiM = \sum_{N-1}^{i=1}C_N^i M=N?1∑i=1?CNi?
下圖是一個頻繁4項集的所有關聯規則網格示意圖
M=C41+C42+C43=14M = C_4^1+C_4^2+C_4^3=14 M=C41?+C42?+C43?=14
上圖中深色區域表示低可信度規則,如果012→3是一條低可信度規則,則所有其它3為后件的規則都是低可信度。這需要從可信度的概念去理解
- Confidence(012→3) = P(3|0,1,2)
- Confidence(01→23) = P(2,3|0,1)
- P(3|0,1,2) >= P(2,3|0,1)
由此可以對關聯規則做剪枝處理。
2.2 關聯規則置信度的計算過程
置信度的計算公式為
置信度=頻繁項集的出現數量某可能規則的出現數量置信度 =\frac{頻繁項集的出現數量}{某可能規則的出現數量} 置信度=某可能規則的出現數量頻繁項集的出現數量?
還是以上篇的超市交易數據為例,我們發現了如下的頻繁項集:
對于尋找關聯規則來說,頻繁1項集L1沒有用處,因為L1中的每個集合僅有一個數據項,至少有兩個數據項才能生成A→B這樣的關聯規則。
當最小置信度取0.5時,L2最終能夠挖掘出9條關聯規則:
以P2->P1為例,在本文最上面的表格中,P2出現了7次,頻繁項集{P1, P2}的出現次數為4次,因此P2->P1的支持度就是4/7。同理,P1出現了6次,那么P1->P2的支持度就是4/6.
從頻繁3項集開始,挖掘的過程就較為復雜,要計算如{P1, P2}這樣的復合頻繁項集后件,并分別計算置信度。
假設有一個頻繁4項集(這是杜撰的,文中的數據不能生成L4),其挖掘過程如下:
發掘關聯規則的代碼如下
得到的結果如下所示
frozenset({5}) --> frozenset({1}) conf: 1.0 frozenset({5}) --> frozenset({2}) conf: 1.0 frozenset({4}) --> frozenset({2}) conf: 1.0 frozenset({5}) --> frozenset({1, 2}) conf: 1.0 [(frozenset({5}), frozenset({1}), 1.0),(frozenset({5}), frozenset({2}), 1.0),(frozenset({4}), frozenset({2}), 1.0),(frozenset({5}), frozenset({1, 2}), 1.0)]3. 為什么需要置信度和支持度同時確定關聯規則
以超市購物為例。
| 1 | Bread, Milk |
| 2 | Break, Diaper, Beer, Eggs |
| 3 | Milk, Diaper, Beer, Coke |
| 4 | Bread, Milk, Diaper, Beer |
| 5 | Bread, Milk, Diaper, Coke |
TID是transaction ID 即交易編號,也就是有五個人在超市買了這樣的東西(Iteams),現在我們統計一下,大家買的東西之間有沒有什么規律,比如買面包的是不是很可能同時買牛奶這樣的規律。
在這里,支持度的計算過程為
support=σ(Milk,Diaper,Beer)∣T∣=25=0.4support =\frac{\sigma(Milk, Diaper, Beer)}{|T|} = \frac{2}{5}=0.4 support=∣T∣σ(Milk,Diaper,Beer)?=52?=0.4
支持度越大,說明同時買這三個東西的人多,說明這三者之間有關系.
但是當交易量特別大的時候,假如有一萬個人買東西,只有10個人同時買了Milk、Diaper、Beer,但其他9990個人沒有買這三者中的任何一個,那么此時S=10/10000=0.001。如果僅從這個0.001看,這三者之間沒有任何關系,但是事實卻不是這樣,因為只有十個人這樣買,并且同時買了這三種東西,所以他們之間應該是由關系的,而不是偶然。
引入置信度的概念后,比如我們想看{Milk, Diaper}→{Beer}的置信度,則計算過程為
confidence=σ(Milk,Diaper,Beer)σ(Milk,Diaper)=23=0.67confidence=\frac{\sigma(Milk, Diaper, Beer)}{\sigma(Milk, Diaper)} = \frac{2}{3}=0.67 confidence=σ(Milk,Diaper)σ(Milk,Diaper,Beer)?=32?=0.67
和S支持度比較只有分母變了,變成了買了Milk和Diaper兩種東西的人,這個式子是說買了Milk和Diaper兩種東西的人里面又有多少人買了Beer這個東西!
在上面支持度為0.001的情況下,此時置信度=10/10=100%!足以說明兩者之間的關聯性。
但是只有置信度也是不可行的,比如10000個訂單中,只有一個人同時購買了Milk,Diaper和Bear,那么此時的置信度為1/1=100%!可是支持度只有0.0001,非常的小。
所以正確的有關聯的判定是:置信度和支持度都應該比較大才可以認為這些東西之間有關聯!
總結
以上是生活随笔為你收集整理的关联规则Apriori算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HR团队如何提升效率?人力资源RPA给你
- 下一篇: 大数据领域十大必读书籍