앙상블의 단어 뜻은 조화와 통일이다. 이 의미를 머신러닝에 대입한다면?
👉 하나의 모델 말고, 여러 개의 모델을 조화롭게 학습시켜 예측 결과들을 이용하면 더 정확한 예측 값을 구할 수 있을 것이란 아이디어다.
대표적인 앙상블 학습법은 배깅과 부스팅이 있다. 이 개념을 알기 위해선 먼저 의사 결정 나무(Decision Tree)와 부트스트랩(Bootstrap)을 알면 좋다.
기존의 데이터 셋으로부터 랜덤 샘플링을 통해 학습 데이터를 늘리는 방법이다. 이것은 데이터의 양을 늘리고, 분포를 고르게 만들 수 있다는 효과가 있다. 즉, 학습 데이터 갯수를 늘려서 분류 모델의 성능을 향상 시키기 위한 목적으로 활용된다.
샘플을 여러 번 뽑아서 각 모델을 학습시키고 결과물을 집계(결합)하는 방법이다.
각 샘플의 예측치를 집계하는 방법은 결과 변수가 연속형이면 평균, 범주형이면 다중 투표를 사용한다.
가중치를 활용해 약 분류기를 강 분류기로 만드는 방법이다.
잘못 분류된 것에 대해서는 높은 가중치를 부여하고, 잘 분류 즉, 정답인 것에 대해서는 낮은 가중치를 줘서 오답을 정답으로 맞추기 위해 오답에 더 집중할 수 있게 해준다.
= 여러 개의 모델 간 상호작용이 일어난다. 처음 모델이 예측하면 예측 결과에 따라 데이터에 가중치가 부여되고, 부여된 가중치가 다음 모델에 영향을 준다.
👉👉 부스팅은 배깅 보다 성능이 적다.(오류가 적다) 하지만, 배깅에 비해 속도가 느리고, 과적합 될 가능성이 있다.
랜던포레스트는 이름에서 알 수 있듯이 숲이다. 즉, 많은 의사결정나무가 모여서 생성되는 개념이라고 할 수 있다.
더 쉽게 말하면 결정 트리를 여러 개 만들어 분류 결과를 다수결로 결정하는 방법이다. 다수의 간단한 분류기를 하나의 분류기에 몰아서 학습시키는 앙상블 학습이라고 할 수 있다.
👉 랜덤포레스트의 각 결정 트리는 랜덤으로 정해진 소수의 독립변수만 사용해 데이터가 속하는 클래스를 결정한다. 이후 다수의 단순 결정 트리에서 출력된 클래스 중 가장 많았던 클래스를 결과로 출력하게 되는 것이다.
『파이썬으로 배우는 딥러닝 교과서』,한빛미디어,(2020), 박광수
을 참고하여 학습 했습니다.
import requests #http 요청 처리를 위해 사용하는 모듈
import zipfile #압축 파일 쓰기
from io import StringIO #strinIO는 실제 파일인 것처럼 읽고 쓰기 가능(문자열을 파일처럼 다루는!)
import io
import pandas as pd
from sklearn.moel_selection import train_test_split
from sklearn import preprocessing
mush_data = "https://archive.ics.uci.edu/ml/machine-learning-databases/mushroom/agaricus-lepiota.data"
# 해당 데이터는 위의 링크를 통해 다운로드 받을 수 있음!
s = requests.get(mush_data).content
mush_data = pd.read_csv(io.StringIO(s.decode("utf-8")),header = None) #header = None은 컬럼 이름이 없다는 뜻으로 만약 1번 째 행이 컬럼 이름이면 header = 0으로 지정해주면 됨
그래서 데이터를 확인해주면
결과가 이렇게 뭐가뭔지 모르게 나온다. url로 다시 들어가서 데이터 설명을 읽어보면
- Number of Attributes: 22 (all nominally valued)
- Attribute Information: (classes: edible=e, poisonous=p)
1. cap-shape: bell=b,conical=c,convex=x,flat=f,
knobbed=k,sunken=s
2. cap-surface: fibrous=f,grooves=g,scaly=y,smooth=s
3. cap-color: brown=n,buff=b,cinnamon=c,gray=g,green=r,
pink=p,purple=u,red=e,white=w,yellow=y
4. bruises?: bruises=t,no=f
5. odor: almond=a,anise=l,creosote=c,fishy=y,foul=f,
musty=m,none=n,pungent=p,spicy=s
6. gill-attachment: attached=a,descending=d,free=f,notched=n
7. gill-spacing: close=c,crowded=w,distant=d
8. gill-size: broad=b,narrow=n
9. 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
10. stalk-shape: enlarging=e,tapering=t
11. stalk-root: bulbous=b,club=c,cup=u,equal=e,
rhizomorphs=z,rooted=r,missing=?
12. stalk-surface-above-ring: fibrous=f,scaly=y,silky=k,smooth=s
13. stalk-surface-below-ring: fibrous=f,scaly=y,silky=k,smooth=s
14. stalk-color-above-ring: brown=n,buff=b,cinnamon=c,gray=g,orange=o,
pink=p,red=e,white=w,yellow=y
15. stalk-color-below-ring: brown=n,buff=b,cinnamon=c,gray=g,orange=o,
pink=p,red=e,white=w,yellow=y
16. veil-type: partial=p,universal=u
17. veil-color: brown=n,orange=o,white=w,yellow=y
18. ring-number: none=n,one=o,two=t
19. ring-type: cobwebby=c,evanescent=e,flaring=f,large=l,
none=n,pendant=p,sheathing=s,zone=z
20. spore-print-color: black=k,brown=n,buff=b,chocolate=h,green=r,
orange=o,purple=u,white=w,yellow=y
21. population: abundant=a,clustered=c,numerous=n,
scattered=s,several=v,solitary=y
22. habitat: grasses=g,leaves=l,meadows=m,paths=p,
urban=u,waste=w,woods=d
이렇게 22개의 속성이 있고 각 데이터 설명을 간단히 볼 수 있다.
이 코드에서는 데이터를 쉽게 취급하기 위해 대응되는 항목으로 바꿔주는 코드가 나온다.
mush_data.columns = ["classes", "cap-shape","cap-surface",
"cap-color","bruises","odor","gill-attachment","gill-spacing",
"gill-size","gill-color","stalk-shape","stalk-root",
"stalk-surface-above-ring","stalk-surface-below-ring",
"stalk-color-above-ring","stalk-color-below-ring",
"veil-type","veil-color","ring-number","ring-type",
"spore-print-color","population","habitat"]
머심러닝에 적합한 데이터 형태로 가공하기 위해 데이터를 수치형 데이터로 변환해준다. 그런데 여기서 수치형 데이터로만 변환 하게 되면 서로 간의 관계성이 생기게 된다.
ex) 월=1, 화=2, 수=3 1+2=3 과 같은 관계성이 존재하게 되는데, 세 요일 간에는 실제로 관계성이 없다. 그렇기 때문에 서로 무관한 수인 더미로 만든 가변수로 변환해 이러한 문제를 막아준다.
mush_data_dummy = pd.get_dummies(
mush_data[["gill_color","gill_attachment","odor","cap_color"]]
)
mush_data_dummy["flg"] = mush_data["classes"].map(lambda x:1 if x=="p" else 0)
#map은 리스트의 요소를 지정된 함수로 처리해주는 함수
#if x=="p"면 x=1이고, 아니면 0
x = mush_data_dummy.drop('flg',axis=1)
y = mush_data_dummy['flg']
#axis=0 행 axis = 1열
x_train, x_test, y_train, y_test = train_test_split(x,y,random_state=100)
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier()
model.fit(x_train,y_train)
print(model.score(x_test,y_test))