머신러닝 중 지도학습의 연관규칙입니다. 열대과일을 구매했으면 옆에 터키, 치즈, 포도 등등
어떤식으로 어떤 연관이 있는지 확인할 수 있습니다.
각각의 연관도를 따질 수 있습니다 .(장바구니분석 이라고도 불림)
이 부분은 빅데이터분석기사(빅분기) 제 2과목에서도 나오는 항목이기에 좀 더 유심하게 봤습니다.
## 연관규칙 학습(Association Rule Learning)
* 연관 (Association): 서로 관련이 있다는 뜻
* 연관 규칙(Association Rule): 연관에 대한 규칙
* 연관 규칙 학습 (Learning): 머신러닝에서 연관규칙을 학습시킴
* 연관규칙을 한마디로 정의하면 동시에 발생한 사건(Transaction)들 간의 관계를 정의한 규칙
(1)연관규칙 관련 용어
1) itemset(항목집합) : 항목들을 모음
2) k-itemset(k-항목집합): k개의 항목직합 ex) 2-itemset: {기저귀:맥주}
3) support (지지도) : 전체 경우의 수 중에서 두 아이템이 같이 나오는 비율
= 항목집합의 지지횟수 / 전체거래 데이터 수
ex) {기저귀: 우유}
{기저귀: 우유: 맥주}
{우유: 맥주}
{기저귀: 우유: 맥주}
{기저귀}
전체경우의 수 : 5개 에서 두 아이템({기저귀:우유})이 같이 나오는 비율
=지지회수/거래회수(트랜잭션 수)
= 3/5 = 0.6
4) support count(지지회수) : 부분항목집합이 나타난 거래의 수 (위 예에서는 3)
5) 빈발 항목집합 : 지정된 지지도 이상의 지지도를 갖는 항목집합
6) confidence(신뢰도) : X가 나온 경우 중에서 X와 Y가 함게 나오는 비율
예) 위 예에서 '기저귀'가 나왔을때 '기저귀,우유'가 나올 비율
쉽계 얘기하면 기저귀를 샀을 때 우유도 같이 살 비율
7) lift (향상도) : 동시에 두 사건이 발생할 비율
X와 Y가 같이 나오는 비율을 X가 나올 비율과 Y과 나올 비율의 곱으로 나눈 값
향상도가
1보다 높을때 positively correlation /긍정적 상관관계
1일때 independent / 독립적
1미만일때 negatively correlation / 부정적 상관관계
(2) 쇼핑데이터 예시
거래번호 구매항목
-------------------------------------------
T1 빵, 우유
T2 기저귀, 달걀, 맥주, 빵
T3 기저기, 맥주, 우유, 콜라
T4 기저귀, 맥주, 빵, 우유
T5 기저귀, 빵, 우유, 콜라
-------------------------------------------
(3) 알고리즘
- apriori 알고리즘
1) 대표적인 연관규칙학습 알고리즘
2) 빈발항목들을 선택하고 그 중 신뢰도(confidence)가 높은 연관규칙 생성
3) 빈발항목집합들을 점진적으로 생성해나감
(4) 연관규칙학습 사용 예시
소비자 구매행동패턴 분석, 상품 추천, 신용카드 사기 탐지, 웹 사용자 행동 분석 등등 추천시스템에서 굉장히 많이 사용
(5) 연관규칙학습 구현 주요 단계
1) 데이터 수집 : 거래데이터, 로그데이터 수집, 항목들의 집합을 구성
2) 데이터 전처리: 중복된 항목들을 제거, 불필요한 정보들을 정리, 데이터들을 트랜잭션 형태로 정리
3) 항목집합 생성: 각 트랜잭션에서 어떤 항목들이 함께 발생하는지 파악, 연관성 파악
4) 연관규칙 탐색 : Apriori 알고리즘 등을 활용해 연관규칙 탐색
빈도수 기반으로 연관성을 계산
불필요한 규칙 제거
중요한 규칙을 강조하기 위한 후처리 작업 수행
5) 규칙평가 : 지지도, 신뢰도, 향상도 등의 지표를 사용해서 규칙을 평가
6) 결과 해석 및 활용 : 찾아낸 연관규칙을 해석, 실제 업무에 적용
7) 주기적 업데이트 : 데이터가 변경 또는 추가될 때 주기적으로 업데이트
연관성을 최신상태로 유지
코드실습
파일명 : association.py
## association.py
## 연관규칙 학습 (Association Rule Learning)
def p(str):
print(str, '\n')
# mlxtend 라이브러리 설치
# 라이브러리 로딩
import mlxtend
import numpy as np
import pandas as pd
from mlxtend.preprocessing import TransactionEncoder
from mlxtend.frequent_patterns import apriori
from mlxtend.frequent_patterns import association_rules
# itemset
# 리스트를 넘파이 배열로
data = np.array([
['우유', '기저귀', '쥬스', ''],
['상추', '기저귀', '맥주', ''],
['우유', '양상치', '기저귀', '맥주'],
['양상치', '맥주', '', '']
])
# 트랜잭션 인코더
te = TransactionEncoder()
# 데이터 학습 후 변환
te_array = te.fit(data).transform(data)
# 데이터프레임으로 변환
df = pd.DataFrame(te_array, columns=te.columns_)
#p(df)
# 지지도, 신뢰도 설정
min_support_per = 0.5 # 최소 지지도 설정 (기본 0.5)
min_threshold_per = 0.5 # 최소 신뢰도 (기본 0.8)
# apriori 알고리즘 적용
result = apriori(
df, # 데이터프레임
min_support=min_support_per, # 최소 지지도
use_colnames=True # 컬럼명 사용여부
)
# 연관규칙 생성
result_rules = association_rules(
result, # 알고리즘 적용 결과
metric='confidence', # 신뢰도
min_threshold=min_threshold_per # 최소 신뢰도
)
#p(result_rules)
#p(result_rules['support']) # 지지도
#p(result_rules['confidence']) # 신뢰도
코드실습
파일명 : association_chipotle.py
## association_chipotle.py
import matplotlib.pyplot as plt
## 연관규칙 학습
def p(str):
print(str, '\n')
#라이브러리 로딩
import pandas as pd
from mlxtend import frequent_patterns
from mlxtend import preprocessing
#데이터프레임
df = pd.read_csv('../assets/chipotle.csv')
df.info()
#chipotle.csv 데이터 구성
'''
order_id 주문번호
quantity : 수량
item_name : 아이템명
choice_description: 선택옵션
item_price : 아이템가격
'''
# 연관분석 함수를 사용하기 위해 리스트로 변환
df_temp =df[['order_id', 'item_name']]
# p(df_temp)
df_temp_arr = [[] for i in range(1835)]
# p(df_temp_arr)
num = 0
for i in df_temp['item_name']:
df_temp_arr[df_temp['order_id'][num]].append(i)
num += 1
p(df_temp_arr)
# order_id 는 1부터 시작하므로 빈값 제거
#그러면 [] 이 값이 제거됨
df_temp_arr.pop(0)
# p(df_temp_arr)
# set으로 중복값을 제거 후 list로 반환
num = 0
for i in df_temp_arr:
df_temp_arr[num] = list(set(df_temp_arr[num]))
num += 1
p(df_temp_arr)
#uniqe한 아이템명
p(df['item_name'].unique())
# 트랜잭션 인코더 생성
te = preprocessing.TransactionEncoder()
#학습시키고 변환
te_arr = te.fit(df_temp_arr).transform(df_temp_arr)
p(te_arr) #T와 F로 변환
# 변환된 이진행렬을 데이터프레임으로 변환 후
# 각 열의 이름을 아이템명으로 설정함
df1 = pd.DataFrame(te_arr, columns=te.columns_)
p(df1) #50개
df1.info()
#정규표현식 라이브러리
import re
#경고 무시
import warnings
warnings.filterwarnings('ignore')
#csv파일을 보면 아이템가격의 $가 있는데 $를 없애보려고 함
#1) 정규표현식
num = 0
for i in df['item_price']:
df['item_price'][num] = re.sub(pattern='[$]', repl=' ',string=i)
num += 1
# p(df['item_price'])
#2) 람다(lambda)함수 반복
#apply : 앞에있는것 하나하나에 뒤에 있는 람다함수를 적용
df['item_price'] = df['item_price'].apply(lambda x:x.lstrip('$'))
p(df)
# 아이템가격을 float로 변환
df['item_price'] = df['item_price'].astype(float)
p(df['item_price'].sum())
#null인 것의 합계
# p(df.isnull().sum())
#choice_description 1246개
#null인것들은 'default'로 채움
df['choice_description'] = df['choice_description'].fillna('default')
p(df.isnull().sum())
#알파벳과 쉼표를 제외한 모든 문자 제거
num = 0
for i in df['choice_description']:
df['choice_description'][num]\
= re.sub(pattern='[^a-zA-Z,]', repl='', string=i)
num += 1
# p(df['choice_description'])
# 아이템명과 선택옵션의 값의 수를 시리즈로 변경
result = df.groupby(['item_name','choice_description']).value_counts()
p(result)
# 시리즈의 인덱스로 리스트변환
temp_index = result.index.tolist()
# p(temp_index)
# 시리즈의 값들을 리스트 변환
temp_values = result.values.tolist()
# p(temp_values)
# #시각화
# import matplotlib.pyplot as plt
# plt.figure(figsize=(16, 8))
# x= df['item_name']
# y= df['quantity']
# plt.bar(x,y)
# plt.xticks(rotation=45)
# plt.show()
# 중복된 아이템 제거하고 판매량 합게 계산
# p(df.groupby('item_name')['quantity'].sum())
# 가장 많이 팔린 메뉴 중 10개 막대그래프로 그리기
top_items = df.groupby('item_name')['quantity'].sum().sort_values(ascending=False).head(10)
p(top_items)
#nlargest함수(가장 큰 값을 가지는 아이템 추출) 사용해서 상위 10개 아이템 추출
top_items = df.groupby('item_name')['quantity'].sum().nlargest(10)
# p(top_items)
# #막대그래프
# plt.figure(figsize=(10,6))
# top_items.plot(kind='bar')
# plt.xlabel('item_name')
# plt.ylabel('quantity')
# plt.show()
#연관학습 라이브러리
from mlxtend.frequent_patterns import apriori
from mlxtend.frequent_patterns import association_rules
#그룹핑 후 확인
#unstack : 인덱스 값을 컬럼으로 사용
df_grouped = df.groupby(['order_id', 'item_name'])['quantity']\
.sum().unstack().reset_index()
# p(df_grouped)
#판매량이 1이상인 경우 1로 변경
df_group = df_grouped.applymap(lambda x:1 if x>=1 else 0)
# p(df_group)
#apriori 알고리즘을 사용해 연관규칙 학습
frequent = apriori(
df_group.drop('order_id', axis=1), #데이터프레임
min_support=0.01, #최소 지지율
use_colnames=True #컬럼명 사용여부
)
# 연관규칙 추출
# lift : 향상도(규칙이 얼마나 의미있는지?)
rules = association_rules(
frequent,
metric='lift',
min_threshold=1.0
)
# p(rules)
# 최종적으로는 <연관학습 결과>를 알아야 함
# p(rules['support'])
p(rules['confidence'])
여기서 조금 난이도가 있었던 부분은 for문으로
# 연관분석 함수를 사용하기 위해 리스트로 변환
df_temp =df[['order_id', 'item_name']]
# p(df_temp)
df_temp_arr = [[] for i in range(1835)]
# p(df_temp_arr)
num = 0
for i in df_temp['item_name']:
df_temp_arr[df_temp['order_id'][num]].append(i)
num += 1
p(df_temp_arr)
이 부분입니다. 결과는 아래와 같습니다.
값들이 너무 많이 나와서 [[], ['Chips and Fresh Tomato Salsa', 'Izze', 'Nantucket Nectar', 이런식으로 리스트에 넣어지게 됩니다. |
이 부분에서는 중복된 셀이 다 들어가게됩니다. 이후 중복된 셀을 없애기 위해서는 set을 사용해서 중복된 값을 제거해주었습니다.
# set으로 중복값을 제거 후 list로 반환
num = 0
for i in df_temp_arr:
df_temp_arr[num] = list(set(df_temp_arr[num]))
num += 1
p(df_temp_arr)
'데이터 분석 및 시각화' 카테고리의 다른 글
[DL] 텐서플로우를 활용한 예제(손글씨, mnist활용) (1) | 2024.09.15 |
---|---|
[DL] basic _딥러닝 기본 (0) | 2024.09.14 |
[ML]K-Means 클러스터링, DBSCAN(밀도기반 클러스터링) (0) | 2024.09.12 |
[ML]클러스터링_집값 상관관계 분석해보기 (0) | 2024.09.11 |
[데이터분석] ML_머신러닝 모델+의사결정나무 (2) | 2024.08.30 |