1. 程式人生 > >基於R的資料探勘方法與實踐(2)——關聯規則

基於R的資料探勘方法與實踐(2)——關聯規則

關聯規則是從龐大的資料中提取一系列變數或因子間關係,以探索資料的變數或專案間隱含的關係。

1、基本原理

關聯規則通常用支援度、置信度、增益三個指標來分別表示其顯著性、正確性和價值。通過給性最小支援度、最小置信度作為門檻值。若該規則的支援度與置信度大於門檻值,則說明該規則有助於進行推論;若該規則的增益大於1,則說明其發生的條件概率有比原先的概率提高,即該規則有效。

1.1 支援度

支援度計算公式如下:

支援度 = P(X∩Y)

以下表中的資料為例。

交易記錄

牛奶

麵包

餅乾

橙汁

汽水

泡麵

水果

201701101

1

1

1

1

0

0

0

201701102

0

1

1

0

1

1

0

201701103

1

0

1

0

0

0

1

201701104

1

1

0

1

0

1

1

201701105

0

0

1

0

1

0

1

要了解顧客同時購買牛奶和麵包的規則是否具有顯著性,可以通過支援度衡量,即計算顧客同時購買牛奶和麵包的概率:

P(麵包∩牛奶) = 2/5 = 0.4

1.2 置信度

置信度是衡量一個事件發生的情況下,另一個事件發生的條件概率,即P(Y|X)。

P(Y|X)= P(X∩Y)/P(X)

一般情況下,置信度需要大於0.5。

如果想要了解規則“顧客在購買牛奶後也會購買麵包”的信心程度,則可以用置信度:

P(麵包|牛奶) = P(麵包∩牛奶) / P(牛奶) = 0.4/0.6 = 0.67

1.3 增益

增益用於比較置信度與事件Y單獨發生兩者之間的概率。增益至少要大於1,才能說明事件X對事件Y的發生有促進作用。

lift= P(Y|X)/P(Y) = P(X∩Y)/[P(X)P(Y)]

規則“顧客在購買牛奶後也會購買麵包”的增益計算如下:

lift(牛奶 -> 麵包) = P(麵包|牛奶) / P(麵包) = P(麵包∩牛奶) / [P(牛奶)P(麵包)] = 0.4/[0.6*0.6] = 1.11

2、關聯規則的分類

2.1以規則中屬性的型別分類

當關聯規則中的屬性都是布林值得時候,稱為布林關聯規則。上面我們討論購買麵包與牛奶的問題,是典型的布林關聯規則。

當所要描述的規則的屬性值是數量的時候,則稱為量化的關聯規則。對於量化的關聯規則,可以通過數值的區間劃分和歸類轉化為布林屬性。

2.2以規則中的資料維度分類

若規則是針對單一維度的時候,稱之為單一維度關聯規則。如規則“顧客在購買牛奶後也會購買麵包”。

若規則是針對兩個或兩個以上維度的,則稱為多維度關聯規則或複合關聯規則。如規則“三十歲以上單身男性工程師會購買海外基金”。

2.3以規則中的層級分類

若規則屬性或專案屬於同一層級,則稱為單一層級關聯規則。如規則“顧客在購買牛奶後也會購買麵包”。

若資料同時包含較低層級和較高層級的專案集集合,則應該建立層級樹,然後進行關聯規則分析。當較低層級的專案集合不易發現關聯規則時,則可以升級為較高的層級,以發現較明顯的關聯規則。這種關聯規則,可以稱為多層級關聯規則。

3、關聯規則的演算法

關聯規則的演算法主要由搜尋方式、計算專案及支援度組成。

3.1Apriori演算法

Apriori演算法是挖掘高頻專案及的布林值關聯規則中最具代表性的演算法,隨後發展的關聯規則演算法大都以其為基礎。該演算法在大量的資料集中,利用專案集來建立關聯規則,並計算每一個候選專案出現的次數,依據所設定的最小支援度為門檻,來衡量候選專案的關聯規則是否顯著。

Apriori演算法分為5步:

(1)設定k = 1。快速掃描事務資料庫,找出所有的1-專案集,與所規定的最小支援度門檻比較,高於最小支援度門檻的作為高頻1-專案集,記為L1

(2)設定k = k + 1併產生新的候選k-專案集。刪除候選k-專案集中所有k-1子專案集不屬於L1的候選專案集,並將過濾之後的k-專案集記為Ck

