랜덤 포레스트는 의사 결정 트리를 만들어 다수결의 결과로 원하는 값을 추론해 내는 방법입니다.

 

아주 간단하게 설명하자면,

 

눈이 크다, 피부가 하얗다, 머리가 노란색이다 - 백인

눈이 작다, 피부가 노랗다, 머리가 검은색이다 - 동양인

눈이 크다, 피부가 검다, 머리가 검은색이다 - 흑인

 

등으로 수많은 조건들에 대한 결과값이 있는 데이터셋을 가지고,

눈은 어떤가? -> 피부색은 어떤가? -> 머리색은 어떤가? 식으로 진행을 하고 최종 인종을 결정하는 구조라 보면 됩니다.

 

제가 공부한 위키 북스에서 출간한 '파이썬을 이용한 머신러닝, 딥러닝 실전 개발 입문'이라는 책에서 소개한 예는 버섯의 특징을 가지고 그 버섯이 독이 있다/없다를 추론해 내고 있습니다.

import urllib.request as req
local= "mushroom.csv"
url = "https://archive.ics.uci.edu/ml/machine-learning-databases/mushroom/agaricus-lepiota.data"
req.urlretrieve(url, local)
print("ok")

먼저 인터넷 페이지에서 csv를 다운받습니다. 웹 브라우저가 아닌 파이썬에서 직접 코딩으로 다운 받습니다.

일단 urllib.request 모듈을 임포트 한 다음 .urlretrieve()를 이용하여 저장합니다. 

위의 코딩을 실행해보면 mushroom.csv가 자동 생성/저장되며 파일을 보면 다음과 같습니다.

 

p,x,s,n,t,p,f,c,n,k,e,e,s,s,w,w,p,w,o,p,k,s,u

e,x,s,y,t,a,f,c,b,k,e,c,s,s,w,w,p,w,o,p,n,n,g

e,b,s,w,t,l,f,c,b,n,e,c,s,s,w,w,p,w,o,p,n,n,m

p,x,y,w,t,p,f,c,n,n,e,e,s,s,w,w,p,w,o,p,k,s,u

e,x,s,g,f,n,f,w,b,k,t,e,s,s,w,w,p,w,o,e,n,a,g

e,x,y,y,t,a,f,c,b,n,e,c,s,s,w,w,p,w,o,p,k,n,g

e,b,s,w,t,a,f,c,b,g,e,c,s,s,w,w,p,w,o,p,k,n,m

e,b,y,w,t,l,f,c,b,n,e,c,s,s,w,w,p,w,o,p,n,s,m

 

위와 같은 총 23개의 알파벳의 조합이 2000개가 넘습니다.

그리고 각 알파벳은 버섯의 특징을 나타냅니다.

처음 열(p또는e)는 독이 있는(poisonous) 또는 먹을 수 있는(edible)이고,

두번째 열의 경우 버섯의 머리 모양입니다. (x/b/s/f)

 

이 역시 인터넷에서 찾아보면 다음과 같이 세부 내용을 알 수 있습니다.

About this file

