R語言學習之關聯規則算法
data(Groceries) #調用數據文件
frequentsets=eclat(Groceries,parameter=list(support=0.05,maxlen=10)) #求頻繁項集
inspect(frequentsets[1:10]) #察看求得的頻繁項集
inspect(sort(frequentsets,by=”support”)[1:10]) #根據支持度對求得的頻繁項集排序並察看(等價於inspect(sort(frequentsets)[1:10])
rules=apriori(Groceries,parameter=list(support=0.01,confidence=0.01)) #求關聯規則
summary(rules) #察看求得的關聯規則之摘要
x=subset(rules,subset=rhs%in%”whole milk”&lift>=1.2) #求所需要的關聯規則子集
inspect(sort(x,by=”support”)[1:5]) #根據支持度對求得的關聯規則子集排序並察看
lhs rhs support confidence lift
1 {other vegetables} => {whole milk} 0.07483477 0.3867578 1.513634
2 {rolls/buns} => {whole milk} 0.05663447 0.3079049 1.205032
3 {yogurt} => {whole milk} 0.05602440 0.4016035 1.571735
4 {root vegetables} => {whole milk} 0.04890696 0.4486940 1.756031
5 {tropical fruit} => {whole milk} 0.04229792 0.4031008 1.577595
==============================================================================================
文章參考資料:
xccd:肖凱大牛的博文
《Rdatamining》
《R IN A NUTSHELL》
注:如有疑惑的問題,參閱下文的預備知識!
關聯分析的挖掘任務可分解爲兩個步驟:一是發現頻繁項集,二是從頻繁項集中產生規則。
############################ 關聯分析 案例實踐 ############################
背景假定:
在電影商店中,一個客戶在一次購物中(也可不同時間段多次購買)購買了很多不同種類,品牌的電影盤。我們要從中找到有用的信息,提升商店的銷售。
問題提出:
1、那麼針對個體客戶來說,他們購買的偏好是什麼? 即購買的A商品,可能會購買那種潛在商品(影片)
2、在客戶中,有沒有明顯的用戶羣細分方式?
使用數據:
rattle包中,csv目錄下的 dvdtrans.csv 文件
數據描述:
該原始數據僅僅包含了兩個字段(ID, Item) 用戶ID,商品名稱。
##### code start #####
# 加載包
library(arules)
# 加載數據
dvdtrans
# 將數據轉換爲arules關聯規則方法apriori 可以處理的數據形式.交易數據
data
# 查看一下數據
attributes(data)
# 使用apriori函數生成關聯規則
rules
# 使用inspect函數提取規則
inspect(rules)
##### code end #####
上面的示例只是給一個感覺。繼續…
#################### nutshell
##################################################################
使用數據:Titanic
# look for data
str(Titanic)
# transform table into data frame
df head(df)
Class Sex AgeSurvivedFreq
1 1st MaleChild No 0
2 2nd MaleChild No 0
3 3rd MaleChild No 35
4 Crew MaleChild No 0
titanic.raw # 如果頻率字段大於0,將該行記錄按列追加到變量中,Freq=0,當然就不追加
for(iin1:4) {
titanic.raw titanic.raw[1:36,]
[,1] [,2] [,3] [,4]
[1,]“3rd”"Male” “Child”"No”
[2,]“3rd”"Male” “Child”"No”
[3,]“3rd”"Male” “Child”"No”
[4,]“3rd”"Male” “Child”"No”
…
[35,]“3rd”"Male” “Child”"No”
[36,]“3rd”"Female”"Child”"No”
# transform to data frame
titanic.raw head(titanic.raw)
V1 V2 V3V4
1 3rd MaleChildNo
2 3rd MaleChildNo
3 3rd MaleChildNo
4 3rd MaleChildNo
5 3rd MaleChildNo
6 3rd MaleChildNo
# 生成數據框後添加屬性名稱
names(titanic.raw)
summary(titanic.raw)
# 轉換後:每一行代表了一個人,可以用於關聯規則。轉換前是什麼類型的數據? (按照class、sex、年齡彙總的生存人數的數據)
With the function, the default settings are:1) supp=0.1, which is the minimum support of rules;2) conf=0.8, which is the minimum confidence of rules; and 3) maxlen=10, which is the maximum length of rules.
library(arules)
rules
rules # 根據最小的 (supp=0.1,conf=0.8),返回的規則的最多個數 10個
summary(rules);
inspect(rules);
quality(rules) inspect(rules)
翻譯:
關聯規則挖掘一個常見的現象是,很多產生的規則並不是有趣的。考慮到我們只關心規則的右件(rhs)表示是否生存,
所以我們參數 appearance 中設置 rhs=c(“Survived=No”, “Survived=Yes”) 並確定 只有這兩種情況出現在 規則右件中(rhs).
其它的項集可以出現在規則左件(lhs),使用default=”lhs”設置。
上面的結果也可以看到,第一個規則的lhs 是個空集,爲了排除這樣的規則,可以使用minlen=2。
而且,算法處理的過程被壓縮(簡化)是通過verbose=F設置的。
關聯規則挖掘結束後,規則將會以lift提升度按照從大到小的排序方式進行排序
rules.better parameter
=list(minlen
= 2,
supp =0.005,
conf =0.8),
appearance
= list(rhs
=c(“Survived=No”,
“Survived=Yes”), default
=”lhs”),
control
= list(verbose=F)
)
# base on lift sorted
rules.sorted inspect(rules.sorted)
lhs rhs supportconfidence lift
1 {Class=2nd,
Age=Child} => {Survived=Yes} 0.010904134 1.00000003.095640
2 {Class=2nd,
Sex=Female,
Age=Child} => {Survived=Yes} 0.005906406 1.00000003.095640
3 {Class=1st,
Sex=Female} => {Survived=Yes} 0.064061790 0.97241383.010243
4 {Class=1st,
Sex=Female,
Age=Adult} => {Survived=Yes} 0.063607451 0.97222223.009650
5 {Class=2nd,
Sex=Female} => {Survived=Yes} 0.042253521 0.87735852.715986
6 {Class=Crew,
Sex=Female} => {Survived=Yes} 0.009086779 0.86956522.691861
7 {Class=Crew,
Sex=Female,
Age=Adult} => {Survived=Yes} 0.009086779 0.86956522.691861
8 {Class=2nd,
Sex=Female,
Age=Adult} => {Survived=Yes} 0.036347115 0.86021512.662916
9 {Class=2nd,
Sex=Male,
Age=Adult} => {Survived=No} 0.069968196 0.91666671.354083
10 {Class=2nd,
Sex=Male} => {Survived=No} 0.069968196 0.86033521.270871
11 {Class=3rd,
Sex=Male,
Age=Adult} => {Survived=No} 0.175829169 0.83766231.237379
12 {Class=3rd,
Sex=Male} => {Survived=No} 0.191731031 0.82745101.222295
翻譯:
當其它設置不發生變化的情況下,越小的支持度會產生更多的規則。這種產生的規則中項集之間的關聯看起來更像是隨機的。
在上例中,最小支持度爲0.005,那麼每一個規則至少有 支持度*交易數(記錄數) 個案例 是滿足支持度爲0.005的。(2201 * 0.005 = 12)
支持度,置信度,提升度是選擇興趣規則的三個方法。還有一切其它的衡量方法,包括卡方,gini等。有多餘20中這樣的計算方法在interestMeasure()方法中
### 規則的剪枝
從上面的例子中,我們能夠發現一些規則與其它規則相比沒有提供額外的信息。(提供的信息少)。
比如第二個規則給出的信息,在第一個規則中已經都闡述明白了。因爲規則1告訴我們 所有的 2nd-class的孩子都倖存了。
(即 Class=2nd,Age=Child 所有的都倖存了,置信度和lift都是一致的,再增加一個sex的判斷是冗餘的)
我們以這個例子來闡述何種情況定義爲redundant(冗餘)
總體來說,規則2 是 規則1 的衍生規則,如果規則2 和 規則1 有相同的 提升度或者 比 規則1 更低的提升度,那麼規則2 就被認爲是冗餘的。
總結 :規則2 比 規則1 lhs多了sex的條件,同時lift ,兩者相同,所以規則2冗餘
lhs rhs support confidence lift
1 {Class=2nd,
Age=Child} =>{Survived=Yes}0.010904134 1.0000000 3.095640
2 {Class=2nd,
Sex=Female,
Age=Child} =>{Survived=Yes}0.005906406 1.0000000 3.095640
代碼:
函數解釋:
is.subset(r1, r2): 檢查r1是否爲r2的子集
lower.tri():返回一個邏輯 以TRUE爲下三角的matrix;diag=T表示包含主對角線
# redundant
subset.matrix
# 使得下三角包含主對角線設置爲NA
subset.matrix[lower.tri(subset.matrix, diag=T)] # 計算列TRUE的數量
redundant = 1; #
which(redundant) # 冗餘規則的下標
# 刪除冗餘規則
rules.pruned inspect(rules.pruned)
lhs rhs support confidence lift
1 {Class=2nd,
Age=Child} => {Survived=Yes} 0.010904134 1.0000000 3.095640
2 {Class=1st,
Sex=Female} => {Survived=Yes} 0.064061790 0.9724138 3.010243
3 {Class=2nd,
Sex=Female} => {Survived=Yes} 0.042253521 0.8773585 2.715986
4 {Class=Crew,
Sex=Female} => {Survived=Yes} 0.009086779 0.8695652 2.691861
5 {Class=2nd,
Sex=Male,
Age=Adult} => {Survived=No} 0.069968196 0.9166667 1.354083
6 {Class=2nd,
Sex=Male} => {Survived=No} 0.069968196 0.8603352 1.270871
7 {Class=3rd,
Sex=Male,
Age=Adult} => {Survived=No} 0.175829169 0.8376623 1.237379
8 {Class=3rd,
Sex=Male} => {Survived=No} 0.191731031 0.8274510 1.222295
規則的解釋:(解釋規則)
很容易就能找到高提升度的數據,但是理解識別出來的規則並不是一件容易的事情。
關聯規則在尋找商業意義上被誤解讀是很常見的。
比如,第一個規則,{Class=2nd,Age=Child} => {Survived=Yes}
規則的置信度爲1,提升度爲3,並且沒有規則揭示age=Child時,class=c(“1nd”,”3nd”).
因此,這樣可能就會被分析師解釋爲:類別爲2的孩子比其它類別的孩子(1,3)有更高的生存機率。
這種解釋是完全的錯誤的!!!!
這個規則僅表示 所有類別爲2的孩子倖存下來了,但是沒有提供任何信息 來進行比較不同的類別的孩子的生存率
爲了研究以上的問題,我們可以通過找到規則右件爲存活的,即rhs爲 Survived=Yes,
規則左件lhs 僅僅包括 Class=1st,2nd,3rd, Age=Child,Adult;不包括其它項集(如default=”none”)
我們對支持度和置信度使用較之前擬合模型這兩個參數較低的閾值,去找出所有孩子不同類別的規則。
爲了方便,先將原來計算的規則寫出來,好做比較
# former rules set
rules.better parameter
=list(minlen
= 2,
supp =0.005,
conf =0.8),
appearance
= list(rhs
=c(“Survived=No”,
“Survived=Yes”), default
=”lhs”),
control
= list(verbose=F)
)
# compare rules set
rules parameter
=list(minlen=3,supp=0.002,
conf=0.2),
appearance
= list(rhs=c(“Survived=Yes”),
lhs=c(“Class=1st”,
“Class=2nd”, “Class=3rd”,
“Age=Child”,
“Age=Adult”),
default=”none”),
control
= list(verbose
= F)
);
rules.sorted {Survived=Yes}0.010904134 1.0000000 3.0956399
2{Class=1st,
Age=Child}=>{Survived=Yes}0.002726034 1.0000000 3.0956399
3{Class=1st,
Age=Adult}=>{Survived=Yes}0.089504771 0.6175549 1.9117275
4{Class=2nd,
Age=Adult}=>{Survived=Yes}0.042707860 0.3601533 1.1149048
5{Class=3rd,
Age=Child}=>{Survived=Yes}0.012267151 0.3417722 1.0580035
6{Class=3rd,
Age=Adult}=>{Survived=Yes}0.068605179 0.2408293 0.7455209
根據結果,前兩個規則中,1類和2類的孩子有相同的倖存率並且都倖存了下來(置信度爲1)。
那麼1類的孩子的規則沒有出現在之前的規則列表中,是因爲支持度閾值低於設定的閾值(0.005),1類此時supp爲0.002.
規則5與規則4相比,3類的孩子存活率只有很低的34%,(此處只是比較的conf,無法按照class和age比較),
而和規則3(1類的成年人)比較,存活率(置信度)就更低了
關聯規則的可視化
library(arulesViz)
plot(rules)
plot(rules, method=”grouped”)
plot(rules, method=”graph”)
plot(rules, method=”graph”, control=list(type=”items”)
plot(rules, method=”paracoord”, control=list(reorder=T))
繼續閱讀:
兩個包:
arulesSequences:序列模型的關聯規則
arulesNBMiner:negative binomial(NB)頻繁項集
# arules
預備知識:
################ system.file() start ################
# 找指定包的路徑
a # 設定文件所在的路徑
file # file
# 判斷指定目錄下文件是否存在
logical.file
# 只要存在文件
if(any(logical.file)) {
file[logical.file] # file[TRUE]
}
# 綜上,用其它的包練習一下
packagePath file logic.file data data
transactionsinsparseformatwith
10 transactions (rows) and
10 items (columns)
# 用 apriori命令生成頻繁項集,設其支持度爲0.5,置信度爲0.8
rules inspect(rules)
lhs rhs supportconfidence lift
1 {Patriot} => {Gladiator} 0.6 1.00000001.428571
2 {Gladiator} => {Patriot} 0.6 0.85714291.428571
3 {SixthSense} => {Gladiator} 0.5 0.83333331.190476
# 加載包
library(arules)
# 找到rattle包所在路徑,路徑下csv目錄,找到file名稱爲dvdtrans.csv.
dvdtrans
函數
1、system.file
功能:
system.file(package=”rattle”)
system.file定義:
function(…,package=”base”,lib.loc=NULL,mustWork=FALSE)
{
# nargs():用於在函數體內調用,返回函數調用時參數的個數。直接數”,”的個數加1;
# file.path():獲取和設置文件路徑
# .Library:返回R軟件庫默認安裝路徑(此路徑下包含了所有installed的包)
# 如果system.file沒加參數,返回R安裝的默認路徑
if(nargs()==0L)
return(file.path(.Library,”base”))
# 如果參數package不只一個包要找,提示
if(length(package)!=1L)
stop(“‘package’ must be of length 1″)
#
packagePath<-find.package(package,lib.loc,quiet=TRUE)
ans<-if(length(packagePath)){
FILES<-file.path(packagePath,…)
present<-file.exists(FILES)
if(any(present))
FILES[present]
else”"
}
else”"
if(mustWork&&identical(ans,”"))
stop(“no file found”)
ans
}