(3)計算Ck中專案集各自的支援度S是否大於或等於規定的最小支援度,得到高頻k-專案集。

(4)判定是否已搜尋過所有的候選專案集,若已搜尋完所有可能的候選集,則繼續步驟(5);否則,回到步驟(2)。

(5)計算所搜尋專案集的置信度和增益,找出顯著性的關聯規則以幫助決策者指定相關決策。

Apriori演算法的缺點是逐層擴充套件候選專案集必須大量地重複搜尋資料庫,因此當高頻專案集長度較長或者數量較多時,必須花費較長時間來挑選產生候選專案集。

3.2Partition演算法

為改善Apriori演算法搜尋效率不高的問題,Partition演算法將資料庫D分割成許多區段Pi,然連後進行掃描找出高頻專案集,以建立顯著關聯規則。具體步驟為:

(1)將資料庫分成互不相交的區段。分別計算各區段的相關專案集合支援度,找出各區段的高頻專案集,稱為區域高頻專案集。每次讀取一個分割區段Pi,採用Apriori演算法找出區域高頻專案集集合,記為LPi

(2)取所有區域高頻專案集的並集,即{LP1∪LP2∪…∪LPn},作為D的整體候選專案集集合。對D重新計算該候選專案集的支援度,找出真正的高頻專案集。

Partition演算法的優點是大幅提高了搜尋效率,缺點是在各區段產生了太多的非相關專案集時,需要大量的儲存空間。

3.3 DHP演算法

DHP演算法利用雜湊樹的構建,設計一個雜湊函式,將資料庫中的專案集對應到散列表中,以累計各雜湊階層所包含專案集的個數,並以累計的階層數粗略估算候選專案集的支援度,以提前刪除不可能稱為高頻專案集的候選專案集。具體步驟如下:

(1)設定k = 1。規定支援度與置信度的門檻值,搜尋整個資料庫D,找出高頻1-專案集L1,並建立2-專案集的散列表,記為H2

(2)設定k = k + 1;利用Lk-1產生專案集集合Ck,先用散列表中各階層的累積次數對Ck進行初步篩選,在計算篩選後的各k-專案集支援度以決定高頻專案集集合Lk

(3)不斷地重複上一步驟,知道所有高頻專案集合Lk都無法再往上一階層產生Ck+1

DHP演算法可以免除大量不必要的低階層(特別是第二階層)候選專案集篩選。其缺點是一開始必須花一些時間來建立散列表,且會導致初期有較高的誤判率。

3.4 MSApriori演算法

MSApriori演算法中,關聯規則最小支援度為該規則內所有專案集對應的最小支援度的最小值。分析者可以對具有較高價值的專案規定較低的支援度門檻,對價值較低的專案規定較高的支援度門檻。具體步驟如下:

(1)規定個專案的最小支援度門檻(MIS),並將所有專案按MIS遞增排列。

(2)掃描所有的專案,找出符合最小支援度的候選1-專案集,記為F1,並篩選F1得到高頻1-專案集L1。其中F1中的專案支援度都在min{MIS}以上,而L1中的專案都在各自的最小支援度以上。

(3)產生其他候選專案集,方法與Apriori演算法類似,以遞迴方式找出各階層的候選專案集以及高頻專案集。

3.5FP-Growth演算法

繁殖模式增長(FP-Growth)演算法是目前最有效率的關聯規則演算法。該演算法將資料庫內含有的頻繁專案集壓縮到一顆頻繁模式樹種,並保留專案集之間的重要關聯資訊。次方法在挖掘時不需要產生大量的候選專案集,最多隻需掃描資料庫兩次,因此可大量減少IO時間,於單一維度及布林值的領域中,都能以相當有效率的搜尋方式建立關聯規則。FP-Growth演算法可以分為兩個階段:

(1)建立FP-tree

i) 第一次掃描資料庫,找出符合最小支援度的第一階高頻專案集L1 = {{A},{B},{C},{F}},依照支援度大小降序排列。得到的結果如下表所示:

交易記錄

專案

屬於高頻專案集並按支援度大小排序

10001

A, B, D, E, F, G

{B}, {A}, {F}

10002

B, C, D, F

{B}, {C}, {F}

10003

A, B, C, F

{B}, {A}, {C}, {F}

10004

A, B, C, G

{B}, {A}, {C}

