일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- scroll
- BOJ
- list
- 2020.05.17
- class
- Reversing
- struct
- 스택
- 컴퓨터구조
- Stack
- ios
- 백준 1920
- Swing
- UIView
- Constraint
- 알고리즘
- stl
- 2020.06.14
- 백준 10828
- vector
- 표준 템플릿 라이브러리
- 순차 컨테이너
- 모달인듯 모달 아닌 뷰
- Animation
- UIPanGestureRecognizer
- 2020.04.19
- 컴퓨터 구조
- Reverse Engineering
- SWiFT
- NavigationBar
- Today
- Total
야금야금
머신러닝의 이해와 지도학습을 이용한 분류 본문
파이썬으로 의사결정나무와 서포트 벡터 머신 알고리즘을 직접 구현해 보면서 머신러닝 알고리즘을 이용하는 방법에 대해 알아보자
1. 사이킷런을 이용한 의사결정나무 구현
의사결정나무 (Decision tree)
: 데이터 분포를 나누는 지도학습의 분류에 해당하는 모델이다.
용어 그대로 의사결정에 필요한 규칙을 나무 형태로 분류해 나가는 분석기법을 말한다.
연속적인 질문을 통해 예측 결과를 제공하는 예측모델로서 사람이 조건에 따라 행동하고 판단하는 것을 머신러닝에 응용한 것이다.
분석 과정이 직관적이고 이해하기 쉽다는 점 때문에 산업 전반에서 실무적으로 많이 사용된다.
지도학습인 의사결정나무에 대해 간단히 알아보았다. 이제 대표적인 머신러닝 오픈소스 라이브러리인 사이킷런(Scikit-Learn)을 이용해 의사결정나무를 실습해보자
사이킷런을 이용하면 특별히 알고리즘이나 지니 계수 같은 것을 이해하지 않고도 손쉽게 의사결정나무를 만들고 테스트할 수 있다.
* 사이킷런 : 파이썬으로 구현한 머신러닝을 위한 확장 라이브러리. 크게 지도학습, 비지도학습, 모델 선택 및 평가, 데이터 전처리로 나눌 수 있다.
사이킷런에서 의사결정나무 알고리즘은 tree 모듈의 DecisionTreeClassifier이라는 클래스로 구현되어 있다.
사이킷런은 머신러닝 알고리즘이 내장되어 있을 뿐만 아니라 의사결정나무의 구조를 DOT 파일 확장자로 출력하는 특수한 기능이 있다. 이 기능을 사용하여 나무 구조화를 시각화해보자
붓꽃 데이터 분류
사이킷런은 기본적으로 붓꽃(iris) 데이터를 포함하고 있다. 다음은 붓꽃 데이터를 이용해서 의사결정나무를 만드는 코드이다
from sklearn import datasets
from sklearn.tree import DecisionTreeClassifier
from sklearn import tree
def main () :
# load_iris()함수를 통한 iris 데이터 로드
dataset = datasets.load_iris ()
features = dataset.data
targets = dataset.target
# 꽃잎의 길이와 넓이 정보만 특징으로 사용
petal_features = features [:, 2 :]
# 의사결정 모델 클래스 생성
cIris = DecisionTreeClassifier (criterion = 'entropy' , max_depth = 3 )
#모델을 훈련
cIris.fit (petal_features, targets)
# DOT 언어의 형식으로 결정 나무의 형태를 출력
with open ( 'iris-dtree.dot' , mode = 'w' ) as f :
tree.export_graphviz (cIris, out_file = f)
if __name__ == '__main__' :
main ()
위의 코드를 tree.py이름으로 저장하고 콘솔창에서 다음 명령어로 실행한다.
$ python tree.py
명령어를 실행하면 export_graphviz 내보내기 도구를 사용해 iris-dtree.dot이라는 파일이 저장되는 것을 확인할 수 있다. 그래프비즈를 이용하여 이미지 데이터로 변환하면 다음과 같은 이미지 파일이 생성된다.
-
X [0] : 꽃잎 길이를 기준으로 양분하려면 기준치는 2.45가 적당하다.
-
samples : 최초 샘플 150개
-
X[1] : 꽃잎 폭을 기준으로 양분하려면 기준치는 1.75가 적당하다.
-
꽃잎 길이가 큰 것 중에서 꽃잎 폭이 큰 것의 샘플 수는 46개다.
유방암 데이터 분류
붓꽃 데이터 분류와 동일한 방법으로 진행한다.
다음은 유방암 데이터를 이용해서 의사결정나무를 만드는 코드이다.
from sklearn import datasets
from sklearn import tree
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_splitdef main():
# iris 데이터 로드 (1)
cancer = datasets.load_breast_cancer()
# 데이터를 훈련, 테스트 데이터로 나누기 (2)
x_train, x_test, y_train, y_test = train_test_split(cancer.data,
cancer.target,
stratify=cancer.target,
test_size=0.2,
random_state=42)
# 의사결정모델 클래스를 생성
cancer_model = DecisionTreeClassifier(criterion = 'entropy', max_depth = 3)
# 모델을 학습 (3)
cancer_model.fit(x_train,y_train)
print("훈련 점수: {:.3f}".format(cancer_model.score(x_train, y_train)))
print("테스트 점수: {:.3f}".format(cancer_model.score(x_test, y_test)))
# DOT 언어의 형식으로 결정 나무의 형태를 출력
with open ( 'cancer-dtree.dot' , mode = 'w' ) as f:
tree.export_graphviz (cancer_model, out_file = f,
feature_names=cancer.feature_names,
class_names=["cancer","not cancer"])
if __name__ == '__main__':
main()
위의 코드를 cancer_classify.py이름으로 저장하고 콘솔창에서 다음 명령어로 실행한다.
$ python cancer_classify.py
명령어를 실행하면 유방암 데이터를 분류하고 결과를 cancer-dtree.dot라는 이름의 파일로 저장한다. 그래프비즈를 이용하여 이미지 데이터로 변환하면 다음과 같은 이미지 파일이 생성된다.
-
종양에 대한 특성의 이름 중에서 worst radius가 가장 많은 영향을 주고 있다.
-
그다음은 worst concave points와 texture error로 분류되었음을 알 수 있다.
-
클래스를 통해 암인지 그렇지 않은지를 쉽게 판단할 수 있다.
지금까지 사이킷런에 포함된 붓꽃 데이터와 유방암 지표 데이터를 활용해 배운 의사결정나무알고리즘의 처리 흐름을 다시 정리하면 다음과 같다.
-
분류에 필요한 파이썬 모듈과 데이터 세트를 준비한다. 사이킷런에 포함되어 있는 데이터 세트(붓꽃과 유방암)을 사용한다
-
분석할 데이터 세트 특성을 확인한다. 각 데이터의 특징과 레이블을 확인한다. 또한 데이터의 내용을 확인한 후 트레이닝 및 검증용 데이터를 분할한다
-
의사결정나무의 변수를 조정한다. 변수를 조정함으로써 모델링의 정확도를 높일 수 있다.
-
모델의 내용을 시각화한다. 시각화 과정은 의사결정나무 분석 결과를 이해하기에 가장 좋은 방법이므로 반드시 진행해야 한다. 시각화된 내용을 보고 특징량 중 어떤 특징량이 얼마나 데이터 분할에 기여했는지를 확인한다.
의사결정나무는 붓꽃과 유방암 사례처럼 분류기로 사용할 수도 있지만, 다른 머신러닝 알고리즘을 활용하기 전에 전처리 용도로, 사전에 중요한 특성이 무엇인지, 어느 특성이 결과에 많은 영향을 끼치는지를 찾는 경우에도 유용하게 쓰일 수 있다.
2. 서포트 벡터 머신 알고리즘
서포트 벡터 머신 : 데이터 분포를 나누는 지도학습의 분류
지금까지도 보편적으로 사용하는 분류를 위한 머신러닝 모델이며 지도학습 모델로서 라벨이 달린 이진 분류 문제에 주로 사용된다.
서포트 벡터 머신 알고리즘에서는 각 데이터 항목을 다차원의 벡터 공간에 점으로 표시한다. 예를 들어 두 개의 속성만 있다면 2차원 모델이 된다. 2차원 공간에 두 개의 그룹이 존재한다고 가정하고 본 부분을 살펴보도록 하자
2차원 공간의 두 개의 그룹이 아래와 같이 존재할 때 두 그룹을 매우 잘 구분하는 직선을 찾는 것이 서포트 벡터 머신의 핵심이다. 서포트 벡터 머신은 데이터를 선형 또는 비선형으로 분리하는 최적의 경계를 찾는 알고리즘이다.
그렇다면 위의 그림에서 가장 적절한 경계는 어떤 것일까?
어느 한 그룹에 치우치지 않고 두 클래스(분류) 사이의 거리가 가장 먼 F그룹이 가장 적절하다.
마진이란 결정 경계와 서포트 벡터 사이의 거리를 의미하며 직선식에 가장 멀리 떨어진 거리를 최대 마진이라고 한다.
최적의 결정 경계는 마진을 최대화한다
서포트 벡터 머신을 이용해 당뇨병 분류하기
우선 데이터 처리 패키지인 판다스(Pandas)를 설치하고 외부에서 피마(Pima) 인디언의 당뇨병 데이터 세트를 가져와 이용하도록 하자
코드는 다음과 같다
from sklearn import datasets
from sklearn import tree
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
# 표준화 (정규화 (모든 값을 0-1에 맞게 변환)
# 또는 표준화(평균 0, 분산 1이 되도록 변환)가 필요하다.)
from sklearn.preprocessing import StandardScaler
# 데이터 셋 로드 (1)
pi_diabetes = pd.read_csv('pima-indians diabetes.csv', header = None)
x = pi_diabetes.iloc[:, :8]
y = pi_diabetes.iloc[:, 8:].values.flatten() # 1차원으로 전개 (2)
print('x shape : {}, x shape : {}'.format(x.shape, y.shape))
# 학습 데이터와 테스트 데이터의 분리 (3)
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state = 0)
# 정규화를 위한 모듈 사용 (4)
std_scl = StandardScaler()
std_scl.fit(x_train)
x_train = std_scl.transform(x_train)
x_test = std_scl.transform(x_test)
# 학습 및 테스트 (5)
svc = SVC()
svc.fit(x_train, y_train)
print('훈련 점수 : {: .3f}'.format(svc.score (x_train, y_train)))
print('테스트 점수 : {: .3f}'.format(svc.score (x_test, y_test)))
위의 파일을 pi_diabetes.py로 저장하고 콘솔창에서 아래와 같은 명령어를 실행하면 다음과 같은 결과가 출력된다.
총 768개의 데이터를 가져오고 학습한 결과를 볼 수 있다. 훈련 점수는 82, 테스트 점수는 77.
다른 머신러닝 기법에 비해 서포트 벡터 머신은 학습 속도가 비교적 빠르다.
피마 인디언 당뇨병 데이터 집합은 연령, 성별, BMI를 포함한 8가지 특징으로 이루어져 있고, 목표 변수는 당뇨병 질환의 유무이다. 이 데이터 세트에 서포트 벡터 머신을 사용하여 피마 인디언이 당뇨병에 걸렸는지 여부를 예측해 보았다. 벡터머신 알고리즘 및 매개변수 최적화를 사용하여 최종적으로 77점의 점수를 얻었다. 복잡한 알고리즘을 사용하지 않고도 당뇨병 발병 여부를 예측할 수 있었다.
서포트 벡터 머신을 이용해 버섯 종류 분류하기
위와 같은 실습을 하나 더 진행해보도록 하자. 캘리포니아대학 어바인 캠퍼스 학습 저장소에 공개되어 있는 독버섯 데이터를 가지고 독버섯 여부를 분류해본다.
훈련 데이터의 한 행은 각각 하나의 버섯을 나타내며 맨 왼쪽 첫 번째 문자가 독성의 유무(p : 유, e : 무)를 나타내고 이후의 문자를 통해 모양과 색깔 등의 특징을 알 수 있다. 따라서 맨 왼쪽 첫 번째 문자를 독버섯의 유무 레이블로 정하고 그 이후의 데이터를 설명 변수로 활용한다.
코드는 다음과 같다.
# pandas 모듈 추가
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
# 데이터 셋 로드 (1)
mushroom = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/mushroom/agaricus-lepiota.data',
header=None)
# 문자를 수치로 치환 (2)
x = []
y = []
for row_index, row in mushroom.iterrows():
y.append(row[0])
row_X = []
for v in row[1:]:
row_X.append(ord(v)) # (3)
x.append(row_X)
# 학습 데이터와 테스트 데이터 나누기 (4)
x_train, x_test, y_train, y_test = train_test_split(x, y)
# 학습 및 테스트 (5)
svc = SVC()
svc.fit(x_train, y_train)
print('훈련 점수 : {:.3f}'.format(svc.score(x_train, y_train)))
print('테스트 점수 : {:.3f}'.format(svc.score(x_test, y_test)))
위 파일을 mushroom.py로 저장하고 아래와 같은 명령어를 실행하면 다음과 같은 결과가 출력된다
버섯 훈련 데이터 집합은 갓 모양, 갓 표면, 서식지 등을 포함한 22가지 특징으로 이루어져 있고, 목표변수는 독성의 유무다. 이 데이터를 가지고 서포트 벡터 머신을 수행한 결과 99%의 점수를 얻었다.
어려운 알고리즘이라고 해서 무조건 좋은 것이 아니라 적합한 상황에 맞는 알고리즘을 사용하는 것이 더 중요하다. 데이터의 특징이나 해결하고자 하는 문제에 따라 적합한 알고리즘을 선택하기 위해 각 알고리즘의 특징과 활용을 이해할 필요가 있다.
참고 도서
마창수,최재철, 『실무가 훤히 보이는 머신러닝&딥러닝』, 책만
'SWING > 머신러닝' 카테고리의 다른 글
문장의 유사도를 N-gram으로 분석하기 (0) | 2020.08.08 |
---|---|
MLP로 텍스트 분류하기 (0) | 2020.08.02 |
베이즈 정리로 텍스트 분류하기 (0) | 2020.07.25 |
한국어 분석(형태소 분석) (0) | 2020.07.25 |
인공지능 서비스와 기술의 이해 (0) | 2020.07.10 |