연관 분석

연관 분석

` 거래 또는 사건들 간의 규칙을 발견하여 IF-THEN 구조로 결과의 연관성을 파악

연관 규칙 측도

  • 지지도(support) : 전체 거래 중 A와 B를 동시에 포함하는 비율
    • $P(A \cap B) $
  • 신뢰도(confidence) : A 거래중 A와 B를 동시에 포함하는 비율
    • $P(B | A)$
  • 향상도(lift) : A가 구매되지 않았을 때 B의 구매확률에 비해 A가 구매되었을 때 B의 구매확률의 증가비
    • $P(B | A) / P(B)$

Apriori

최소 지지도 이상의 빈발항목집합을 찾은 후 연관규칙 계산



apply

회차와 6개 숫자 정보가 있는 로또 데이터를 이용

1
2
3
4
5
import numpy as np
import pandas as pd
lotto = pd.read_csv('data/lotto.csv')
lotto.time_id = lotto['time_id'].astype('str')
lotto.head()

time_id num1 num2 num3 num4 num5 num6
0 859 8 22 35 38 39 41
1 858 9 13 32 38 39 43
2 857 6 10 16 28 34 38
3 856 10 24 40 41 43 44
4 855 8 15 17 19 43 44
1
2
# pd.melt(lotto, id_vars='time_id')
lotto_ary = lotto.set_index('time_id').T.to_dict('list')

Transaction data로 변환하기

각 아이템이 있는지 없는지 보여줌

1
2
3
4
5
from mlxtend.preprocessing import TransactionEncoder
te = TransactionEncoder()
te_ary = te.fit(lotto_ary.values()).transform(lotto_ary.values())
df = pd.DataFrame(te_ary, columns=te.columns_)
df.head()

image

1
2
3
4
5
6
7
from mlxtend.preprocessing import TransactionEncoder
from mlxtend.frequent_patterns import apriori, association_rules
fre_set = apriori(df, min_support=0.002, use_colnames=True) # 최소 지지도 0.002
# fre_set['length'] = fre_set['itemsets'].apply(lambda x: len(x))

fre_rule = association_rules(fre_set,metric="confidence", min_threshold=0.8)
# 최소 신뢰도 0.8
1
fre_rule.sort_values(by="lift",ascending=False).iloc[:10,:]

antecedents consequents antecedent support consequent support support confidence lift leverage conviction
703 (16, 26, 31) (43, 36) 0.002328 0.012806 0.002328 1.0 78.090909 0.002298 inf
643 (24, 34, 22) (31, 7) 0.002328 0.012806 0.002328 1.0 78.090909 0.002298 inf
642 (34, 31, 7) (24, 22) 0.002328 0.012806 0.002328 1.0 78.090909 0.002298 inf
682 (26, 21, 14) (18, 15) 0.002328 0.013970 0.002328 1.0 71.583333 0.002296 inf
652 (34, 10, 36) (44, 22) 0.002328 0.013970 0.002328 1.0 71.583333 0.002296 inf
646 (24, 22, 31) (34, 7) 0.002328 0.013970 0.002328 1.0 71.583333 0.002296 inf
666 (24, 20, 15) (12, 30) 0.002328 0.013970 0.002328 1.0 71.583333 0.002296 inf
702 (16, 26, 43) (36, 31) 0.002328 0.013970 0.002328 1.0 71.583333 0.002296 inf
700 (16, 43, 36) (26, 31) 0.002328 0.015134 0.002328 1.0 66.076923 0.002293 inf
653 (34, 10, 22) (36, 44) 0.002328 0.016298 0.002328 1.0 61.357143 0.002290 inf


번호 개수를 시각화보면 다음과 같다

1
2
3
4
5
k = []
data = np.array([k+_ for _ in lotto_ary.values()]).flatten()
data = pd.Series(data)
import seaborn as sns
sns.barplot(x=data.value_counts(ascending=False).index[:10] ,y = data.value_counts(ascending=False)[:10], order=data.value_counts(ascending=False).index[:10])

image

34가 제일 많이 나와서 34가 나오는 규칙을 추출해 보았다.

1
fre_rule[conse.astype('str').str.contains('34')]

image

여기서 향상도는 6.4정도로 나오는데 1번 규칙만 살펴보면 34만 추출된 것 보다 1,5,13이 뽑히고 34가 뽑힐 확률이 6.4배 정도 된다는 뜻이다. 하지만 순서를 고려하지 않고 단순히 조합에 대한 확률만 고려한 규칙이라 여기서는 향상도가 높은 조합이 추첨번호가 될 가능성이 높은 것은 아님.

그 외에도 인사이트를 찾아보기 위해 describe() 등 해보는 게 좋음.

데이터 출처 : 데이터 에듀 adp 모의고사

updatedupdated2021-03-242021-03-24
Load Comments?