본문 바로가기

머신러닝(Machine Learning)/실무

랜덤 포레스트를 이용한 식용 가능한 버섯 구분하기




이 포스팅은 서적 '머신러닝, 딥러닝 실전개발 입문'을 참고한 포스팅입니다.




랜덤 포레스트(Random Forest, Randomized Trees)란 학습 전용 데이터를 기반으로 다수의 의사결정 트리를 만들고, 


만들어진 의사결정 트리를 기반으로 다수결로 결과를 유도하는 머신러닝 모델 중 하나이다.



의사결정 트리 라는 것은 트리 구조를 하고 있는 그래프인데, 예측과 분류를 수행하는 알고리즘 자체를 의사결정 트리라고 부른다.


귀납적 추론을 기반으로 하는 의사결정 트리는 실무적으로 가장 많이 사용되고 있는 머신러닝 모델 중 하나로 지도학습 모델이다.



의사결정 트리는 주로 불연속 데이터를 다루며 노이즈가 발생해도 중단되거나 엉뚱한 결과를 보여주지 않는 매우 강건한 모델이다.


의사결정 트리의 대표적인 적용 사례로는 


환자의 진료기록을 토대로 증상을 유추하는 경우


대출을 받고자 하는 사람의 신용을 평가하는 경우


대출자의 상환 불이행 가능성을 예측하는 경우 등이 있다,



그림으로 살펴보자.





의사 결정 트리또한 전형적인 분류 모델 중 하나인데, 위는 필기체 숫자 이미지를 분류하는 것을 직관적으로 나타낸다.


아마도 그림을 보면 직관적으로 어떤 의미인지 이해할 것이다.


이제 한가지만 더 깊게 생각해보면 어릴때 한번쯤은 해보았을 스무고개와 비슷하다고 생각이든다.


스무고개의 달인들은 알테지만, 스무고개 게임의 법칙은 가장 적은 질문으로 답을 알아맞히는 것이다.


이를 위해서는 질문의 전략이 필요한데, 


스무고개의 효과적인 전략은 반복적인 이등분을 할 때 이등분의 효과가 큰 속성을 먼저 묻는 식으로 진행하는 것이다.


이러한 전략은 의사결정 트리에도 동일하게 적용된다.



위의 예시처럼 하단의 역C모양인지를 먼저 질문하게되면


가장 집합의 요소의 숫자가 크게 분류할 수 있다. {3, 4, 5 ,9}와 {0, 1, 2, 6, 7, 8} 이와 같은 식으로 말이다.


조금 더 세부적인 내용은 이론 카테고리에서 함께 포스팅하겠다.


실제로 한번 구현해보자.






보다 더 흥미로운 이해를 위해 오늘의 실습 내용을 한번 시나리오화 해보겠다.



나는 한국 지역의 버섯 전문가이다. 그런데 휴가를 맞아 여행을 가던 도중에 위치도 모르는 남태평양 부근의 무인도에 표류하고 말았다.


불행인지 다행인지 모르겠으나, 무인도의 초원에는 수많은 다양한 종류의 버섯이 자라고 있었다.


허나 이곳의 버섯은 비슷하게 생겨도 한국의 생태와는 달라서 무엇이 어떤 것이 식용 가능한 것인지, 식용 불가능한 것인지 알 수 없었다.


잘알려진 사실로 '비슷한 특징을 가진 버섯은 독의 유무까지 비슷한 경향이 있다'라는 버섯의 사실과 


나의 경험을 기반으로 한 버섯의 총22개의 특징으로 식용가능한 것인지 불가능한것인지를 구분해야 살 수 있다.



예를들어 특징중에는 버섯의 머리모양이 벨형태인지, 원뿔 형태인지, 볼록한 형태인지, 평평한 형태인지, 오목한 형태인지


아니면 버섯의 머리색이 갈색인지 황갈색인지 연한 갈색인지 회색인지 등의 특징이다.



이러한 데이터들(시나리오의 내가 알고 있는 버섯들)은 UCI 머신러닝 레포지토리에 공개되어있다. 


이러한 독버섯과 관련된 데이터를 기반으로 머신러닝을 수행해보겠다,



다음 데이터 세트는 버섯의 특징을 기반으로 독의 유무를 판정하기 위한 데이터 세트를 CSV 형태의 데이터이다.



맨 앞의 특징은 독의 유무이다.


독이 있으면 "p(poisonous)", 식용이면 "e(edible)"이다.


뒤의 22개의 특징은 아까 앞서 말했듯이, 버섯의 머리모양, 버섯 머리의 색, 버섯 기둥의 색 등과 같은 특징 22개를 나타낸 것이다.


다음과 같은 데이터 세트를 기반으로 머신러닝을 수행해보자.





해당 소스코드의 라인 29에서는 RandomForestClassfier( )함수를 이용하여 랜덤 포레스트의 객체를 생성한 것을 확인할 수 있다.


랜덤 포레스트 학습기를 이용하여 해당 데이터를 학습시킨 것이였다.



자 이제 해당 소스코드의 결과를 확인해보자.





제데로 분류되었음을 확인할 수 있었다.


테스트 데이터의 2031개중 총 1057개를 식용으로, 총 974개를 독버섯으로 분류했으며,


이는 모두 레이블에 맞는 정확한 분류를 하였다고 판단되는 결과를 보인다.





고찰


해당 예에서는 버섯의 특징을 한 글자로 나타낼 수 있어서 문자 코드로 변환하기 좋았다.


허나 이를 그래프로 그리기에 앞어서 중요한 점이 한가지가 있는 데,


데이터를 숫자로 변경할 때는 주의해야 할 것이다.


예를 들어, 다음과 같이 데이터에 숫자를 할당했다고 하자



빨강 = 1, 파랑 = 2, 초록 =3, 흰색 = 4



해당 데이터의 숫자는 분류의 의미일뿐 아무런 연속적의미는 없다


예르르들어 흰색(4)가 파랑(2)의 2배이므로 해당 학습에 2배이상의 영향을 끼치도록 하면 안되는 것이다.


따라서 데이터를 분류할 때 값을 분류하기 위한 '분류 변수'인지 연속된 '연속 변수'인지를 고려해야 한다.



각각의 데이터가 상관 없다는 것을 나타내기 위해서는 매개변수를 다음과 같은 배열로 나타내야 한다.



빨강 = 1 0 0 0

파랑 = 0 1 0 0

초록 = 0 0 1 0

흰색 = 0 0 0 1



데이터의 용량은 늘어나지만 색끼리 전혀 관련성이 없다면 이렇게 다루는 것이 좋다.


이는 해당 사항을 고려한 코드이다.