Skip to main content
Summary

나무 한 그루보다 숲이 더 안정적이다

이전 장에서 우리는 결정트리를 만났습니다. 결정트리는 질문을 하나씩 던지며 데이터를 나누는 모델입니다. "나이가 몇 살 이상인가?", "소득이 일정 금액보다 높은가?", "최근 한 달 동안 로그인한 적이 있는가?"처럼 조건을 따라 내려가다 보면 마지막 잎에서 예측이 나옵니다.

결정트리는 매력적입니다. 사람이 이해하기 쉽고, 데이터가 어떤 기준으로 나뉘는지도 눈에 잘 보입니다. 하지만 약점도 뚜렷합니다. 훈련 데이터에 너무 민감하다는 점입니다. 데이터 몇 개가 바뀌거나, 우연히 섞인 패턴이 있으면 트리의 모양이 크게 달라질 수 있습니다. 마치 한 사람의 의견만 듣고 중요한 결정을 내리는 것과 비슷합니다. 그 사람이 운 좋게 잘 맞힐 때도 있지만, 특정 경험에 지나치게 끌려 엉뚱한 판단을 할 때도 있습니다.

랜덤포레스트는 이 문제를 아주 단순하면서도 강력한 방식으로 해결합니다.

한 그루의 결정트리에 모든 것을 맡기지 않고, 여러 그루의 결정트리를 만든 뒤 그 의견을 합칩니다. 분류 문제라면 여러 트리가 투표하고, 회귀 문제라면 여러 트리의 예측값을 평균냅니다. 그래서 이름도 랜덤포레스트, 즉 '무작위 숲'입니다.

숲을 떠올려 봅시다. 나무 한 그루는 바람에 쉽게 흔들릴 수 있습니다. 하지만 숲 전체를 보면 한 그루의 흔들림이 전체 풍경을 망치지는 않습니다. 랜덤포레스트의 핵심 감각도 바로 여기에 있습니다.

랜덤포레스트

앙상블: 여러 모델의 의견을 합치는 방법

랜덤포레스트를 이해하려면 먼저 앙상블이라는 말을 알아야 합니다. 앙상블은 여러 모델을 함께 사용해 더 좋은 예측을 만드는 방법입니다. 음악에서 앙상블은 여러 연주자가 함께 어울려 하나의 소리를 만드는 것을 뜻합니다. 머신러닝에서도 비슷합니다. 모델 하나가 혼자 판단하는 대신, 여러 모델이 각자 판단하고 그 결과를 모읍니다.

예를 들어 타이타닉 생존 예측 문제를 생각해 봅시다. 어떤 승객이 생존했을지 예측하는 분류 문제입니다. 결정트리 하나는 이렇게 말할 수 있습니다.

"이 승객은 생존했을 가능성이 높습니다."

그런데 다른 트리는 다르게 판단할 수 있습니다.

"아니요, 이 승객은 생존하지 못했을 가능성이 높습니다."

랜덤포레스트는 여러 트리에게 같은 승객을 보여준 뒤 투표를 시킵니다. 100그루의 트리 중 73그루가 "생존"이라고 말하고, 27그루가 "비생존"이라고 말한다면 최종 예측은 "생존"이 됩니다.

회귀 문제에서는 투표 대신 평균을 냅니다. 집값 예측 모델을 예로 들어 봅시다. 여러 트리가 각각 다음처럼 예측했다고 해 보겠습니다.

  • 첫 번째 트리: 5억 1천만 원

  • 두 번째 트리: 4억 9천만 원

  • 세 번째 트리: 5억 4천만 원

  • 네 번째 트리: 5억 0천만 원

이때 랜덤포레스트는 이 값들을 평균내어 최종 집값을 예측합니다. 어떤 트리가 조금 과하게 높게 예측하고, 어떤 트리가 조금 낮게 예측하더라도 평균을 내면 극단적인 판단이 완화됩니다.

이것이 앙상블의 기본 아이디어입니다. 하나의 모델이 가진 실수를 여러 모델의 협력으로 줄이는 것입니다.

그런데 같은 트리를 여러 개 만들면 무슨 소용일까

여기서 중요한 질문이 생깁니다.

