일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 컴퓨터비전
- html/css
- CNN
- 컴퓨터구조
- 영어공부
- CSS
- 데이터베이스
- 정보처리기사실기
- numpy/pandas
- 딥러닝
- 운영체제
- 자바
- 파이썬라이브러리
- 데이터입출력구현
- 중학수학
- 텍스트마이닝
- 코딩테스트
- 중학1-1
- 연습문제
- SQL
- 정보처리기사필기
- pandas
- 파이썬
- 혼공머신
- 자바 실습
- 정수와유리수
- JSP/Servlet
- 머신러닝
- C++
- 데이터분석
- Today
- Total
클라이언트/ 서버/ 엔지니어 "게임 개발자"를 향한 매일의 공부일지
트리 알고리즘 1 - 결정 트리 1 : 결정 트리 알고리즘으로 레드 와인과 화이트 와인 분류하기 본문
이번에 공부할 단원은 트리 알고리즘이다. 난 아무래도 하나의 과정이 끝나야 다음 분야가 눈에 들어오는 것 같다. 정처기는 잠시 미루고 오늘과 내일 새벽까지 6단원 학습을 마쳐볼 생각이다.
그럼 바로 학습을 시작해 보자. 여기서부터는 단 한 번도 들어보지 않은 머신러닝 모델이니 더욱 집중해서 학습해야 할 것이다.
학습 목표
결정 트리 알고리즘을 사용해 새로운 분류 문제를 다루어본다. 결정 트리가 머신러닝 문제를 어떻게 해결하는지 이해한다.
시작하기 전에
한빛 마켓에서는 신상품으로 캔 와인을 판매하려고 한다. 입고된 와인을 보니 급하게 제작하는 바람에 레드 와인과 화이트 와인 표시가 누락되었다. 김팀장은 혼공머신을 불러 이 문제를 해결할 것을 부탁한다.
혼공머신은 일단 알코올 도수, 당도, pH 값에 로지스틱 회귀 모델을 적용할 계획을 세운다.
로지스틱 회귀로 와인 분류하기
먼저 와인 샘플 데이터셋을 불러와야 한다. 와인 데이터셋을 데이터프레임으로 제대로 읽었는지 확인하기 위해 처음 5개의 샘플을 확인해 본다.
처음 3개의 열(alcohol, sugar, pH)은 각각 알코올 도수, 당도, pH값을 나타낸다. 네 번째 열(class)은 타깃값으로 0이면 레드 와인, 1이면 화이트 와인이다. 레드 와인과 화이트 와인을 구분하는 이진 분류 문제이고, 화이트 와인이 양성 클래스이다. 즉 전체 와인 데이터에서 화이트 와인을 골라내는 문제이다.
먼저 info() 메서드로 각 열의 데이터 타입과 누락된 데이터가 있는지 확인했다. 출력 결과를 보면 총 6497개의 샘플이 있고 4개의 열은 모두 실수값이다. 누락된 값은 없는 것 같다.
다음에 알아볼 메서드는 describe()이다. 이 메서드는 열에 대한 간략한 통계를 출력한다. 평균, 표준편차(std), 최소, 최대값을 볼 수 있다. 또 중간값과 1사분위수(25%), 3사분위수(75%)를 알려준다.
사분위수는 데이터를 순서대로 4등분한 값이다. 예를 들어 2사분위수(중간값)는 데이터를 일렬로 늘어놓았을 때 정중앙 값이다. 만약 데이터 개수가 짝수개라 중앙값을 선택할 수 없다면 가운데 2개 값의 평균을 사용한다.
여기서 알 수 있는 것은 알코올 도수와 당도, pH 값의 스케일이 다르다는 것이다. 이전에 했던 것처럼 사이킷런의 StandardScaler 클래스를 사용해 특성을 표준화해야 한다.
wine 데이터프레임에서 처음 3개의 열을 넘파이 배열로 바꿔서 data 배열에 저장했다. 그리고 마지막 class 열을 넘파이 배열로 바꾼 후 target 배열에 저장한다. 이제 훈련 세트와 테스트 세트로 나누는 작업을 진행한다. train_test_split() 함수는 설정값을 지정하지 않으면 25% 정도만 테스트 세트로 나눈다.
확인 결과 훈련 세트는 5197개, 테스트 세트는 1300개가 나왔다. 이제 StandardScaler 클래스를 사용해 훈련 세트를 전처리했다.
표준 점수로 변환된 train_scaled와 test_scaled를 사용해 로지스틱 회귀 모델을 훈련했다. 점수가 높지 않다. 훈련 세트와 테스트 세트의 점수가 모두 낮으니 모델이 과소적합된 것 같다. 이 문제를 해결하기 위해 규제 매개변수 C의 값을 바꿔보겠다.
이 모델을 설명하기 위해 로지스틱 회귀가 학습한 계수와 절편을 출력했다.
알코올 도수와 당도가 높을수록 화이트 와인일 가능성이 높고, pH가 높을수록 레드 와인일 가능성이 높은 것 같다. 하지만 이 숫자들이 어떤 의미인지 설명하기 어렵다. 대부분의 머신러닝 모델은 이렇게 학습의 결과를 설명하기 어렵다.
이 보고서를 조금 더 쉬운 방법으로 이해하기 위해 이사님은 순서도를 그리며 모델을 설명해 본다. pH가 크면 레드 와인이고, 그렇지 않으면 화이트 와인이라고..
결정 트리
결정 트리는 스무고개처럼 질문을 하나씩 던져서 정답을 맞혀가는 것이다. 데이터를 잘 나눌 수 있는 질문을 찾는다면 계속 질문을 추가해서 분류 정확도를 높일 수 있다. 사이킷런은 결정 트리 알고리즘을 제공한다. 사이킷런의 DecisionTreeClassifier 클래스를 사용해 결정 트리 모델을 훈련해 보겠다.
훈련 세트에 대한 점수가 높게 나왔다. 하지만 테스트 세트의 성능은 그에 비해 조금 낮다. 과대적합된 모델이라고 볼 수 있다. 결정 트리 그림은 이와 같다. 마치 수양버들 나뭇잎처럼 늘어졌다. 진짜 나무는 밑에서부터 하늘 위로 자라나지만, 결정 트리는 위에서부터 아래로 거꾸로 자라난다. 맨 위의 노드를 루트 노드라 부르고 맨 아래 끝에 달린 노드를 리프 노드라고 한다.
너무 복잡하니 plot_tree() 함수에서 트리의 깊이를 제한해서 출력해 본다. max_depth 매개변수를 1로 주면 루트 노드를 제외하고 하나의 노드를 더 확장해서 그린다. 또 filled 매개변수에서 클래스에 맞게 노드의 색을 칠할 수 있다. feature_names 매개변수에는 특성의 이름을 전달할 수 있다.
이제 확실히 잘 보인다. 그림을 읽는 방법은 다음과 같다. 루트 노드는 당도가 -0.239 이하인지 질문한다. 만약 어떤 샘플의 당도가 -0.239와 같거나 작으면 왼쪽 가지로 간다. 그렇지 않으면 오른쪽 가지로 이동한다. 루트 노드의 총 샘플 수는 5197개이고, 음성 클래스는 1258개, 양성 클래스는 3939개이다.
왼쪽 노드는 당도가 더 낮은 지를 물어본다. 루트 노드보다 양성 클래스, 즉 화이트 와인의 비율이 크게 줄어들었다. 그 이유는 오른쪽 노드를 보면 알 수 있다. 오른쪽 노드는 음성 클래스가 81개, 양성 클래스가 2194개로 대부분의 화이트 와인 샘플이 이 노드로 이동했다. 루트 노드보다 이 노드가 더 진하고, 왼쪽 노드는 더 연해졌다. plot_tree() 함수에서 filled=True로 지정하면 클래스마다 색깔을 부여하고, 어떤 클래스의 비율이 높아지면 점점 더 진한 색으로 표시한다.
결정 트리에서 리프 노드에서 가장 많은 클래스가 예측 클래스가 된다. 만약 이 결정 트리의 성장을 여기서 멈춘다면 왼쪽 노드에 도달한 샘플과 오른쪽 노드에 도달한 샘플은 모두 양성 클래스로 예측된다. 두 노드 모두 양성 클래스의 개수가 많기 때문이다.
불순도
gini는 지니 불순도를 의미한다. DecisionTreeClassifier 클래스의 criterion 매개변수의 기본값이 gini이다. criterion 개개변수의 용도는 노드에서 데이터를 분할할 기준을 정하는 것이다. 앞서 그린 루트 노드는 어떻게 당도 -0.269를 기준으로 왼쪽과 오른쪽 노드로 나누었을까? 바로 criterion 매개변수에 지정한 지니 불순도를 사용한다.
지니 불순도는 클래스의 비율을 제곱해서 더한 다음 1에서 빼면 된다. 루트 노드와 왼쪽, 오른쪽 노드의 지니 불순도를 계산하면 이와 같다. 노드에 하나의 클래스만 있다면 지니 불순도는 0이 되어 가장 작다. 이런 노드를 순수 노드라고도 부른다. 결정 트리 모델은 부모 노드와 자식 노드의 불순도 차이가 가능한 크도록 트리를 성장시킨다.
부모 노드와 자식 노드의 불순도 차이를 계산하는 방법은 다음과 같다. 먼저 자식 노드의 불순도를 샘플 기새에 비례하여 모두 더한다. 그다음 부모 노드의 불순도에서 빼면 된다.
예를 들어 앞의 트리 그림에서 루트 노드를 부모 노드라 하면 왼쪽 노드와 오른쪽 노드가 자식 노드가 된다. 왼쪽 노드로는 2922개의 샘플이 이동했고, 오른쪽 노드로는 2275개의 샘플이 이동했다. 그럼 불순도의 차이는 0.066이 된다. 이런 부모와 자식 노드 사이의 불순도 차이를 정보 이득이라고 한다. 이 알고리즘은 정보 이득이 최대가 되도록 데이터를 나눈다.
DecisionTreeClassifier 클래스에서 creiterion='entropy'를 지정하여 엔트로피 불순도를 사용할 수 있다. 엔트로피 불순도도 노드의 클래스 비율을 사용하지만 지니 불순도처럼 제곱이 아니라 밑이 2인 로그를 사용하여 곱한다.
앞의 트리는 제한 없이 자라났기 때문에 훈련 세트보다 테스트 세트에서 점수가 크게 낮았다. 이 문제를 다루어보자.
가지치기
열매를 잘 맺기 위해 과수원에서 가지치기를 하는 것처럼 결정 트리도 가지치기를 해야 한다. 결정 트리에서 가지치기를 하는 가장 간단한 방법은 자라날 수 있는 트리의 최대 깊이를 지정하는 것이다. max_depth 매개변수를 3으로 지정하여 모델을 만들었다.
훈련 세트의 성능은 낮아졌지만 테스트 세트의 성능은 거의 그대로이다. 그림으로 그리면 이와 같다. 그래프를 따라가면서 샘플이 어떻게 나뉘는지 확인할 수 있다. 루트 노드 다음에 있는 깊이 1의 노드는 모두 당도를 기준으로 훈련 세트를 나눈다. 하지만 깊이 2의 노드는 맨 왼쪽의 노드만 당도를 기준으로 나 누고 왼쪽에서 두 번째 노드는 알코올 도수를 기준으로 나눈다.
깊이 3에 있는 노드가 최종 노드인 리프 노드이다. 왼쪽에서 세 번째에 있는 노드만 음성 클래스가 더 많다. 이 노드에 도착해야만 레드 와인으로 예측한다. 루트 노드부터 이 노드까지 도달하려면 당도는 -0.239보다 작고 -0.802보다 커야 한다. 당도가 -0.802보다 크고 -0.239보다 작은 와인 중에 알코올 도수가 0.454와 같거나 작은 것이 레드 와인이다.
그런데 -0.802라는 음수로 된 당도를 어떻게 설명해야 할까? 앞서 불순도를 기준으로 샘플을 나눈다고 했다. 불순도는 클래스별 비율을 가지고 계산했다. 샘플을 어떤 클래스 비율로 나누는지 계산할 때 특성값의 스케일이 계산에 영향을 미칠까? 특성값의 스케일은 결정 트리 알고리즘에 아무런 영향을 미치지 않는다.
따라서 표준화 전처리를 할 필요가 없다. 이것이 결정 트리 알고리즘의 또 다른 장점 중 하나이다.
그럼 앞서 전처리하기 전의 훈련 세트와 테스트 세트로 결정 트리 모델을 훈련해 보겠다.
결과를 보면 같은 트리지만, 특성값을 표준점수로 바꾸지 않은 터라 이해하기가 훨씬 쉽다. 당도가 1.625보다 크고 4.325보다 작은 와인 중에 알코올 도수가 11.025와 같거나 작은 것이 레드 와인이다. 그 외에는 모두 화이트 와인으로 예측했다.
마지막으로 결정 트리는 어떤 특성이 가장 유용한지 나타내는 특성 중요도를 계산해 준다. 이 트리의 루트 노드와 깊이 1에서 당도를 사용했기 때문에 아마도 당도가 가장 유용한 특성 중 하나일 것 같다. 특성 중요도는 결정 트리 모델의 feature_importances_ 속성에 저장되어 있다.
역시 두 번째 특성이 당도가 0.87 정도로 특성 중요도가 가장 높다. 그다음 알코올 도수, pH순이다. 이 값을 모두 더하면 1이 된다. 특성 중요도는 각 노드의 정보 이득과 전체 샘플에 대한 비율을 곱한 후 특성별로 더하여 계산한다. 특성 중요도를 활용하면 결정 트리 모델을 특성 선택에 활용할 수 있다.
학습을 마치고
와인을 분류하는 결정 트리에 대해서 공부해 보았다. 처음 들어보는 개념이었는데 그래도 잘 이해했다. 강의 화면이 작아서 잘 구분하기 어려웠는데 실습을 진행하면서 지금은 아리송했던 내용들이 어느 정도 잡힐 것 같다. 트리 알고리즘도 공부하길 정말 잘했다는 생각이 들었다.
'인공지능 > 머신러닝' 카테고리의 다른 글
트리 알고리즘 3 - 교차 검증과 그리드 서치 1 : 교차 검증 및 그리스 서치와 랜덤 서치의 차이를 알고 최적의 성능을 내는 방법 (2) | 2024.09.30 |
---|---|
트리 알고리즘 2 - 결정 트리 2 : 스스로 실습하고 문제 풀어보는 시간 (0) | 2024.09.29 |
다양한 분류 알고리즘 4 - 확률적 경사 하강법 2 : 스스로 실습하고 문제 풀어보는 시간 (0) | 2024.09.29 |
다양한 분류 알고리즘 3 - 확률적 경사 하강법 1 : 확률적 경사 하강법과 손실 함수에 대하여 (0) | 2024.09.29 |
다양한 분류 알고리즘 2 - 로지스틱 회귀 2 : 스스로 실습하고 문제 풀어보는 시간 (0) | 2024.09.29 |