ii)建立FP-tree的根節點,表示為空節點,然後再次掃描資料庫,將屬於高頻專案集的交易記錄按步驟(1)所排列的專案順序加入FP-tree中,直至所有高頻專案集均經過掃描且建立連線關係,完成第二次掃描資料庫的步驟。

iii) 為使得FP-tree更容易解讀,建立專案連線表,使每個專案可通過一個節點鏈指出該葉節點在樹種出現的位置,使樹形圖更為清晰。

(2)以FP-Growth演算法針對該樹中所隱含的規則進行挖掘。

i) 由專案連線表中的專案欄自下而上按照葉節點X坐落的順序挖掘,按照每個關聯專案連線FP-tree,找出FP-tree中X葉節點的字首路徑,而X葉節點的字首路徑所構建的FP-tree即為X的條件頻繁模式樹(簡稱X的條件FP-tree)。

ii) 以相同的方法遞迴挖掘X的條件FP-tree,計算模式庫中每個專案的支援度,找出非空集合且具有高頻專案集特徵的專案集合,用模式庫中的高頻專案與X組合成高頻專案集,列於候選專案集中。

iii) 運用階段一與階段二的模式不斷對FP-tree遞迴挖掘,找出包含該葉節點的所有字首路徑,直到所有的葉節點均不存在任何字首路徑。

專案集

字首路徑

挖掘出的高頻專案集

{F}

({B}{A}{C})

({B}{A})

({B}{C})

{F}

{B, F}

{C}

({B}{A})

({B})

{C}

{B,C}

{A}

({B})

{A}

{B,A}

{B}

ø

{B}

4、關聯規則的應用

以arules包中的IncomeESL資料為例,開展關聯規則分析。

> IncomeESL <- IncomeESL[complete.cases(IncomeESL),] #刪除包含缺失值的資料
> dim(IncomeESL) #檢視刪除缺失值之後的IncomeESL的資料維度
[1] 6876   14
> IncomeESL.tr <- as(IncomeESL, "transactions") #關聯規則分析必須使用transactions格式的資料,因此採用as()將data.frame資料轉換為transactions物件
> rules <- apriori(IncomeESL.tr, parameter = list(support = 0.1, confidence = 0.6)) #採用Apriori演算法進行關聯規則分析,將支援度設為0.1、置信度設為0.6
Apriori

Parameter specification:
 confidence minval smax arem  aval originalSupport maxtime support minlen maxlen target   ext
        0.6    0.1    1 none FALSE            TRUE       5     0.1      1     10  rules FALSE

Algorithmic control:
 filter tree heap memopt load sort verbose
    0.1 TRUE TRUE  FALSE TRUE    2    TRUE

Absolute minimum support count: 687 

set item appearances ...[0 item(s)] done [0.00s].
set transactions ...[84 item(s), 6876 transaction(s)] done [0.00s].
sorting and recoding items ... [42 item(s)] done [0.00s].
creating transaction tree ... done [0.00s].
checking subsets of size 1 2 3 4 5 6 done [0.02s].
writing ... [2360 rule(s)] done [0.00s].
creating S4 object  ... done [0.00s].
> plot(rules) #繪製關聯規則的散點圖

這幅散點圖表示了規則的分佈圖:大部分規則的support在0.2以內,Confidence在0.6-1內。每個點的顏色深淺代表了lift的值。

> plot(rules, method = "grouped")#繪製關聯規則的群組矩陣圖


群組矩陣圖可以總覽產生的關聯規則中包含哪些專案,進而選取使用者可能感興趣的規則進行詳細檢查。右側縱向列出的是規則的結果專案(RHS),上方橫向列出的是規則的條件專案(LHS);矩陣交匯的地方,以圓圈大小表示支援度,以顏色深淺代表增益。

比如我們選取的比較感興趣的問題是“什麼樣的人會擁有自己的房子”,就可以通過篩選RHS為“householder status=own”(注意編寫程式的時候,“=”兩側一定不能有空格,否則會提示錯誤)的顯著(lift>1)規則,並列出其中支援度最大的5名做進一步分分析。

> rulesOwn <- subset(rules, subset = rhs %in% "householder status=own" & lift > 1) #遴選出RHS為{householder status=own}的顯著(增益>1)規則
> inspect(head(sort(rulesOwn, by = "support"), n = 5)) #列出其中支援度排前5的規則做進一步分析
    lhs                              rhs                        support confidence     lift count