"결정트리를 여러 개 만든다고 해도, 모두 똑같은 데이터를 보고 똑같은 방식으로 학습하면 결국 같은 트리만 여러 개 생기는 것 아닌가?"

맞습니다. 똑같은 트리 100개를 만들어 놓고 투표를 시키면 사실상 한 트리의 의견을 100번 복사한 것과 다르지 않습니다. 앙상블이 힘을 가지려면 모델들이 서로 조금씩 달라야 합니다.

랜덤포레스트는 이 차이를 만들기 위해 두 가지 무작위성을 사용합니다. 첫째, 각 트리가 보는 데이터를 조금씩 다르게 만듭니다. 둘째, 각 트리가 질문을 만들 때 참고하는 특징도 조금씩 다르게 제한합니다.

먼저 데이터부터 봅시다. 전체 훈련 데이터가 1,000개 있다고 해도, 모든 트리가 똑같은 1,000개를 그대로 보는 것은 아닙니다. 랜덤포레스트는 데이터에서 일부를 뽑아 각 트리에게 나눠 줍니다. 이때 같은 데이터가 여러 번 뽑힐 수도 있고, 어떤 데이터는 특정 트리의 학습에서 빠질 수도 있습니다. 이런 방식은 흔히 부트스트랩 샘플링이라고 부릅니다. 말이 어렵지만 감각은 단순합니다. "각 트리에게 조금씩 다른 문제집을 나눠 준다"는 뜻입니다.

다음은 특징입니다. 예를 들어 고객 이탈 예측 모델에 다음과 같은 특징이 있다고 해 봅시다.

  • 가입 기간

  • 월 결제 금액

  • 최근 로그인 횟수

  • 고객센터 문의 횟수

  • 할인 쿠폰 사용 여부

  • 이용 중인 요금제

결정트리 하나를 만들 때 모든 특징을 항상 자유롭게 사용하게 하면, 어떤 강한 특징 하나에 지나치게 의존할 수 있습니다. 예를 들어 "최근 로그인 횟수"가 매우 강력한 힌트라면 대부분의 트리가 비슷한 첫 질문을 던질 가능성이 큽니다.

랜덤포레스트는 이를 막기 위해 각 분기에서 일부 특징만 후보로 보게 합니다. 어떤 트리는 가입 기간과 결제 금액을 중심으로 판단하고, 어떤 트리는 고객센터 문의 횟수와 요금제를 중심으로 판단합니다. 이렇게 하면 트리들이 서로 다른 관점에서 데이터를 보게 됩니다.

사람으로 비유하면 더 쉽습니다. 한 명은 가격에 민감한 고객 패턴을 잘 보고, 다른 한 명은 사용 빈도를 잘 보고, 또 다른 한 명은 문의 이력을 잘 보는 식입니다. 각자의 시야는 조금 제한되어 있지만, 여러 명의 의견을 합치면 오히려 더 넓은 판단이 됩니다.

랜덤포레스트가 과적합에 강한 이유

결정트리는 깊게 자라면 훈련 데이터를 거의 외울 수 있습니다. 외운다는 것은 좋은 일이 아닙니다. 시험 문제와 정답을 통째로 암기한 학생이 새로운 문제를 만나면 약해지는 것과 같습니다. 머신러닝에서는 이런 현상을 과적합이라고 부릅니다.

단일 결정트리는 특히 과적합에 취약합니다. 질문을 계속 쪼개다 보면 아주 작은 데이터 조각까지 맞추려 하기 때문입니다. 예를 들어 집값 예측에서 어떤 트리가 "방 개수", "면적", "역과의 거리", "건축 연도", "층수"를 계속 조합하다가 훈련 데이터 속 몇몇 집의 특이한 가격까지 맞추려 할 수 있습니다. 훈련 데이터에서는 성적이 좋지만, 새로운 집을 만나면 예측이 흔들립니다.

랜덤포레스트는 이 문제를 완화합니다. 이유는 각 트리가 서로 다른 방향으로 실수하기 때문입니다.

트리 A는 어떤 집값을 너무 높게 예측할 수 있습니다. 트리 B는 같은 집값을 조금 낮게 예측할 수 있습니다. 트리 C는 주변 지역을 더 중요하게 보고, 트리 D는 면적을 더 중요하게 볼 수 있습니다. 이들의 예측을 평균내면 한 트리의 극단적인 판단이 줄어듭니다.

