[PYTHON] 머신러닝 연관규칙을 활용한 식단 추천

2023. 11. 27. 22:17DATA PROGRAMMING/PYTHON

이번 실습에서는 식단 데이터를 가지고 와서 해당 국과 밥 데이터와 원하는 식단에 따른 추천 메뉴1, 메뉴2 추천하는 프로그램을 머신러닝의 연관규칙을 통해서 수행하고자 한다.

 

df = pd.read_csv("C:/Users/user/Downloads/2020년 4분기 치료식 식단 정보.csv",encoding='cp949')
df

 

해당 코드를 보면 메뉴명 대체로 메뉴명1과 메뉴명2는 대부분 밥과 국 메뉴인 것을 알 수 있다. 메뉴명 5는 대부분 김치 종류의 반찬이므로 나는 메뉴명1과 메뉴명2에 따라 메뉴명3과 메뉴명 4를 추천하는 코드를 작성하고자 한다.

 

 

king=input('원하시는 식단 종류를 입력하세요:')
selected_columns1 = ['식이구분','메뉴명1', '메뉴명2', '메뉴명3', '메뉴명4']  # 이 부분은 실제 데이터프레임의 컬럼명에 맞게 수정해야 합니다.
selected_columns2 = ['메뉴명1', '메뉴명2', '메뉴명3', '메뉴명4']
df = df[selected_columns1]
df = df.loc[df['식이구분'] == king]
df = df[selected_columns2]
df = pd.DataFrame(df)

df

우선 내가 원하는 컬럼들만 뽑아준다. 메뉴명1~4와 원하는 식단을 선택하기 위해 식이구분 컬럼을 선택하고 입력받은 식단에 해당하는 행들만 추출한후 메뉴명1~4컬러만 남긴다.

 

 

 

 

from itertools import product

def generate_set_pairs(list1, list2):
    pairs = [{x, y} for x, y in product(list1, list2)]
    return pairs

list3 = list(df['메뉴명3'])
list4 = list(df['메뉴명4'])

result_set_pairs2 = generate_set_pairs(list3, list4)

# 내부 set을 tuple로 변환 후 딕셔너리의 키로 사용하여 중복 제거
unique_pairs_dict2 = {tuple(pair): None for pair in result_set_pairs2}
unique_pairs2 = [set(pair) for pair in unique_pairs_dict2.keys()]


list1 = list(df['메뉴명1'])
list2 = list(df['메뉴명2'])

result_set_pairs1 = generate_set_pairs(list1, list2)

# 내부 set을 tuple로 변환 후 딕셔너리의 키로 사용하여 중복 제거
unique_pairs_dict1 = {tuple(pair): None for pair in result_set_pairs1}
unique_pairs1 = [set(pair) for pair in unique_pairs_dict1.keys()]

 

메뉴명1과 메뉴명2로 이루어진 모든 리스트와 메뉴명3과 메뉴명4로 이루어진 모든 리스트를 뽑아낸다. 이는 연관규칙 이후에 이에 해당하는 규칙들만 출력하기 위해서이다.

 

 

 

# 데이터프레임을 transactions 리스트로 변환
transactions = []
for i in range(len(df)):
    transactions.append([str(df.values[i, j]) for j in range(df.shape[1])])

# 연관 규칙 탐색
association_rules = apriori(transactions, min_support=0.005, min_confidence=0.001, min_length = 3)
association_results = list(association_rules)

association_results

적절한 최소 지지도, 최소 길이, 최소 신뢰도를 설정한 이후에 apriori알고리즘을 활용해 연관규칙을 시행해 준다.

 

 

 

 

rules = []

for results in association_results:
    supp = results.support
    for orders in results.ordered_statistics:
        if (orders.items_base in unique_pairs1) and (orders.items_add in unique_pairs2)  and (len(orders.items_add)==1): # 이 조건 수정으로 반찬 갯수나 밥, 국에 대한 내용 수정가능
            conf = orders.confidence
            lift = orders.lift
            hypo = orders.items_base
            conc = orders.items_add
            rules.append([hypo, conc, supp, conf, lift])

for rule in rules:    
    print(rule[0], '->', rule[1])
    print('supprot = ' + str(rule[2]))
    print('confidence = ' +str(rule[3]))
    print('lift = ' + str(rule[4]))
    print()

마지막으로 만들어진 연관규칙중 아까 생성해 놓은 조건(메뉴명1, 메뉴명2 --> 메뉴명3, 메뉴명4)을 만족하는 규칙들을 선택해준다.