[1] {marital status=married}      => {householder status=own} 0.2614892  0.6779789 1.804096  1798
[2] {marital status=married,                                                                     
     language in home=english}    => {householder status=own} 0.2472368  0.6961507 1.852451  1700
[3] {marital status=married,                                                                     
     type of home=house}          => {householder status=own} 0.2329843  0.8279070 2.203053  1602
[4] {marital status=married,                                                                     
     type of home=house,                                                                         
     language in home=english}    => {householder status=own} 0.2207679  0.8433333 2.244102  1518
[5] {marital status=married,                                                                     
     ethnic classification=white} => {householder status=own} 0.2049156  0.7353862 1.956856  1409

可以發現,支援度前5名的規則中,所有的條件均包含“maritalstatus=married”,且其單一條件的置信度達到了0.68。

如果我們感興趣的專案並未產生相應的規則,除了降低產生關聯規則的門檻值以外,我們也可以通過對資料重新整合,降低屬性的水平數後再進行關聯規則分析。例如,本案例中,我們對高收入人群感興趣,但產生的規則中卻很少有與income相關的規則。那麼,我們可以將income取值中原有的9個水平按照$40000為分界點重新劃分為“$40-”、“$40+”兩個水平,再次進行關聯規則分析。

> library(arules) #載入arules程式包
> library(arulesViz) #載入arulesViz程式包
> data("IncomeESL") #載入資料檔案IncomeESL
> class(IncomeESL) #檢視IncomeESL的資料型別
[1] "data.frame"
> dim(IncomeESL) #檢視IncomeESL的維度
[1] 8993   14
> IncomeESL <- IncomeESL[complete.cases(IncomeESL),] #刪除包含缺失值的資料
> dim(IncomeESL) #檢視刪除缺失值之後的IncomeESL的資料維度
[1] 6876   14
> IncomeESL[["income"]] <- factor((as.numeric(IncomeESL[["income"]]) > 6) + 1, levels = 1:2, labels = c("$40-", "$40+")) #將income劃分為2個水平
> IncomeESL.tr <- as(IncomeESL, "transactions") #關聯規則分析必須使用transactions格式的資料,因此採用as()將data.frame資料轉換為transactions物件
> rules <- apriori(IncomeESL.tr, parameter = list(support = 0.2, confidence = 0.6)) #採用Apriori演算法進行關聯規則分析,將支援度設為0.2、置信度設為0.6
Apriori

Parameter specification:
 confidence minval smax arem  aval originalSupport maxtime support minlen maxlen target   ext
        0.6    0.1    1 none FALSE            TRUE       5     0.2      1     10  rules FALSE

Algorithmic control:
 filter tree heap memopt load sort verbose
    0.1 TRUE TRUE  FALSE TRUE    2    TRUE

Absolute minimum support count: 1375 

set item appearances ...[0 item(s)] done [0.00s].
set transactions ...[77 item(s), 6876 transaction(s)] done [0.01s].
sorting and recoding items ... [23 item(s)] done [0.00s].
creating transaction tree ... done [0.00s].
checking subsets of size 1 2 3 4 5 done [0.01s].
writing ... [513 rule(s)] done [0.00s].
creating S4 object  ... done [0.00s].
> rulesIncome <- subset(rules, subset = rhs %in% "income=$40+" & lift > 1) #遴選出RHS為{householder status=own}的顯著(增益>1)規則
> inspect(head(sort(rulesIncome, by = "support"), n = 5)) #列出其中支援度排前5的規則做進一步分析
    lhs                                                  rhs           support   confidence lift    
[1] {householder status=own}                          => {income=$40+} 0.2436009 0.6482198  1.716934
[2] {marital status=married}                          => {income=$40+} 0.2370564 0.6146305  1.627966
[3] {householder status=own,language in home=english} => {income=$40+} 0.2325480 0.6555966  1.736472
[4] {marital status=married,language in home=english} => {income=$40+} 0.2248400 0.6330876  1.676853
[5] {householder status=own,type of home=house}       => {income=$40+} 0.2107330 0.6665133  1.765387
    count
[1] 1675 
[2] 1630 
[3] 1599 
[4] 1546 
[5] 1449 

可以發現,“擁有自己的房子”和“已婚人士”為高收入人群的機會比較高置信度在0.6~0.7之間。