데이터과학자를 꿈꾸며
How decision trees work
원문 보기
번역: 채규병
제가 제일 좋아하는 모형 중 하나가 의사결정나무입니다. 의사결정나무는 간단하면서도 강력합니다. 실제로 Kaggle 경연에서 가장 높은 퍼포먼스를 내는 모형들은 XGBoost의 여러 조합입니다. 그리고 XGBoost는 여러 개의 의사결정나무와 몇몇의 똑똑한 feature engineering으로 이루어져있습니다.
의사결정나무의 개념은 아주 직관적입니다. 자 여러분이 출근하는 시간을 기록해서 데이터 집합을 만든다고 해봅시다. 당신이 정시에 도착하는지를 알아보기 위해서 말이죠. 다음 그림을 보시면, 대부분 출발 시간이 8:15 전입니다. 그리고 이보다 15분 늦게 출발하면 지각을 하게 됩니다.
여러분은 위 패턴을 의사결정나무로 정리할 수 있습니다. 첫번째 가지를 뻗을 포인트는 "8:15 전에 출발했는가?" 입니다. 선택지는 예 혹은 아니오, 두 가지가 있습니다. 연속해서 우리는 계속 예(Yes)들을 왼쪽에 놓습니다. 의사결정의 경계를 둠으로써 데이터를 두 그룹으로 나눕니다. 비록 불규칙하거나 예외가 있을 수 있지만, 전체적인 패턴은 8:15에 의사결정의 경계를 두면서 점들이 찍힙니다. 이 패턴을 통해서 우리는 8:15 전에 출발했다면, 정시 출근을 할 것이라고 합리적으로 확신할 수 있을 것입니다. 마찬가지로 8:15 이후에 출발했다면 합리적으로 지각을 확신할 수 있습니다.
이는 가장 간단한 형태의 의사결정나무입니다. 단 한 쌍의 가지만을 가졌습니다.
의사결정나무 모형을 8:15 전과 후의 가지를 더 세부적으로 나누어 정제해봅시다. 만약 의사결정 경계를 8:00와 8:30으로 추가한다면, 우리의 정시 도착에 대한 예측을 더 나눌 수 있습니다. 8:00 전은 완전히 정시 출근이 보장됩니다. 반면 8:00 - 8:15는 아마도 정시 출근이 가능하겠으나, 8:00 전에 출발한 만큼은 보장할 수는 없을 것입니다. 이와 비슷하게 8:15 이후 출발도 더 나눌 수 있습니다. 8:15 - 8:30 출발과 8:30 이후 출발로 말입니다. 8:30 이후 출발은 거의 확실히 지각할 것이고, 8:30 전은 아주 작은 기회라도 남아 있을 것입니다.
위 의사결정나무는 두 개의 레벨을 갖고 있습니다. 이처럼 의사결정나무들은 여러분이 원하는 만큼의 레벨을 가질 수 있습니다. 가장 자주 쓰이는 형태는 각 의사결정 포인트(혹은 노드)가 두 개의 가지로 뻗는 형태입니다.
위 예는 하나의 예측 변수만 가지고 있고, 범주형 타겟 변수입니다. 예측 변수는 출발 시간이고, 타겟 변수는 정시출근 여부입니다. 범주형 변수라는 것은 딱 두 가지(Yes or No)로 구분되는 값만 가진다는 뜻입니다(물론 더 많은 범주를 가져도 범주형 변수입니다). 범주형 타겟을 가지는 의사결정나무는 분류 나무(classification trees)라고도 불립니다.
위 예를 두 개의 예측 변수가 있는 케이스로 확장해봅시다.
출발시간과 요일을 둘 다 고려해보는 겁니다. 여기서 우리는 월요일 = 1, 토요일 = 6, 그리고 일요일 = 7로 셀 것입니다.
아래 그림을 보시면, 토요일부터 일요일(주말)은 초록색으로 채워진 도넛 모양의 점들이 왼쪽으로 더 뻗어있습니다. 이는 아마도 8:10이 주중에는 정시출근하기에 충분한 시간대지만 주말에는 아니라는 것을 의미합니다.
주말에도 우리의 정시 출근에 대한 예측을 더 낫게 하기 위해서, 8:15 전의 출발시간을 주중과 주말로 더 나누어봅시다. 이제 주중에 8:15 전에 출발했다면, 완전히 정시출근입니다. 하지만 주말에 8:15 전에 출발했다면 대부분은 정시 출근하겠지만, 항상 그런 건 아닙니다. 자 하나의 노드를 가지고 있던 의사결정나무를 새로운 의사결정경계를 가지고 업데이트 해봅시다.
자 이제, 우리의 예측을 더 정제해봅시다. 주말의 8:15 전 출발을 8:00 이후와 전으로 나눕니다. 주말엔 8:00 - 8:15 사이가 대부분 지각인 것을 표현한 것입니다. 이제 두 개의 관점의 의사결정나무를 깔끔하게 4개의 다른 영역으로 나뉜 형태를 갖게 되었습니다. 이들 중 두 개는 정시 도착을 반영하고 다른 두 개는 지각을 보여줍니다.
이것은 3 레벨의 의사결정나무입니다. 모든 가지들이 똑같은 수의 레벨까지 내려가지 않아도 된다는 점을 주목해주세요.
자 이제 다음으로, 연속적인(범주형이 아닌) 타겟 변수를 가진 예제를 살펴봅시다.
모형이 연속적인 수치인 변수들에 대한 예측을 한다면, 회귀 나무(a regression tree)라고 부르기도 합니다. 지금까지 1개 혹은 2개의 관점적인 분류 나무를 살펴보았습니다. 이제부터는 회귀 나무를 살펴보겠습니다.
누군가에 기상 시간을 물어본다고 생각해봅시다. 이 질문을 통해서 우리는 나이를 예측해볼 수 있습니다. 회귀 나무의 뿌리(root, 첫 번째 노드)는 전체 데이터 집합에 대한 추정입니다. 아래 데이터 예시에서, 만약 우리가 누군가의 나이를 모른 채로 추정해야 한다면, 합리적인 추측은 6:25이 될 것입니다. 이것이 의사결정나무의 뿌리입니다.
합리적인 첫 번째 분기는 25세입니다. 평균적으로, 25세보다 어린 사람들은 7:05에 일어나고, 25세 이상의 사람들은 6:00에 일어납니다.
여전히 여기에서는 더 어린 집단이 있습니다. 그래서 이를 더 나누어보죠. 이제 12세보다 어린 사람들은 7:45에 일어난다고 추정하고, 12 - 25세의 사람들은 6:40에 일어난다고 추정할 수 있습니다.
마찬가지로 25세 이상의 집단도 더 나눌 수 있습니다. 25 - 40세 사이의 사람들은 평균적으로 6:10에 일어나고 40 - 70세는 평균적으로 5:50에 일어납니다.
집단을 더 나누었지만, 여전히 제일 어린 집단 안에서 많은 변동성이 있습니다. 그래서 더 나누어봅시다. 8세로 나눔으로써, 더 데이터에 적합(fit)하게 추정치를 정제할 수 있습니다. 지금 하고 있는 일련의 과정에서 주목해야 할 것은, 우리의 나무의 이파리(leaves)들이 하나 또는 두 개의 점들만 가지는 레벨까지 내려가고 있다는 점입니다. 물론 이는 과적합(overfitting)으로 이끌 수 있는 위험한 조건일 수 있습니다. 과적합에 대해서는 조금 있다가 논의해보도록 하겠습니다.
이처럼 나무를 도출하는 것은 누군가의 나이에 기반하는 수치적인 추정치를 만들 수 있게 해줍니다. 만약에 36세의 기상시간을 추정해야 한다면, 우리는 나무의 꼭대기에서부터 시작하면 됩니다. 25세보다 어린가요? 아니요. 오른쪽으로 갑니다. 40세보다 어린가요? 예. 왼쪽으로 갑니다. 그리하여 이 나뭇잎에 의한 추정은 6:10입니다. 의사결정나무의 구조는 여러분이 궁금해하는 어떤 나이의 사람도 각각의 상자로 정렬할 수 있게 해줍니다. 그리고 이는 그 사람의 기상시간에 대한 추정치를 만들게 해줍니다.
더 나아가 두 개의 예측 변수를 가진 회귀 나무의 예시로 확장해봅시다. 만약에 나이 뿐만 아니라, 기상하는 날의 달(Month) 또한 구한다고 해봅시다. 더 풍부한 패턴을 찾을 수 있습니다. 북부 아메리카에서는 여름의 달이 날이 더 깁니다. 이는 아침에 약간 더 일찍 일어나게 하죠 (물론 완전히 비현실적인 예시입니다..). 어린이와 십 대는 직장이나 학교의 엄격한 일정에서 부담이 없기 때문에 해가 뜨면 기상합니다(불규칙적으로 일어나지 않을까). 반대로 성인들은 계절에 따른 아주 약간의 변동성만 가지는 더 정형적인 패턴으로 떨어질 것입니다. 다시 말해, 이 예시에서 나이 든 사람들은 조금 더 일찍 일어날 것입니다.
지금까지 해온 것과 마찬가지로 의사결정나무를 만들어봅시다. 뿌리부터 시작합니다. 전체 데이터 집합에 대한 단일 추정으로 거칠지만 6:30이라고 해봅시다.
다음으로, 의사결정 경계를 두기에 좋은 장소를 찾아봅시다. 저는 35세의 나이로 데이터를 분할해서 두 개의 반 쪽들을 생성했습니다. 하나는 35세 미만의 인구에 대해 7:06에, 다른 하나는 35세 이상의 인구에 대하 6:12의 기상시간을 갖습니다.
이 과정을 반복합니다. 더 어린 인구를 9월 중순 전후로 나누고, 3월 중순 전후로 나눕니다. 이는 겨울 달과 여름 달을 분리합니다. 겨울 달에서는 35세 이하 사람들은 7:30 기상시간을 갖습니다. 그리고 여름 달에서는 6:56에 기상합니다.
다음으로 위 쪽으로 재방문해봅시다. 더 정확한 대표성을 얻기 위해 35세 이상의 인구로 가서 48세로 나누어봅시다.
또한 35세 이하 인구의 겨울 기상시간을 18세로 나눌 수 있습니다. 겨울의 18세 이하의 누군가는 7:54에 일어날 것이고, 반대로 18세 이상은 6:48에 일어납니다.
여러분은 높은 꼭대기의 출현이 보이시나요? 각각의 추가적인 커트(노드를 생성)를 만들 때마다, 우리의 의사결정나무 모형은 점차 원래 데이터 모양에 가까워집니다. 또한 오른쪽 색지도를 보시면, 의사결정경계들은 데이터 집합을 대략적으로 동일한 색깔의 구역으로 나누고 있습니다.
다음 커트에서도 이러한 추세가 계속됩니다. 여름 달에서 35세 이하의 인구를 13세로 나눕니다. 모형의 형태가 점점 더 원래 데이터의 형태과 같아집니다.
모형이 데이터의 부드러운 추세(smooth trend)를 밀접하게 나타낼 때까지 이 과정을 계속한다고 상상해봅시다. 각각의 의사결정 구역은 점진적으로 작아질 것입니다. 데이터에서 그 숨겨진 함수(underlying function)에 대한 근사는 점진적으로 나아질 것입니다.
의사결정나무의 강력함은 함정이 없는 것이 아닙니다. 더 주의해야 하는 것은 과적합(overfitting)입니다. 위 단일 변수를 가진 의사결정나무의 예시로 돌아가봅시다. 기상시간 대비 나이를 추정했던 예시말입니다. 상상해보세요. 이 나이 축을 한 개 또는 두 개의 점들이 각각의 바구니에 담길 때까지 계속해서 나눈다고 말입니다.
위 그림과 같은 모형을 만들었다면, 우리의 의사결정나무는 데이터를 아주 아주 잘 설명하고 적합(fit)합니다. 너무나 잘 맞습니다. 부드러운 곡선 데이터가 따르는 숨겨진 추세(underlying trend)를 잡아낼 뿐만 아니라, 측정된 데이터를 포함하는 소음(모형화되지 않은 변동성)도 잡아냅니다. 만약에 우리가 이 모형을 채택하고 새로운 데이터에 대해 예측한다면, 훈련 데이터의 소음이 사실상 예측을 덜 정확하게 만들 것입니다. 이상적으로는, 우리는 의사결정나무가 소음이 아니라, 숨겨진 추세를 잡아내길 바랍니다. 이러한 문제를 방지하기 위한 방법 중 하나는, 의사결정나무의 각 나뭇잎에서 한 줌의 데이터가 아니라 그보다 더 많이 있도록 확실히 하는 것입니다. 이렇게 하면 어떠한 소음도 평균화될 수 있습니다.
또 주의해서 봐야할 점은 많은 변수를 가지는 것입니다. 지금까지 한 개 차원의 회귀나무로 시작해서, "달" 데이터를 추가했고 두 개 차원의 회귀 나무를 만들었습니다. 이 방법은 얼마나 우리가 관점을 가지고 있는지를 상관하지 않습니다. 예를 들어, 위도, 하루 운동량, 체질량 지수 그리고 여러 관련성이 있다고 생각되는 다른 변수들을 추가할 수도 있습니다. 이처럼 많은 변수들을 시각화하기 위해서는 지오프레이 힌톤(딥 뉴런 네트워크 연구자)이 공유한 트릭을 사용하는 것을 추천합니다.
14차원 공간에서 초평면을 다루려면 3차원의 공간을 시각화하고 14! 라고 혼자 크게 말하십시오.
많은 변수들을 다루는 어려움은 의사결정나무가 자랄 때에 어떤 변수로 가지를 뻗을 것이냐를 결정하는 문제입니다. 만약에 너무나 많은 변수가 존재한다면 많은 연산을 필요로 할 수 있습니다. 또한 추가하는 변수가 많아질수록, 더 믿을만한 것들을 고르려면 더 많은 데이터가 필요합니다. 비교 가능하도록 데이터의 점들의 갯수과 변수들의 갯수를 위치시키는 건 쉽습니다. 우리의 데이터 집합을 테이블 형태로 표현할 때, 그 자체만으로 행의 갯수로서 열의 갯수와 비교할 수 있도록 설명합니다. 이를 다루는 방법은 많이 있습니다. 예를 들어 각 가지를 나누기 위해서 변수를 임의 추출할 수도 있습니다. 하지만 유심히 관찰하고 주의 깊게 다뤄야 합니다.
의사결정나무가 실패할 수 있는 부분을 유의한다면, 의사결정나무의 강점을 자유롭게 이용할 수 있습니다. 의사결정나무는 여러분의 데이터에 대한 가정을 가능하게 해주는 환상적인 나무입니다. 꽤 제너럴합니다. 이것들은 예측변수와 타겟변수 사이의 비선형 관계도 찾을 수 있게 해줍니다. 또한 예측변수들 사이의 상호작용 뿐만 아니라, 2차의(quadratic), 지수적(expoential), 주기적(cyclical) 그리고 다른 관계도 밝힐 수 있습니다. 필요한 커트를 나눌 수 있는 충분한 데이터만 있다면 말입니다. 더욱이 의사결정나무는 인공 뉴런 네트워크와 같은 다른 모형에서는 숨어 있을 수 있는 비평활 행동(non-smooth behaviors), 급작스런 점프(sudden jumps) 그리고 피크(peaks)도 찾아낼 수 있습니다.
의사결정나무가 지속적으로 풍부한 데이터 문제에 대해 다른 방법보다 높은 퍼포먼스를 내는 데에는 충분한 이유가 있습니다.