[PYTHON] 장바구니 데이터 빈발항목 집합 구하기(연관규칙) 실습

2023. 10. 10. 10:00DATA PROGRAMMING/PYTHON

import numpy as np
import pandas as pd
import itertools

itertools는 조합, 순열 등을 구하기 용이하게 해주는 라이브러리다.

 

 

df = pd.read_csv('C:/Users/user/Downloads/marketbasket.csv', encoding='UTF8', header='infer')

print(df.shape)
print(df.columns)
print(df.head())

데이터를 불러오고 대략적으로 확인해 주자.

 

 

 

new_columns = df.columns.str.strip().to_list()
df.columns = new_columns

컬럼들의 이름을 strip해준 후에 리스트 형태로 저장하고, 다시 df의 컬럼이름들을 strip해준 값들로 지정한다.

 

print(df.isnull().any().sum())
print(df[df > 1].any().sum())

null값이 있는지, df의 데이터 값이 1이상인 값이 있는지 확인한다. (둘 다 0이므로 해당하는 데이터는 없다)

 

 

def support(df, items_list):
    items_list = items_list if isinstance(items_list, list) else list(items_list)
    a= np.sum(df.loc[:,items_list].sum(axis=1) == len(items_list))
    b= df.shape[0] #전체 행의 갯수
    return a/b

지지도를 구하는 함수를 만들어 준다. 데이터 프레임과 아이템 리스트를 인자로 받는데, items_list인자가 리스트가 아니면 리스트로 바꾼 다음 인자로 받는다.

items_list 열들만 확인했을때 리스트에 포함된 아이템을 모두 포함하는 행의 갯수를 a에 저장한다.

전채 행 중 a의 비율이 지지도이다.

 

 

 

def make_set_over_support(df, min_support):
    items= []
    size = 1
    single_items = [col for col in df.columns if support(df,[col])>min_support]
    
    while True :
        new_items = []
        for items_candidate in itertools.combinations(single_items, size):
            if support(df, items_candidate) > min_support:
                new_items.append(list(items_candidate))
        if len(new_items) == 0:
            break
        else:
            items += new_items
            size += 1
            
    return items

우선 최소 지지도를 넘는 한 개의 아이템만을 포함한 규칙을 생성한다. 그리고 아이템의 갯수를 늘려가며 최소 지지도를 넘는 모든 조합을 찾는다. 이렇게 계산하는 이유는 최소 지지도를 넘는 아이템 집합의 부분집합은 무조건 최소 지지도를 넘을 것이고 그 지지도 또한 최소한 같거나 더 클것이기 때문이다. 즉, 가장 적은 수(1개)의 아이템을 포함하는 조합부터 차례로 아이템의 갯수를 늘려간다면 불필요한 계산을 줄일 수 있다.

 

 

def make_confidence_list(df, item_set_over_support, confidence_threshold):
    r_list = []
    for item1 in item_set_over_support:
        for item2 in item_set_over_support:
            if len(set(item1).intersection(set(item2))) ==0:
                confidence = support(df, set(item1).union(set(item2)))/support(df,item1)
                if confidence > confidence_threshold:
                    r_list.append((item1, item2, confidence))
            else:
                continue
    return sorted(r_list, key = lambda x : x[2], reverse = True)

이번엔 신뢰도를 계산할 차례이다. 신뢰도를 구하는 함수의 인자는 전체 데이터 프레임,  최소 지지도를 넘는 조합들, 최소 신뢰도 순으로 입력한다.

item 집합을 두 그룹으로 나누고 두 그룹의 교집합 원소의 갯수가 0 (배반사건)인 경우에만 계산을 진행한다.

item1에 대한 item2의 신뢰도는 item1이 포함된 그룹 중 item1과 item2가 모두 포함된 그룹의 비율이다. 여기선 item1과 item2가 모두 포함된 그룹을 합집합으로 표현할 수 있다. 이렇게 구한 신뢰도가 인자로 받은 최소 신뢰도보다 높다면 결과 리스트에 포함한다.

 

 

print("over support list")
over_support_lst = make_set_over_support(df,0.05)
print(over_support_lst)
print('-----------------')
print('over confidence list')
for item1, item2, confidence in make_confidence_list(df, over_support_lst, 0.5):
    print("{} --> {}: {}".format(item1, item2, confidence))

이제 최소 지지도는 0.05, 최소 신뢰도는 0.5인 연관규칙들을 찾을 수 있다.