본문 바로가기
AI SCHOOL/TIL

[DAY 50] Decision Tree를 이용한 분류, 학습과 예측, Accuracy

2023. 3. 8.

분류, 회귀 모두 사용 가능한 Decision Tree의 기본 원리를 이해하고 머신러닝에 활용했다.

scikit-learn의 DecisionTreeClassifier 모델을 사용하여 고객 행동 예측을 경험해보고 Accuracy를 평가해보는 과정으로 머신러닝 모델의 동작(학습 -> 예측 -> 평가)을 이해하였다.

데이터 준비

데이터는 Kaggle에 있는 Telco Customer Churn 데이터를 로드하여 df에 저장하였다.
인구통계, 구독과 관련된 정보 등 고객 정보가 들어 있으며 이를 이용하여 이탈 여부를 예측하였다.

customerID를 index로 지정, TotalCharges 컬럼을 numeric으로 변환, 결측치 제거 등의 전처리 과정을 거쳤다.
11개 행에 대해 결측치가 있었는데, 전체 7032개의 행에 비해 적은 수이며 만약 임의의 수로 대체한다면 오히려 예측 성능이 떨어질 것을 감안하여 제거하였다.

예측해야할 Churn(이탈여부) 컬럼에 대해 빈도수, 비율을 구하고 빈도수를 시각화 한 것은 아래와 같다.

valuecount

학습과 예측에 사용할 4개의 컬럼 SeniorCitizen, tenure, MonthlyCharges, TotalCharges를 선택하고 feature와 label을 나누어 X, y에 할당하였다.

그 후 전체 X, y 데이터를 각각 train(학습), test(검증) 데이터로 나누었다.

split_count = int(df.shape[0] * 0.8)  # 5625

전체(7032행)의 80% 기준 인덱스 split_count를 계산하고

X_train = X[:split_count]
X_test = X[split_count:]
X_train.shape, X_test.shape

# 실행 결과
((5625, 4), (1407, 4))

split_count를 기준으로 X 데이터를 5625행, 1407행으로 나누고

y_train = y[:split_count]
y_test = y[split_count:]
y_train.shape, y_test.shape

# 실행 결과
((5625,), (1407,))

y 데이터 또한 split_count를 기준으로 5625, 1407개로 나누었다.

X_train, X_test는 행렬 형태로 판다스의 데이터프레임, y_train, y_test는 벡터 형태로 판다스의 시리즈 형태이다.
train, test데이터끼리는 행 수가 같아야한다.

이렇게 학습, 예측, 평가를 위한 데이터가 준비되었다.

모델 생성, 학습, 예측

from sklearn.tree import DecisionTreeClassifier

우선 사이킷런(sklearn)에서 분류모델(DecisionTreeClassifier)을 로드했다.

# 모델 생성
model = DecisionTreeClassifier(criterion='entropy', random_state=42)
# 모델 학습(fit)
model.fit(X_train, y_train)
# 데이터 예측(predict)
y_predict = model.predict(X_test)

모델을 생성한 후, X_train과 y_train 데이터를 통해 학습하고, 학습된 모델에 X_test를 넣어 예측값 y_predict를 얻었다.
y_predict는 배열 형태로 생성되었다.

Accuracy(정확도) 평가

모델이 얼마나 잘 예측했는지 측정한다.
예측한 값 y_predict와 실제 X_test와 대응되는 이탈 여부가 들어 있는 y_test 값을 비교하여 정확도를 계산할 수 있다.

# 정확도(accuracy)
# 실제 값과 일치하도록 예측한 값은 True 로 나온다. 
# True == 1 이기 때문에 평균값을 내면 정답을 맞힌 비율을 구할 수 있다.
(y_test == y_predict).mean()

# 실행 결과
0.7256574271499645

True, False 값들을 평균내어 구한 정확도와

from sklearn.metrics import accuracy_score
accuracy_score(y_test, y_predict)

# 실행 결과
0.7256574271499645

sklearn의 accuracy_score 함수를 이용하여 구한 정확도는 같다.

지니 계수와 엔트로피

지니 계수
집합에 이질적인 것이 얼마나 섞였는지를 측정하는 지표로 불순도를 나타낸다.
집합에 있는 항목이 모두 같다면 지니 계수는 최솟값(0)을 갖게 되고 완전히 순수한 집합이라고 할 수 있다.
트리는 불순도가 점점 낮아지게 분할 기준을 선택하며 진행된다.
지니 계수가 0이 되면 그리는 것을 멈춘다.

plot_tree를 이용해 디시전트리 시각화
- 시각화 할 때 max_depth는 5로 제한했다.

decision1
모델 생성시 criterion을 gini(default)로 지정

루트 노드의 지니 계수 : 0.389
=> 1 - (4137/5625) ** 2 - (1488/5625) ** 2

엔트로피
정보 획득량을 의미하며 분할의 품질을 엔트로피로 평가할 때 점수가 잘 나온다.
지니 계수에 비해 트리의 품질을 엄격하게 평가하고자 하는 경우 사용한다.
섀넌의 엔트로피 : 동전을 던질 때 발생 가능한 모든 결과의 개수에 밑이 2인 로그를 취한 것
- 2개의 동전을 던지면 4가지 결과가 발생 가능하며 엔트로피는 2비트가 된다.

plot_tree를 이용해 디시전트리 시각화

decision2
모델 생성시 criterion을 entropy로 지정

루트 노드의 entropy : 0.834
=> -(((4137/5625)*np.log2(4137/5625)) + ((1488/5625)*np.log2(1488/5625)))

피처 중요도 시각화

model.feature_importances_

# 실행 결과
array([0.02230494, 0.22861819, 0.39455799, 0.35451889])

feature_importances_를 통해 모델의 피처 중요도를 추출하고

seaborn의 barplot으로 시각화하면 아래와 같다.

bar1

피처의 중요도는 마케팅 전략 등에 사용될 수 있다.

반응형

댓글