Attribute Information: (classes: edible=e, poisonous=p)

  • cap-shape: bell=b,conical=c,convex=x,flat=f, knobbed=k,sunken=s
  • cap-surface: fibrous=f,grooves=g,scaly=y,smooth=s
  • cap-color: brown=n,buff=b,cinnamon=c,gray=g,green=r,pink=p,purple=u,red=e,white=w,yellow=y
  • bruises: bruises=t,no=f
  • odor: almond=a,anise=l,creosote=c,fishy=y,foul=f,musty=m,none=n,pungent=p,spicy=s
  • gill-attachment: attached=a,descending=d,free=f,notched=n
  • gill-spacing: close=c,crowded=w,distant=d
  • gill-size: broad=b,narrow=n
  • gill-color: black=k,brown=n,buff=b,chocolate=h,gray=g, green=r,orange=o,pink=p,purple=u,red=e,white=w,yellow=y
  • stalk-shape: enlarging=e,tapering=t
  • stalk-root: bulbous=b,club=c,cup=u,equal=e,rhizomorphs=z,rooted=r,missing=?
  • stalk-surface-above-ring: fibrous=f,scaly=y,silky=k,smooth=s
  • stalk-surface-below-ring: fibrous=f,scaly=y,silky=k,smooth=s
  • stalk-color-above-ring: brown=n,buff=b,cinnamon=c,gray=g,orange=o,pink=p,red=e,white=w,yellow=y
  • stalk-color-below-ring: brown=n,buff=b,cinnamon=c,gray=g,orange=o,pink=p,red=e,white=w,yellow=y
  • veil-type: partial=p,universal=u
  • veil-color: brown=n,orange=o,white=w,yellow=y
  • ring-number: none=n,one=o,two=t
  • ring-type: cobwebby=c,evanescent=e,flaring=f,large=l,none=n,pendant=p,sheathing=s,zone=z
  • spore-print-color: black=k,brown=n,buff=b,chocolate=h,green=r,orange=o,purple=u,white=w,yellow=y
  • population: abundant=a,clustered=c,numerous=n,scattered=s,several=v,solitary=y
  • habitat: grasses=g,leaves=l,meadows=m,paths=p,urban=u,waste=w,woods=d

모양, 무늬, 색, 냄새, 표면특징, 분포, 서식지 등등 여러 조건에 따라 분류를 하였습니다.

 

실제 위 학습을 해보고 정확도를 확인해보면 1이 나오는 것으로 보아 어떠한 정체 모르는 버섯을 발견했을 때 위 22가지 조건에 따라 분류를 한 다음 학습한 컴퓨터에게 물어보면 위 버섯을 먹을 수 있는지 없는지 알려준다는 것이지요.

 

import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn import metrics
from sklearn.model_selection import train_test_split
# 데이터 읽어 들이기--- (※1)
mr = pd.read_csv("mushroom.csv", header=None)
# 데이터 내부의 기호를 숫자로 변환하기--- (※2)
label = []
data = []
attr_list = []
for row_index, row in mr.iterrows():
    label.append(row.loc[0])
    row_data = []
    for v in row.loc[1:]:
        row_data.append(ord(v))
    data.append(row_data)
# 학습 전용과 테스트 전용 데이터로 나누기 --- (※3)
data_train, data_test, label_train, label_test = \
    train_test_split(data, label)
# 데이터 학습시키기 --- (※4)
clf = RandomForestClassifier()
clf.fit(data_train, label_train)
# 데이터 예측하기 --- (※5)
predict = clf.predict(data_test)
# 결과 테스트하기 --- (※6)
ac_score = metrics.accuracy_score(label_test, predict)
cl_report = metrics.classification_report(label_test, predict)
print("정답률 =", ac_score)
print("리포트 =\n", cl_report)

결과

정답률 = 1.0
리포트 =
               precision    recall  f1-score   support

           e       1.00      1.00      1.00      1048 
           p       1.00      1.00      1.00       983 

    accuracy                           1.00      2031 
   macro avg       1.00      1.00      1.00      2031 
weighted avg       1.00      1.00      1.00      2031

 

clf = RandomForestClassifier()를 보면 알 수 있듯이 SVM.svc()가 아닌 랜덤 포레스트 분류기 함수를 사용하였습니다.

 

다른 점 보다도 주목할 점은 각각의 특징을 알파벳으로 구분지었는데 이를 숫자로 바꾸었습니다. 하지만 여기서 숫자는 어떠한 정도가 아닌 단순 분류 목적입니다.

 

사실 초보인 저로선 계속하여 반복 수련을 통해 익숙해져야 할 것 같습니다. 일단 개념을 정리하는 차원에서의 포스팅입니다~!

+ Recent posts