분류에서도 비슷합니다. 스팸 메일 분류기를 만든다고 해 봅시다. 어떤 트리는 "무료", "당첨", "긴급" 같은 단어에 민감하게 반응할 수 있습니다. 다른 트리는 발신자 주소나 링크 개수에 더 집중할 수 있습니다. 한 트리가 우연한 단어 조합에 속더라도, 다른 트리들이 균형을 잡아 주면 최종 판단은 더 안정적이 됩니다.

여기서 중요한 점은 랜덤포레스트가 과적합을 완전히 없애는 마법의 도구는 아니라는 것입니다. 데이터가 너무 적거나, 특징에 심각한 오류가 있거나, 훈련 데이터와 실제 데이터의 성격이 크게 다르면 랜덤포레스트도 좋은 예측을 하기 어렵습니다. 다만 단일 결정트리보다 우연한 패턴에 덜 휘둘리도록 설계되어 있습니다.

이 장에서 기억해야 할 문장은 이것입니다.

랜덤포레스트는 여러 결정트리를 일부러 다르게 만들고, 그 예측을 합쳐 더 안정적인 판단을 만든다.

분류에서는 투표, 회귀에서는 평균

랜덤포레스트의 최종 예측 방식은 문제 유형에 따라 조금 다릅니다. 하지만 어렵지 않습니다.

분류 문제에서는 투표를 합니다. 타이타닉 생존 예측, 스팸 메일 분류, 고객 이탈 예측처럼 정답의 종류를 고르는 문제라면 각 트리가 하나의 선택지를 고릅니다. 그리고 가장 많은 표를 얻은 선택지가 최종 예측이 됩니다.

예를 들어 고객 이탈 예측에서 10그루의 트리가 다음처럼 판단했다고 해 봅시다.

  • 이탈: 7표

  • 유지: 3표

이 경우 랜덤포레스트는 이 고객이 이탈할 가능성이 높다고 예측합니다. 모델 구현에 따라서는 단순히 "이탈"이라고만 말하는 것이 아니라, 이탈 확률을 0.7처럼 표현할 수도 있습니다. 10그루 중 7그루가 이탈이라고 봤으니 70% 정도의 확신으로 볼 수 있는 셈입니다.

회귀 문제에서는 평균을 냅니다. 집값, 매출, 온도, 배송 시간처럼 숫자를 예측하는 문제에서는 각 트리가 숫자 하나를 내놓습니다. 랜덤포레스트는 이 숫자들을 평균내어 최종 예측값을 만듭니다.

이 구조는 우리가 앞에서 반복해 온 머신러닝의 흐름과 그대로 이어집니다.

데이터를 준비합니다. 특징을 만듭니다. 여러 트리가 각자 예측합니다. 실제값과 비교합니다. 오차를 줄이는 방향으로 모델을 만듭니다. 그리고 새로운 데이터에 적용합니다.

다만 랜덤포레스트에서는 "모델 하나"가 아니라 "모델들의 모임"이 예측한다는 점이 다릅니다.

랜덤이라는 말이 불안하게 들릴 때

처음 랜덤포레스트를 들으면 이런 생각이 들 수 있습니다.

"랜덤이라니, 아무렇게나 만든다는 뜻인가?"

그렇지 않습니다. 여기서 랜덤은 엉망이라는 뜻이 아니라, 다양성을 만들기 위한 장치입니다. 같은 선생님에게 같은 교재로 같은 방식의 답안만 100번 받는 것보다, 서로 다른 관점의 답안을 여러 개 받아 비교하는 편이 더 튼튼한 판단으로 이어질 수 있습니다.

랜덤포레스트의 무작위성은 통제된 무작위성입니다. 데이터도 아무렇게나 버리는 것이 아니라, 각 트리가 조금씩 다른 표본을 보게 합니다. 특징도 아무렇게나 무시하는 것이 아니라, 각 분기에서 일부 후보만 보게 해 트리들이 서로 닮아 가는 것을 막습니다.

이 다양성이 없으면 숲은 숲이 아니라 같은 나무를 복사해 세워 놓은 전시장에 가까워집니다. 랜덤포레스트가 강한 이유는 트리의 수가 많아서만이 아니라, 그 트리들이 서로 조금씩 다르기 때문입니다.

