의사결정나무는 해석이 쉽기 때문에 유용한 알고리즘이다. 우연히 범주형 데이터를 기준으로 의사결정나무를 만들어야 할 필요성이 생겼다. 타겟값이 있는 것은 아니고, 범주형 데이터를 기준으로 카테고리 비중이 가장 차이나는 애들부터 나눠달라는 요구사항이 있었다.
이에 의사결정나무 알고리즘을 이용하면 쉽게 분류할 수 있을 것 같아서 만들어보았다. 오늘은 범주형 의사결정나무 알고리즘 만들기에 대해서 알아보도록 하겠다.
1. 범주형 의사결정나무 만드는 방법은?
일단 가지치는 기준을 정해야 한다. 가지를 치는 기준은 각 카테고리별로 비중을 구한 후에 이 비중의 표준편차가 가장 크거나 작은 칼럼을 기준으로 가지치기를 하도록 하였다.
이에 대한 함수를 하나 만든 후에는 이를 재귀적 호출하여 가장 끝까지 나눠지도록 한다. 해당 함수가 make_tree라는 함수이다.
의사결정나무는 첫 번째 가지부터 딕셔너리로 만든다. 다음 가지가 값(value)으로 들어가 있는 형태이다. 트리를 이쁘게 출력하는 방법을 고민해봤는데, pyprnt 패키지를 이용해서 딕셔너리를 이쁘게 출력하는 방법이 가장 쉽고 좋을 듯 했다.
( 참조: 파이썬 리스트와 딕셔너리를 이쁘게 시각화 조회하는 방법! )
트리의 카운트를 세는 것이 조금 불편해서, 가지의 count를 세는 make_cout함수도 만들어보았다.
2. 코드 실행
예를 들어 아래와 같은 데이터를 넣었다고 하면, 카테고리값별로 가장 차이가 많이 나는 칼럼부터 순서대로 가지를 친다.
분류한 결과는 아래와 같다.
사용한 코드는 아래와 같다.
import pandas as pd
def cal_std(df, c):
"""
group비율의 표준편차를 구한다.
"""
df_gr = df.groupby(c)[c].count()
df_gr = df_gr/len(df)
return df_gr.std()
def feature_to_split(df, method):
"""
method: min, max
분류할 특성을 찾는다. 표준편차가 가장 적거나 큰 걸로
"""
col_list = df.columns
var_list = list()
for c in col_list:
var = cal_std(df, c)
var_list.append(var)
if method == 'min':
res_std_col = col_list[var_list.index(min(var_list))]
elif method == 'max':
res_std_col = col_list[var_list.index(max(var_list))]
return res_std_col
def split_data(df, method):
"""
method에서 지정한 방법으로 데이터셋 분리
"""
c = feature_to_split(df, method)
var_list = set(df[c])
var_dict = dict()
for v in var_list:
var_dict.update({v : df.loc[df[c]==v]})
split_df = {c:var_dict}
return split_df, c
def make_tree(df, n, method='min'):
"""
df: 데이터프레임
n: tree depth
"""
if n==0:
return df
split_df, split_col = split_data(df, method)
for c in split_df[split_col]:
split_df[split_col].update({c : make_tree(split_df[split_col][c], n-1, method)})
return split_df
def make_count(output):
"""
생성한 트리의 가지별 count를 구한다.
"""
key_list = output.keys()
for k in key_list:
if isinstance(output[k], pd.DataFrame)==True:
output.update({k:len(output[k])})
else:
make_count(output[k])
return output
if __name__=="__main__":
df = pd.DataFrame({'col1': [1,1,2,2,2], 'col2': [1,1,1,1,9], 'col3': [8,9,9,9,9]})
df.head()
output = make_tree(df, 3, method = 'max')
output_cnt = make_count(output)
print(output_cnt)
import pyprnt
pyprnt.prnt(output_cnt)
오늘은 이렇게 범주형 의사결정나무 알고리즘 만들기에 대해서 알아보았다. 혹시 위와 같은 작업이 필요한 사람이 있다면 도움이 되었기를 바란다.
'데이터 > 데이터 분석' 카테고리의 다른 글
파이썬 워드클라우드, 이쁘게 그리는 방법은?! (0) | 2022.01.19 |
---|---|
파이썬 KoNLPy, 형태소 분석 및 워드클라우드 그리는 법은?! (2) | 2022.01.18 |
추천 알고리즘 탐색, Deep FM 알아보기 (0) | 2022.01.18 |
추천 알고리즘 탐색, Factorization Machine 알아보기 (0) | 2022.01.18 |
데이터 분석 용어 정리 - Funnel, adhoc 분석 (0) | 2022.01.17 |
XGBoost와 랜덤 포레스트 재학습 하는 방법은? (0) | 2022.01.17 |
SOM 군집 알고리즘이란? 파이썬 학습 방법은?! (0) | 2022.01.16 |
파이썬 판다스 데이터프레임 리스트로 추출하는 방법은?! (0) | 2022.01.15 |