[R 연관규칙 (Association Rule)] R arules package로 연관규칙 분석하기
R 분석과 프로그래밍/R 연관규칙(Association Rule) 2016. 5. 23. 10:01지난번 포스팅에서는 대용량 데이터로 부터 효율적으로 연관규칙(association rules)을 도출할 수 있는 apriori algorithm 에 대하여 알아보았습니다.
이번 포스팅에서는 R의 arules package를 가지고 분석하는 방법을 예를 들어서 설명하도록 하겠습니다.
(그동안 선형대수랑 기계학습 이론 내용만 포스팅하다보니 R 사용법 포스팅한지가 너무 오래된거 같아요. ^^;)
arules package는 Apriori algorithm으로 구현되었 있습니다.
1. arules package 설치 및 library(arules)로 로딩
aruels package는 base package가 아니므로 별도 설치 필요합니다.
> install.packages("arules") |
2. 데이터 확보 및 탐색
분석에 사용할 데이터는 Epub 거래 데이터셋 입니다. Help에 'Epub' 을 검색해보면 아래와 같은 설명이 나옵니다. Vienna University of Economics and Business Administration에서의 2003~2008년까지 기간 동안 전자책 다운로드 이력/거래 데이터입니다.
Epub Data SetDescriptionThe Usagedata(Epub) FormatObject of class Author(s)Michael Hahsler SourceProvided by Michael Hahsler from ePub-WU at http://epub.wu-wien.ac.at.
|
data(Epub)로 로딩하고 summary(Epub)로 데이터셋 요약정보를 살펴보겠습니다.
- sparse format 형식으로 저장된 itemMatrix의 거래(transactions) 데이터셋이며,
- 15,729개의 행(즉, 거래)과 936개의 열(items)으로 구성되어 있습니다.
- 밀도(density)가 0.1758755% 라고 되어 있는데요, 전체 15729*936개의 cell 중에서 0.1758% 의 cell에 거래가 발생해서 숫자가 차 있다는 뜻입니다. (일부 책벌레 애독자가 한꺼번에 다수의 책을 사고, 대부분의 독자는 item 1개나 2개 단품 위주로 샀기 때문에 이렇게 밀도가 낮겠지요?)
- 'most frequent items' 는 거래 빈도가 가장 많은 top 5의 품목명과 거래빈도를 제시해주고 있습니다.
(doc_11d 가 356회 거래 빈도 발생으로 1위)
- 'element (itemset/transaction) length distribution' 은 하나의 거래 장바구니(즉, row 1개별로)에 품목(item)의 개수별로 몇 번의 거래가 있었는지를 나타냅니다.
(장바구니에 item 1개 짜리 단품만 거래한 경우가 11,615건으로서 가장 많고, item 2개 거래는 2,189건이군요)
- 마지막에 item 정보의 label 형식과 transaction ID, TimeStamp 정보의 format 예시가 나옵니다.
> data(Epub) > summary(Epub) transactions as itemMatrix in sparse format with 15729 rows (elements/itemsets/transactions) and 936 columns (items) and a density of 0.001758755 most frequent items: doc_11d doc_813 doc_4c6 doc_955 doc_698 (Other) 356 329 288 282 245 24393 element (itemset/transaction) length distribution: sizes 1 2 3 4 5 6 7 8 9 10 11 12 13 14 11615 2189 854 409 198 121 93 50 42 34 26 12 10 10 15 16 17 18 19 20 21 22 23 24 25 26 27 28 6 8 6 5 8 2 2 3 2 3 4 5 1 1 30 34 36 38 41 43 52 58 1 2 1 2 1 1 1 1 Min. 1st Qu. Median Mean 3rd Qu. Max. 1.000 1.000 1.000 1.646 2.000 58.000 includes extended item information - examples: labels 1 doc_11d 2 doc_13d 3 doc_14c includes extended transaction information - examples: transactionID TimeStamp 10792 session_4795 2003-01-02 10:59:00 10793 session_4797 2003-01-02 21:46:01 10794 session_479a 2003-01-03 00:50:38 |
참고로, R을 분석에 많이 사용해본 분이라면 dataframe 형식의 데이터셋을 많이 사용해보셨을 텐데요, 연관규칙분석에서 사용할 itemMatrix in sparse format 형식의 데이터셋과 비교해보면 아래와 같이 차이가 있습니다. 위에서 Epub 데이터셋의 density가 0.1758%로서 item별 matrix cell의 거의 대부분이 숭숭 비어있다고 했는데요, 비어있는 cell까지 모두 저장하려면 메모리 비효율이 발생하므로 cell의 차있는 부분(즉, 거래발생 항목, nonzero elements)에 대해서만 효율적으로 데이터를 저장해놓는 방식이 itemMatrix in sparse format 형식입니다. 저장 효율이 좋아지는 대신 반대급부로 access하는 것이나 저장구조는 좀 복잡해집니다.
(행렬의 대부분의 cell이 '0'이면 sparse matrix 라고 하며, 그 반대는 dense matrix 라고 합니다.)
csv 파일을 dataframe 으로 업로드할 때 read.csv() 함수를 사용하는 것처럼, transaction 데이터를 연관규칙분석을 위해 sparse format의 itemMatrix로 업로드하기 위해서는 read.transactions("dataset.csv") 함수를 사용합니다.
이번에는 inspect() 함수를 사용해서 거래 데이터 10개만 뽑아서 살펴보겠습니다.
> ## check itemsets in sparse matrix > inspect(Epub[1:10]) items transactionID TimeStamp 10792 {doc_154} session_4795 2003-01-02 10:59:00 10793 {doc_3d6} session_4797 2003-01-02 21:46:01 10794 {doc_16f} session_479a 2003-01-03 00:50:38 10795 {doc_11d,doc_1a7,doc_f4} session_47b7 2003-01-03 08:55:50 10796 {doc_83} session_47bb 2003-01-03 11:27:44 10797 {doc_11d} session_47c2 2003-01-04 00:18:04 10798 {doc_368} session_47cb 2003-01-04 04:40:57 10799 {doc_11d,doc_192} session_47d8 2003-01-04 09:00:01 10800 {doc_364} session_47e2 2003-01-05 02:48:36 10801 {doc_ec} session_47e7 2003-01-05 05:58:48 |
다음으로 itemFrequency() 함수를 이용해서 거래품목(item)별로 거래에서 차지하는 비율(support)를 살펴보겠습니다. Epub[ , 1:10] 으로 앞에 10개만 indexing 해왔습니다.
> ## support per item: itemFrequency() > itemFrequency(Epub[ , 1:10]) doc_11d doc_13d doc_14c doc_14e doc_150 doc_151 0.0226333524 0.0009536525 0.0024794965 0.0017801513 0.0015894208 0.0007629220 doc_153 doc_154 doc_155 doc_156 0.0006357683 0.0013351135 0.0010808062 0.0031152648
|
itemFrequencyPlot(dataset, support = xx) 함수를 이용해서 지지도 1% 이상의 item에 대해 막대그래프를 그려보겠습니다.
> ## item frequency plot : itemFrequentPlot() > itemFrequencyPlot(Epub, support = 0.01, main = "item frequency plot above support 1%") |
이번에는 itemFrequencyPlot(dataset, topN = xx) 함수를 사용해서 support 상위 30개의 막대그래프를 그려보겠습니다. support 1등 item이 'doc_11d'이고 2~2.5% 사이로군요. 30등 tiem은 'doc_3ec'이고 support가 약 1% 이네요.
> ## item frequency plot top 30 : itemFrequencyPlot(,topN) > itemFrequencyPlot(Epub, topN = 30, main = "support top 30 items")
|
아래는 image()함수와 sample()함수를 이용해서 500개의 무작위 샘플을 가지고 matrix diagram을 그려본 것입니다. 그림의 점들은 거래가 발생한 item을 의미합니다. 이 그림만 봐서는 어떤 패턴이 있는지 알기가 어렵지요? ^^'
> # matrix diagram : image() > image(sample(Epub, 500, replace = FALSE), main = "matrix diagram")
|
3. 연관규칙 분석 (association rule analysis)
arules 패키지의 apriori() 함수를 이용해서 연관규칙을 분석해보겠습니다.
parameter 에 list로 minimum support, minimum confidence, minimum length 를 지정해주면 이를 충족시키지 못하는 superset에 대해서는 pruning 을 해서 빠르게 연관규칙을 찾아줍니다.
그런데, 아래 예시에서는 minumum support = 0.01 로 했더니 기준이 너무 높았던지 연관규칙이 '0'개 나왔네요.
> ## association rule analysis : apriori() > Epub_rule <- apriori(data = Epub, + parameter = list(support = 0.01, + confidence = 0.20, + minlen = 2)) Apriori Parameter specification: confidence minval smax arem aval originalSupport support minlen maxlen target ext 0.2 0.1 1 none FALSE TRUE 0.01 2 10 rules FALSE Algorithmic control: filter tree heap memopt load sort verbose 0.1 TRUE TRUE FALSE TRUE 2 TRUE Absolute minimum support count: 157 set item appearances ...[0 item(s)] done [0.00s]. set transactions ...[936 item(s), 15729 transaction(s)] done [0.00s]. sorting and recoding items ... [19 item(s)] done [0.00s]. creating transaction tree ... done [0.00s]. checking subsets of size 1 2 done [0.00s]. writing ... [0 rule(s)] done [0.00s]. creating S4 object ... done [0.00s] |
minumum support 기준을 0.001 로 낮추어서 다시 한번 분석을 해보겠습니다.
아래처럼 결과가 나왔습니다. 연관규칙 분석은 기본 개념과 결과를 해석할 줄 알면 분석툴로 분석하는 것은 이처럼 매우 쉽습니다. (컴퓨터는 연산해야할 일이 엄청 많지만요...)
> # re-setting minimum support from 0.01 to 0.001 > Epub_rule_2 <- apriori(data = Epub, + parameter = list(support = 0.001, + confidence = 0.20, + minlen = 2)) Apriori Parameter specification: confidence minval smax arem aval originalSupport support minlen maxlen target ext 0.2 0.1 1 none FALSE TRUE 0.001 2 10 rules FALSE Algorithmic control: filter tree heap memopt load sort verbose 0.1 TRUE TRUE FALSE TRUE 2 TRUE Absolute minimum support count: 15 set item appearances ...[0 item(s)] done [0.00s]. set transactions ...[936 item(s), 15729 transaction(s)] done [0.00s]. sorting and recoding items ... [481 item(s)] done [0.00s]. creating transaction tree ... done [0.02s]. checking subsets of size 1 2 3 done [0.00s]. writing ... [65 rule(s)] done [0.00s]. creating S4 object ... done [0.00s]
> Epub_rule_2 set of 65 rules |
4. 연관규칙 조회 및 평가
연관규칙을 Epub_rule 이라는 객체에 저장을 해두었으므로, summary() 함수를 써서 연관규칙에 대해 개략적으로 파악을 해보면 아래와 같습니다.
62개 rule이 2개 item으로 이루어져 있고, 3개 rule은 3개 item으로 구성되있군요. 지지도(support), 신뢰도(confidence), 향상도(lift)에 대한 기초통계량도 같이 제시가 되었는데요, 향상도 최소값이 11.19로서 전반적으로 꽤 높군요.
> summary(Epub_rule_2) set of 65 rules rule length distribution (lhs + rhs):sizes 2 3 62 3 Min. 1st Qu. Median Mean 3rd Qu. Max. 2.000 2.000 2.000 2.046 2.000 3.000 summary of quality measures: support confidence lift Min. :0.001017 Min. :0.2048 Min. : 11.19 1st Qu.:0.001081 1st Qu.:0.2388 1st Qu.: 34.02 Median :0.001208 Median :0.2874 Median : 59.47 Mean :0.001435 Mean :0.3571 Mean :105.16 3rd Qu.:0.001526 3rd Qu.:0.3696 3rd Qu.:100.71 Max. :0.004069 Max. :0.8947 Max. :454.75 mining info: data ntransactions support confidence Epub 15729 0.001 0.2
|
연관규칙을 평가하기 위해 개별 규칙(rule)을 inspect()함수를 사용해서 살펴보겠습니다. 아래 결과에 1~20개의 rule을 제시했는데요, lhs : Left-hand side, rhs : Right-hand side 를 의미합니다.
|
위처럼 주욱 나열을 해놓으면 rule이 수백, 수천개가 되면 일일이 눈으로 보고 평가하기가 쉽지가 않습니다. 봐야할 rule이 많을 때는 sort() 함수를 써서 분석가가 보고자하는 기준에 맞게 by 매개변수로 정렬을 하여 우선순위를 뒤서 보면 유용합니다. 아래 예는 lift 를 기준으로 상위 20개 연관규칙을 정렬해보았습니다. 매우 유용하지요?!!
|
아래는 정렬 기준을 '지지도(support)'로 해서 top 20 연관규칙을 뽑아본 것입니다. 편하고 좋지요?!
> # sorting association rules by support : sort(, by = "support") > inspect(sort(Epub_rule_2, by = "support")[1:20]) lhs rhs support confidence lift 50 {doc_72f} => {doc_813} 0.004068917 0.3516484 16.81178 45 {doc_4ac} => {doc_16e} 0.002797381 0.4313725 53.42566 46 {doc_16e} => {doc_4ac} 0.002797381 0.3464567 53.42566 62 {doc_364} => {doc_71} 0.002733804 0.2336957 15.91255 60 {doc_60e} => {doc_6bf} 0.002670227 0.2745098 21.06227 61 {doc_6bf} => {doc_60e} 0.002670227 0.2048780 21.06227 49 {doc_972} => {doc_8f9} 0.002161612 0.2281879 18.69358 58 {doc_1a2} => {doc_4c7} 0.002098035 0.2391304 17.99657 56 {doc_424} => {doc_359} 0.001843728 0.3020833 44.40625 57 {doc_359} => {doc_424} 0.001843728 0.2710280 44.40625 47 {doc_4da} => {doc_84b} 0.001780151 0.2314050 34.01653 48 {doc_84b} => {doc_4da} 0.001780151 0.2616822 34.01653 52 {doc_8a8} => {doc_8af} 0.001716574 0.2903226 47.07715 53 {doc_8af} => {doc_8a8} 0.001716574 0.2783505 47.07715 27 {doc_803} => {doc_3fc} 0.001589421 0.3289474 59.47142 28 {doc_3fc} => {doc_803} 0.001589421 0.2873563 59.47142 55 {doc_466} => {doc_19f} 0.001525844 0.2264151 25.80640 59 {doc_359} => {doc_4c7} 0.001398690 0.2056075 15.47368 13 {doc_6e8} => {doc_6e7} 0.001335113 0.6562500 294.91875 14 {doc_6e7} => {doc_6e8} 0.001335113 0.6000000 294.91875
|
또 하나 유용한 tip이 있다면 subset() 함수를 써서 관심이 있는 item이 포함된 연관규칙만 선별해서 보는 방법입니다. subset()함수를 이용해 연관규칙에서 "doc_72f"나 "doc_4ac"를 포함하는 규칙을 선별하는 방법은 아래와 같습니다.
> # subset of association rules : subset() > rule_interest <- subset(Epub_rule_2, items %in% c("doc_72f", "doc_4ac")) > inspect(rule_interest) lhs rhs support confidence lift 6 {doc_4bf} => {doc_4ac} 0.001080806 0.5000000 77.10294 45 {doc_4ac} => {doc_16e} 0.002797381 0.4313725 53.42566 46 {doc_16e} => {doc_4ac} 0.002797381 0.3464567 53.42566 50 {doc_72f} => {doc_813} 0.004068917 0.3516484 16.81178 |
연관규칙을 찾을 때 왼쪽(lhs : Left-hand side)이나 오른쪽(rhs: Right-hand side)을 기준으로 원하는 항목(item)이 포함된 규칙만 찾고 싶을 때는 아래와 같이 lhs 나 rhs 조건을 주면 됩니다.
> # subset with left-hand side item : subset(lhs %in% "item") > rule_interest_lhs <- subset(Epub_rule_2, lhs %in% c("doc_72f", "doc_4ac")) > inspect(rule_interest_lhs) lhs rhs support confidence lift 45 {doc_4ac} => {doc_16e} 0.002797381 0.4313725 53.42566 50 {doc_72f} => {doc_813} 0.004068917 0.3516484 16.81178 |
위에서는 사용한 %in% (select itemsets matching any given item) 조건은 적어도 하나의 제품이라도 존재하면 연관규칙을 indexing해온다는 뜻입니다. 이에 반해 %pin% (partial matching) 는 부분 일치만 하더라도, %ain% (select only itemsets matching all given item) 는 완전한 일치를 할 때만 indexing을 하게 됩니다.
아래에 item 이름에 부분적으로라도 "60e"라는 철자가 들어가 있는 item이 들어가 있는 연관규칙을 부분집합으로 indexing해오는 예를 들어보겠습니다. 이 기능도 꽤 유용하겠지요?
> # partial subset : %pin% > rule_interest_pin <- subset(Epub_rule_2, items %pin% c("60e")) > inspect(rule_interest_pin) lhs rhs support confidence lift 60 {doc_60e} => {doc_6bf} 0.002670227 0.2745098 21.06227 61 {doc_6bf} => {doc_60e} 0.002670227 0.2048780 21.06227
|
Rule의 왼쪽에 "doc_6e8"과 "doc_6e9" item을 동시에 정확히 가지고 있는 rule을 "ain" 을 사용해서 선별해보면 아래와 같습니다.
> rule_interest_lhs_ain <- subset(Epub_rule_2, lhs %ain% c("doc_6e8", "doc_6e9")) > inspect(rule_interest_lhs_ain) lhs rhs support confidence lift [1] {doc_6e8,doc_6e9} => {doc_6e7} 0.001080806 0.8947368 402.094
|
support, confidence, lift 조건을 추가해서 부분집합(subset)을 취할 수도 있습니다. 아래 예는 신뢰도(confidence) 0.25 초과하는 rule 을 선별하라는 조건을 추가하였습니다. 참 편하지요?!
> # partial subset with confidence condition : %pin%, confidence > rule_interest_pin_conf <- subset(Epub_rule_2, items %pin% c("60e") & confidence > 0.25) > inspect(rule_interest_pin_conf) lhs rhs support confidence lift 60 {doc_60e} => {doc_6bf} 0.002670227 0.2745098 21.06227 |
5. 연관규칙의 시각화 : arulesViz package
arulesViz package를 사용해서 연관규칙을 시각화해보겠습니다.
- Scatter plot for association rules
> install.packages("arulesViz") > > # scatter plot of association rules
|
- Grouped matrix for assocation rules
> # grouped matrix for association rules > plot(sort(Epub_rule_2, by = "support")[1:20], method = "grouped")
|
* 65개 rule을 모두 그리니깐 너무 작게 나와서 support 기준 상위 20개만 선별해서 그렸음
- Network Graph for assocation rules
참고로 아래 그래프의 원은 item element가 아니라 {item} → {item} 연관규칙의 지지도(support)를 나타냅니다. 지지도에 따라 원의 크기가 비례합니다. 색깔은 향상도(Lift)를 나타냅니다. 색깔이 진할수록 향상도가 높습니다. 그런데 화살표(from lhs to rhs)가 그려지다 말아서 그래프가 영... 어색합니다. -_-???
> # Graph for association rules
|
위의 65개 연관규칙 그래프의 라벨 글자 크기(label font size, default = 1)를 줄이고, 화살표 크기(arrow size, default = 1)도 조금 잘게 해보겠습니다. 네트워크 그래프 그릴 때 사용하는 igraph 패키지의 파라미터 설정 방법을 사용하면 됩니다. 위의 그래프보다는 아주 조금 더 나은거 같기는 한데요, 많이 좋아보인다는 느낌은 안드네요. ^^;; (그래프 그릴 때마다 위치가 조금씩 달라지므로 제가 화면 캡쳐해놓은 거랑은 아마 다르게 그려질 거예요)
> # changing font size(vertex.label.cex), arrow > plot(Epub_rule_2, method = "graph", + control = list(type="items"), + vertex.label.cex = 0.7, + edge.arrow.size = 0.3, + edge.arrow.width = 2)
* igraph 참고 : http://rfriend.tistory.com/221 |
Network graph for association rules 그래프 해석을 좀더 쉽게 할 수 있도록 아래 그래프의 몇 개의 item 간 연관규칙 그래프 옆에다가 association rule(left-hand => right-hand rule, support, confidence, lift) 분석 결과를 매핑해서 표시를 해보았습니다. item 과 item 의 연관규칙 관계를 화살표로 나타내구요, 원의 크기는 지지도, 원의 색깔은 향상도를 나타냅니다.
- 화살표 (arrow) : left-hand => right-hand rule 의 방향(direction from left to right)을 나타냄
- 원의 크기 (circle size) : 지지도(support)에 비례해서 커짐
- 원의 색깔 (circle color) : 향상도(lift)에 비례해서 색이 진해짐
연관규칙 그래프 시각화를 좀더 이쁘게 하려면 연관규칙 개수를 20개 이내로 줄여주면 됩니다. 아래는 연관규칙 55~65번째 (11개 규칙) 만 선별해서 type = "items" 로 그려본 것인데요, label 글자 크기나 화살표 등이 전혀 거슬리지 않고 자연스럽지요?
[ 그림 1] Graph-based visualization with item and rules as vertices
> plot(Epub_rule_2[55:65], method = "graph", control = list(type="items"))
|
type = "itemsets" 으로 설정을 해주면 아래의 그래프 처럼 "item-set" (가령, {doc_6e8, doc_6e9}, {doc_6e7, doc_6e9} 처럼 여러개 item 들이 들어 있는 바구니) 끼리의 연관규칙 관계를 시각화해줍니다.
- 화살표 두께(width) : item-set 간 연관규칙 지지도(support)에 비례하여 커짐
- 화살표 색깔(color) : item-set 간 연관규칙 향상도(lift)에 비례하여 진해짐
type = "items" (위의 [그림1]) 일 때와 type = "itemsets" (아래의 [그림 2]) 일때의 동그라미로 표시해 둔 부분을 유심히 비교해서 살펴보시면 서로 연관규칙을 어떻게 표현하는 것인지 이해할 수 있을 것입니다. 서로 장단점이 있지요?
[ 그림 2] Graph-based visualization with item-sets as vertices
> plot(Epub_rule_2[55:65], method="graph", control=list(type="itemsets"))
|
6. 연관규칙을 CSV 파일로 저장
마지막으로 write() 함수를 사용해서 분석한 연관규칙을 CSV 파일로 저장해보겠습니다. 나중에 엑셀로 불러다가 후속 분석/작업하는데 필요할 수도 있겠지요? file = "경로" 지정할 때 경로구분표시가 '\'가 아니라 '/' 로 해주어야 하는 것에 주의하시기 바랍니다. Windows 탐색기의 경로 그대로 복사해다가 붙이면 경로구분표시가 '\' 되어 있어서 오류납니다.
|
마지막으로 as() 함수를 이용하여 연관규칙을 데이터프레임(dataframe) 구조로 변환해서 저장해보겠습니다. 연관규칙이 데이터프레임으로 되어있으면 다른 분석할 때 가져다 쓰기에 편하겠지요?
> # transforming into dataframe > Epub_rule_df <- as(Epub_rule_2, "data.frame")
> str(Epub_rule_df) 'data.frame': 65 obs. of 4 variables: $ rules : Factor w/ 65 levels "{doc_16e} => {doc_4ac}",..: 22 23 14 44 26 20 43 41 42 38 ... $ support : num 0.00121 0.00121 0.00108 0.00108 0.00108 ... $ confidence: num 0.655 0.559 0.205 0.37 0.333 ... $ lift : num 303.1 303.1 11.2 114 114 ... |
데이터프레임으로 만들었으니 이전 포스팅에서 배웠던 IS(Interest-Support) Measure 와 교차지지도(cross support) 흥미측도를 생성할 수 있습니다. R arules 패키지에서 자동으로 생성해주는 것은 지지도(support), 신뢰도(confidence), 향상도(lift) 3개뿐이다 보니 IS측도나 교차지지도는 직접 코딩해서 계산해줘야 합니다.
아래 예시는 IS 기준으로 내림차순한 다음에 IS측도 상위 10개만 indexing한 것입니다. (교차지지도는 최소지지도, 최대지지도 구해서 나눠줘야 하는 복잡함이 있으므로 패쓰... ^^; )
> # IS(Interest-Support) measure = sqrt(lift(A,B)*support(A,B)) > Epub_rule_df <- transform(Epub_rule_df, IS = sqrt(lift*support))> Epub_rule_df[order(-Epub_rule_df$IS), ][1:10, ] rules support confidence lift IS 65 {doc_6e7,doc_6e8} => {doc_6e9} 0.001080806 0.8095238 454.7500 0.7010682 64 {doc_6e7,doc_6e9} => {doc_6e8} 0.001080806 0.8500000 417.8016 0.6719840 63 {doc_6e8,doc_6e9} => {doc_6e7} 0.001080806 0.8947368 402.0947 0.6592317 9 {doc_6e9} => {doc_6e7} 0.001271537 0.7142857 321.0000 0.6388766 10 {doc_6e7} => {doc_6e9} 0.001271537 0.5714286 321.0000 0.6388766 7 {doc_6e9} => {doc_6e8} 0.001207960 0.6785714 333.5391 0.6347454 8 {doc_6e8} => {doc_6e9} 0.001207960 0.5937500 333.5391 0.6347454 13 {doc_6e8} => {doc_6e7} 0.001335113 0.6562500 294.9187 0.6274950 14 {doc_6e7} => {doc_6e8} 0.001335113 0.6000000 294.9187 0.6274950 1 {doc_506} => {doc_507} 0.001207960 0.6551724 303.0943 0.6050833
|
이상으로 R arules 패키지를 사용해서 연관규칙 분석하는 방법을 마치도록 하겠습니다.
다음번 포스팅에서는 범주형 데이터의 연관분석에 대하여 알아보도록 하겠습니다.
이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡'를 꾸욱 눌러주세요.
연관규칙 분석을 위해 transactions format으로 데이터를 변환하는 방법에 대한 질문이 자주 있어서 아래와 같이 데이터 유형별로 예를 들어 정리하였습니다. 참고하세요.
##==== [참고] List를 transactons format 으로 변환하기 ====
> ##------------------------------------------ > ## List -> transactions 자료로 변환 > ##------------------------------------------ > # transaction list > tr_list <- list(c("a", "b"), + c("a", "c"), + c("b", "c", "d"), + c("a", "e"), + c("c", "d", "e")) > # set transaction names > names(tr_list) <- paste("tr", c(1:5), sep = "_") > tr_list $tr_1 [1] "a" "b" $tr_2 [1] "a" "c" $tr_3 [1] "b" "c" "d" $tr_4 [1] "a" "e" $tr_5 [1] "c" "d" "e" > tr <- as(tr_list, "transactions") > tr transactions in sparse format with 5 transactions (rows) and 5 items (columns) > summary(tr) transactions as itemMatrix in sparse format with 5 rows (elements/itemsets/transactions) and 5 columns (items) and a density of 0.48 most frequent items: a c b d e (Other) 3 3 2 2 2 0 element (itemset/transaction) length distribution: sizes 2 3 3 2 Min. 1st Qu. Median Mean 3rd Qu. Max. 2.0 2.0 2.0 2.4 3.0 3.0 includes extended item information - examples: labels 1 a 2 b 3 c includes extended transaction information - examples: transactionID 1 tr_1 2 tr_2 3 tr_3
|
##==== [참고] Matrix를 transactions format 으로 변환하기 ====
> ##------------------------------------------- > ## Matrix -> transactions 자료로 변환 > ##------------------------------------------- > tr_matrix <- matrix(c(1, 1, 0, 0, 0, + 1, 0, 1, 0, 0, + 0, 1 , 1, 1, 0, + 1, 0, 0, 0, 1, + 0, 0, 1, 1, 1), + ncol = 5) > # set dim names > dimnames(tr_matrix) <- list(c("a", "b", "c", "d", "e"), + paste("tr", c(1:5), sep = "_")) > tr_matrix tr_1 tr_2 tr_3 tr_4 tr_5 a 1 1 0 1 0 b 1 0 1 0 0 c 0 1 1 0 1 d 0 0 1 0 1 e 0 0 0 1 1 > # coerce into transactions > tr2 <- as(tr_matrix, "transactions") > tr2 transactions in sparse format with 5 transactions (rows) and 5 items (columns) > summary(tr2) transactions as itemMatrix in sparse format with 5 rows (elements/itemsets/transactions) and 5 columns (items) and a density of 0.48 most frequent items: tr_3 tr_5 tr_1 tr_2 tr_4 (Other) 3 3 2 2 2 0 element (itemset/transaction) length distribution: sizes 2 3 3 2 Min. 1st Qu. Median Mean 3rd Qu. Max. 2.0 2.0 2.0 2.4 3.0 3.0 includes extended item information - examples: labels 1 tr_1 2 tr_2 3 tr_3 includes extended transaction information - examples: transactionID 1 a 2 b 3 c
|
##==== [참고] DataFrame을 transactions format 으로 변환하기 ( 1 ) ====
> ##------------------------------------------------ > ## data.frame -> transactions 자료로 변환 > ##------------------------------------------------ > tr_dataframe <- data.frame( + age = as.factor(c("30대", "20대", "30대", "40대", "10대")), + grade = as.factor(c("A", "B", "A", "A", "C"))) > > # coerce into transactions > tr3 <- as(tr_dataframe, "transactions") > > tr3 transactions in sparse format with 5 transactions (rows) and 7 items (columns) > summary(tr3) transactions as itemMatrix in sparse format with 5 rows (elements/itemsets/transactions) and 7 columns (items) and a density of 0.2857143 most frequent items: grade=A age=30대 age=10대 age=20대 age=40대 (Other) 3 2 1 1 1 2 element (itemset/transaction) length distribution: sizes 2 5 Min. 1st Qu. Median Mean 3rd Qu. Max. 2 2 2 2 2 2 includes extended item information - examples: labels variables levels 1 age=10대 age 10대 2 age=20대 age 20대 3 age=30대 age 30대 includes extended transaction information - examples: transactionID 1 1 2 2 3 3 |
##==== [참고] DataFrame을 transactions format 으로 변환하기 ( 2 ) =====
> ## as(split([dadaframe[,"itemID"], dataframe[,"transactionID"]), "transactions") 함수 |
많은 도움 되었기를 바랍니다.
'R 분석과 프로그래밍 > R 연관규칙(Association Rule)' 카테고리의 다른 글
[R 연관규칙(Association Rule)] 순차패턴분석 (Sequence Pattern Analysis) (21) | 2016.05.29 |
---|---|
[R 연관규칙 (Association Rule)] 범주형 및 연속형 데이터의 연관규칙 분석 (12) | 2016.05.25 |
[R 연관규칙 (Association Rule)] R arules package로 연관규칙 분석하기 (24) | 2016.05.23 |
[R 연관규칙(Association Rule) ] Apriori algorithm (14) | 2016.05.21 |
[R 연관규칙(Association Rule)] 지지도(support), 신뢰도(confidence), 향상도(lift), IS측도, 교차지지도 (23) | 2016.05.19 |
[R 연관규칙(Association Rule)] 연관규칙분석, 장바구니분석(Market Basket Analysis) (7) | 2016.05.18 |
댓글을 달아 주세요
와,,, 좋은글 감사합니다
댓글 감사합니다. 꾸준히 읽으시나봐요 ^^
안녕하세요? 또 질문 드립니다 ^^;
아래와 같이 104개의 규칙이 생성되었고, support, confidence, lift 등 수치를 구했는데요. lift는 1을 기준으로, confidence는 0~1 값을 기준으로 높고 낮음 판단하면 될 것 같은데, support는 어떠한 기준으로 보통 높고 낮음을 판단하나요? 상대적인 기준으로 판단하나요?
set of 104 rules
rule length distribution (lhs + rhs):sizes
2 3
78 26
Min. 1st Qu. Median Mean 3rd Qu. Max.
2.00 2.00 2.00 2.25 2.25 3.00
summary of quality measures:
support confidence lift
Min. :0.001244 Min. :0.2000 Min. : 2.612
1st Qu.:0.001244 1st Qu.:0.4386 1st Qu.: 12.039
Median :0.001244 Median :0.6250 Median :131.265
Mean :0.002039 Mean :0.6404 Mean :233.051
3rd Qu.:0.001555 3rd Qu.:0.8000 3rd Qu.:473.211
Max. :0.019590 Max. :1.0000 Max. :804.000
mining info:
data ntransactions support confidence
df_transaction 3216 0.001 0.2
단위 시간 당 최소 개수에 대한 의사결정/판단이 가능하다면 min support 계산할수 있습니다.
가령 한달(30일) 총 거래건수 30,000건일때(즉, 하루 평균 1,000건 거래), 하루 최소 10건 이상은 거래가 되어야 의미가 있다고 판단했다면 한달이면 300건, min support= 300/30000=0.01
이런식으로 대략 가늠해볼수 있습니다.
rule이 100여개면 분석가가 quick하게 review할만한 규모네요. quick하게 보시고 min support 수준 주관적으로 설정해서 screening해서 분석해보시지요. 몇번의 trial & error 필요해요.
답변 감사드립니다!
안녕하세요. ^^;
항상 좋은 방법론을 공유시켜주셔서 감사합니다.
늘 도움이 되고 있습니다.
다름이 아니라, 한가지 궁금증이 있어 여러 검색을 해도 쉽게 알 수가 없어 문의드리고 싶은 부분이 있어서요. : )
바로 조건에 관련된 부분인데요.
rule_interest_pin <- subset(Epub_rule_2, items %pin% c("60e"))
위 코드에서 보신 것처럼, c("60e")를 갖고 있는 상품이 한개라도 있다면 해당 규칙을 발견하는것으로 이해했는데요,
rule_interest_pin <- subset(Epub_rule_2, items %pin% c("60e","70e"))
가령 70e라는 product가 있다고 가정 했을때, "60e"와 "70e"를 동시에 포함하는 조건절은 할 수 없는 것인지요.
개인적으로 생각했던 부분으로 했을 경우
Error in lhs %pin% c("60e", "70e") :‘60e’‘70e’ contains more than one item label pattern
위와 같은 에러가 나오는데, 혹시 두 개이상의 조건으로 규칙을 탐색하는 방식이 있는지 여쭤보고자 합니다 ^^.
항상 감사드리며, 소중한 댓글 부탁드립니다.
noxan님, 반갑습니다.
%ain% 를 사용해서 rule 왼쪽에 ("doc_6e8", "doc_6e9")을 동시에 정확히 가지고 있는 rule을 선별해내는 R script 입니다. 참고하시기 바랍니다. 본문에도 update 해두었습니다.
# select only itemsets matching all given item : subset(lhs %ain% "item")
rule_interest_lhs_ain <- subset(Epub_rule_2, lhs %ain% c("doc_6e8", "doc_6e9"))
inspect(rule_interest_lhs_ain)
###############
%pin% 매개변수는 item 하나별로 부분만족여부를 판단하기 때문에 문의하신 목적으로는 부적합합니다. (에러 메시지 => Error in lhs %pin% c("60e", "70e") :‘60e’‘70e’ contains more than one item label pattern)
R friend님 친절한 답변 감사합니다 ^^
덕분에 해결되었네요. 앞으로도 많은 관심을 갖고 페이지 방문하겠습니다
noxan님, 해결됐다니 잘됐네요. ^^
안녕하세요 좋은 포스팅 잘 보고 갑니다!!
구글링을 아무리 해도 풀리지 않는 문제가 하나 있는데 여기서 그 실마리를 얻어서 한가지 여쭤보려고 합니다.
제가 가지고 있는 데이터는 Item Matrix형태의 csv파일 입니다.
즉 colname에 항목이 표시되어있고 그 아래에 0,1 로 항목의 유무를 나타내고 있습니다.
이것을 read.Transaction 명령어로 불러올 수 있도록 Transaction data 형태로 바꾸어서 저장하고 싶은데
여기에 도움이 될만한 내용을 알고 계신지요?
혹시 알고 계시다면 답변 부탁드립니다ㅠㅠ
안녕하세요 r_kid님,
item matrix 데이터프레임을 연관규칙분석을 위한 transactions format으로 변환하려면 아래처럼 한번 해보세요.
install.packages("arules")
library(arules)
# transformation
tran_form <- as(item_mat, "transactions")
# check
str(tran_form)
inspect(tran_form)
plot(Epub_rule_2, method = "graph", control = list(type="items"))
이 그래프를 그렸는데, 규칙수가 많아서 그런지 글자들이 잘 안보이네요. 혹시 글자의 사이즈를 줄일 수도 있나요? 혹시나 cex=0.8 이렇게 해봤는데 아래같은 오류가 뜨네요 ^^;
Error in i.parse.plot.params(graph, list(...)) :
Unknown plot parameters: cex
vertex.label.cex 파라미터로 라벨 글자 크기를 조절할 수 있습니다. 아래 R script 참고하세요.
plot(Epub_rule_2, method = "graph", control = list(type="items"), vertex.label.cex = 0.5)
igraph 함수를 사용하는거였군요! 바로 적용해보니 잘 됩니다, 감사합니다 ^^
추가 질문 드립니다. 실제로 plot을 해보면 LHS, RHS에 해당하는 칼럼값들, 즉 중심이되는 변수들이 모든 화살표의 중심으로 모이고 주변은 원으로 연결됩니다. 그 원은 support와 lift로 연결이 되구요. 다만, plot을 해 본 결과 화살표의 중심은 알겠는데, 화살표를 둘러싼 동그라미에는 변수명이 없는 것 같아요. 특정 아이템들이 중심에 위치한 것만 이 그래프를 통해 봐야하는건가요?
글로 쓸려니 잘 설명이 안되네요. 제가 아직 그래프 해석을 잘 못하는 것 같아 그런데, 도움 부탁 드립니다 ^^
노경모님, arulesViz package 가 igraph를 기본 뼈대로 해서 다른 시각화 패키지들을 엮어서 만든 것이다 보니 igraph 패키지의 파라미터를 사용해서 점이나 화살표 설정을 바꿀 수 있습니다.
arulesViz 패키지의 연관규칙 시각화 해석하는 방법에 대해서 포스팅의 본문에 이미지 캡쳐해서 설명을 추가하였습니다.
그래프 캡쳐하고 포스팅하려니 시간이 많이 걸리네요. ^^;;;
감사합니다! 속이 다 시원하네요 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ
안녕하세요? 구글에서 검색하다 올려주신 글 보고 많은 도움이 되었습니다.
개인작업하다 궁금한 점이 있어서 댓글을 적게 되었습니다.
lhs에 조건을 넣고 있는데 위에 보니
rule_interest_pin <- subset(Epub_rule_2, items %pin% c("60e"))
구문이 있던데
lhs에 조건을 아무것도 안넣을려고 하는데 어떻게 해야하는지 궁금합니다. "" null, na등 넣어보았는데 안되네요. ex) {} => 60e 이런 조건들을 검색할려고 합니다.(그러면 처음 사람들이 구매, 관심있는 데이터를 구할 수 있는것 같아서 시도중입니다.) 혹시 보시거든 답변 부탁드립니다. 감사합니다.
안녕하세요.
문의하신 취지의 신규고객의 첫구매 상품 분석을 하시려면 연관분석 대신에 "신규고객 분석용 마트"를 별도로 만드셔서, 신규고객의 첫 거래 transaction만 가져다가 상품코드 기준으로 발생빈도만 카운트하시면 됩니다.
좀더 아이디어를 내보면, 신규고객의 3개월후 혹은 6개월후의 고객상태(유지, 휴면, 이탈)나 등급(최우수, 우수, 일반, 휴면.이탈 등) 정보와 매핑해서 상태나 등급별로 첫 구매 상품의 차이가 있는지 카이제곱검정 해보시는것도 유용할것 같습니다.
도움이 되었기를 바랍니다.
와 정말 자세히 설명주셔서 감사합니다. 관심가지고 자주 방문할게요!
댓글 감사합니다. 요즘 바빠서 통 글을 못썼는데요, 다시 힘내서 글 써봐야겠습니다. ^^
안녕하세요.
오늘 오전까지만해도 작성자님께 많은 도움을 받았습니다.
다시 한 번 감사드립니다.
혹시 정형데이터 말고 비정형데이터(논문, 소설 등..) 도 연관분석이 가능할까요?
분석 목적이 연관분석을사용하는 것이 맞는다면, 원 데이터를 연관분석을 할 수 있도록 transactions 포맷으로 전처리, 변환하해서 분석하면 됩니다.
도움이 많이 되었습니다~!! 감사합니다.
도움이 되었다니 기쁘네요. 댓글 감사합니다. ^^