특징 중요도: 모델은 무엇을 보고 판단했을까

랜덤포레스트의 또 다른 장점은 특징 중요도를 확인할 수 있다는 점입니다. 특징 중요도는 모델이 예측할 때 어떤 입력을 상대적으로 많이 활용했는지 보여 주는 값입니다.

예를 들어 고객 이탈 예측 모델을 만들었더니 특징 중요도가 다음과 비슷하게 나왔다고 해 봅시다.

  • 최근 로그인 횟수: 높음

  • 고객센터 문의 횟수: 높음

  • 가입 기간: 중간

  • 월 결제 금액: 낮음

이 결과를 보면 모델이 고객 이탈을 예측할 때 최근 로그인 횟수와 고객센터 문의 횟수를 중요하게 본다는 힌트를 얻을 수 있습니다. 실제로 최근 로그인 횟수가 급격히 줄고 고객센터 문의가 많아진 고객은 서비스에 불만을 느끼고 있을 가능성이 있습니다.

집값 예측에서도 특징 중요도는 유용합니다. 면적, 위치, 방 개수, 건축 연도, 지하철역과의 거리 중 무엇이 예측에 큰 영향을 주는지 살펴볼 수 있습니다. 스팸 메일 분류에서는 특정 단어, 링크 개수, 발신자 정보 같은 특징이 얼마나 중요한지 확인할 수 있습니다.

다만 특징 중요도를 해석할 때는 조심해야 합니다. 중요도가 높다고 해서 반드시 원인이라는 뜻은 아닙니다. 모델이 예측에 자주 활용했다는 뜻이지, 그 특징이 현실에서 결과를 직접 만들어 냈다는 뜻은 아닙니다.

예를 들어 우산 판매량과 비 오는 날은 관련이 큽니다. 하지만 우산 판매량이 비를 내리게 하는 것은 아닙니다. 마찬가지로 고객센터 문의 횟수가 이탈 예측에 중요하게 나왔다고 해서, 문의 횟수 자체가 언제나 이탈의 원인이라고 단정할 수는 없습니다. 문의 횟수는 불만의 신호일 수도 있고, 서비스 사용량이 많다는 신호일 수도 있습니다.

특징 중요도는 모델을 이해하기 위한 손전등입니다. 어두운 방 전체를 완벽하게 밝혀 주지는 않지만, 모델이 어디를 보고 있는지 감을 잡게 해 줍니다.

랜덤포레스트를 쓸 때의 감각

랜덤포레스트는 실무에서 자주 좋은 출발점이 됩니다. 이유는 단순합니다. 데이터 전처리를 아주 복잡하게 하지 않아도 꽤 괜찮은 성능을 내는 경우가 많고, 회귀와 분류 문제 모두에 사용할 수 있으며, 단일 결정트리보다 안정적입니다.

물론 단점도 있습니다. 트리가 여러 개이기 때문에 단일 결정트리보다 계산량이 많습니다. 또 숲 전체의 판단을 완전히 한눈에 이해하기는 어렵습니다. 결정트리 하나는 그림으로 그려서 따라갈 수 있지만, 수백 그루의 트리를 모두 사람이 읽기는 어렵습니다. 그래서 랜덤포레스트는 해석 가능성과 성능 사이에서 균형을 잡는 모델이라고 볼 수 있습니다.

결정트리 하나는 설명하기 쉽지만 흔들리기 쉽습니다. 랜덤포레스트는 조금 덜 투명해지는 대신 더 안정적인 예측을 얻습니다. 머신러닝에서는 이런 교환이 자주 등장합니다. 모델이 단순할수록 이해하기 쉽지만 복잡한 패턴을 놓칠 수 있고, 모델이 복잡해질수록 성능은 좋아질 수 있지만 해석은 어려워질 수 있습니다.

그래서 랜덤포레스트를 사용할 때는 다음 질문을 함께 던지는 것이 좋습니다.

  • 단일 결정트리보다 테스트 데이터에서 성능이 좋아졌는가?

  • 특정 특징 하나에 지나치게 의존하고 있지는 않은가?

  • 특징 중요도가 현실적인 해석과 어느 정도 맞아떨어지는가?

  • 트리의 개수나 깊이를 조정했을 때 성능이 어떻게 변하는가?

이 질문들은 단순히 모델을 실행하는 사람과 모델을 이해하는 사람을 갈라놓습니다. 버튼만 누르면 모델은 만들어집니다. 하지만 좋은 머신러닝 사용자는 모델이 왜 그런 판단을 했는지, 새로운 데이터에서도 잘 작동할지 계속 의심합니다.

작은 예: 스팸 메일 숲 만들기

스팸 메일 분류기를 다시 떠올려 봅시다. 우리는 각 메일에서 여러 특징을 만들 수 있습니다. 제목에 특정 단어가 포함되어 있는지, 링크가 몇 개인지, 발신자 주소가 낯선지, 느낌표가 지나치게 많은지, 본문 길이는 어느 정도인지 같은 정보입니다.

단일 결정트리는 이 특징들을 바탕으로 하나의 질문 흐름을 만듭니다. 예를 들면 이렇게 판단할 수 있습니다.

"링크가 3개 이상인가? 그렇다면 제목에 '무료'가 있는가? 그렇다면 스팸일 가능성이 높다."

하지만 이 트리는 우연히 훈련 데이터에 많았던 패턴을 외울 수 있습니다. 어떤 정상 메일도 링크가 많고 '무료'라는 단어를 포함할 수 있습니다. 예를 들어 온라인 강의 플랫폼에서 보낸 "무료 특강 안내" 메일은 정상 메일일 수 있습니다.

랜덤포레스트는 여러 트리를 만듭니다. 어떤 트리는 링크 개수를 중요하게 보고, 어떤 트리는 발신자 주소를 중요하게 보고, 어떤 트리는 제목 단어보다 본문 길이를 더 봅니다. 최종 판단은 이들의 투표로 정해집니다. 그래서 특정 단어 하나에 속을 가능성이 줄어듭니다.

이 장면은 랜덤포레스트의 장점을 잘 보여 줍니다. 모델 하나가 세상을 완벽히 이해하지 못해도 괜찮습니다. 서로 다른 관점의 모델들이 함께 판단하면, 한 모델의 편견이나 실수가 전체 결론을 덜 흔들게 됩니다.

이번 장의 핵심

랜덤포레스트는 결정트리를 여러 개 모아 만든 앙상블 모델입니다. 분류 문제에서는 여러 트리의 투표로 정답을 고르고, 회귀 문제에서는 여러 트리의 예측값을 평균냅니다.

중요한 것은 트리를 많이 만든다는 사실만이 아닙니다. 각 트리가 서로 다르게 학습하도록 데이터와 특징을 조금씩 다르게 사용한다는 점이 핵심입니다. 이 무작위성 덕분에 트리들은 서로 다른 실수를 하게 되고, 최종 예측은 한 트리보다 더 안정적이 됩니다.

단일 결정트리는 이해하기 쉽지만 과적합에 취약합니다. 랜덤포레스트는 여러 트리의 판단을 합쳐 과적합을 줄이고 새로운 데이터에 더 잘 대응하도록 돕습니다. 또한 특징 중요도를 통해 모델이 어떤 입력을 중요하게 활용했는지 살펴볼 수 있습니다.

이제 우리는 결정트리 하나에서 출발해 여러 트리가 협력하는 숲까지 왔습니다. 다음에는 또 다른 강력한 앙상블 방식인 그래디언트 부스팅을 살펴볼 차례입니다. 랜덤포레스트가 여러 트리를 비교적 독립적으로 만들어 의견을 모으는 방식이라면, 그래디언트 부스팅은 앞선 모델의 실수를 다음 모델이 이어받아 고쳐 가는 방식입니다. 숲이 회의를 통해 판단했다면, 부스팅은 오답 노트를 보며 한 걸음씩 실력을 끌어올리는 방식에 가깝습니다.

책 목록

처음 만나는 머신러닝: 데이터가 스스로 규칙을 배우는 법

전체 목차 보기

이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.

틸노트는 사용자가 AI를 활용해 노트를 쉽게 작성하거나 편집할 수 있는 서비스입니다.

AI 스퀘어 단톡방에 함께해요

AI 활용과 틸노트 사용 팁을 나누는 오픈채팅방입니다. 입장 비밀번호는 tilnote입니다.

참여하기