scikit-learn이란?
- scikit-learn은 2007년 구글 썸머 코드에서 처음 구현됐으며 현재 파이썬으로 구현된 가장 유명한 기계 학습 오픈 소스 라이브러리
- 아나콘다에서 기본적으로 제공하는 라이브러리 중 하나
- 장점 : 라이브러리 외적으로는 scikit 스택을 사용하고 있기 때문에 다른 라이브러리와의 호환성이 좋다. 내적으로는 통일된 인터페이스를 가지고 있기 때문에 매우 간단하게 여러 기법을 적용할 수 있어 쉽고 빠르게 최상의 결과를 얻을 수 있다.
- 라이브러리의 구성은 크게 지도 학습, 비지도 학습, 모델 선택 및 평가, 데이터 변환으로 나눌 수 있다
- scikit-learn 사용자 가이드 : http://scikit-learn.org/stable/user_guide.html
- 지도 학습에는 서포트 벡터 머신, 나이브 베이즈(Naïve Bayes), 결정 트리(Decision Tree)등이 있으며 비지도 학습에는 군집화, 이상치 검출 등이 있다.
- 모델 선택 및 평가에는 교차 검증(cross-validation), 파이프라인(pipeline)등 있으며 마지막으로 데이터 변환에는 속성 추출(Feature Extraction), 전처리(Preprocessing)등이 있다.
- 클래스별로 보자면, 각 기법들이 공통으로 가지고 있어야 하는 기본 BaseEstimator가 있으며 기법의 공통적인 부분을 모은 ClassifierMixin, RegressorMixin, ClusterMixin들이 있어 기법들은 각각의 기법의 클래스를 상속 받아 구현할 수 있다.
- 대부분의 클래스는 입력 데이터를 적합화하는 fit 메소드와 새로운 데이터를 예측하는 predict 메소드를 가지고 있다.
참고 자료 : https://github.com/brenden17/blog/blob/master/post/ms.scikit-learn.v.md
1. kNN : k-Nearest Neighbors
- 알려진 범주로 알려지지 않은 범주 분류 (해석 용이)
- 기존의 범주가 존재해야 함
- 결측치(NA) 및 이상치 전처리 중요
- 많은 특징을 갖는 데이터 셋은 부적합
- 유클리드 거리 계산식 (Euclidean distance) 이용 : 가장 유사한 범주를 가장 가까운 거리를 통해 선택
- 적용 분야 : 개인별 영화 추천, 이미지/비디오에서 얼굴 또는 글자 인식, 유전자 데이터 패턴 식별
2. NB : Naive Bayes
- 통계적 분류기
- 주어진 데이터가 특정 클래스에 속하는지를 확률을 통해서 예측 ( 조건부 확률 이용 - P(B|A) )
- 베이즈 확률 정리(Bayes' theorem)을 적용한 기계학습 방법 (사전/사후 확률 사이의 관계를 나타낸 이론)
- 특정 영역에서는 DT나 kNN 분류기보다 성능이 우수
- 텍스트 데이터처럼 희소한 고차원인 경우 높은 정확도와 속도 제공
- 적용 분야 : 스팸 메일 분류, 문서(주제) 분류, 비 유무 예측, 컴퓨터 네트워크 상 침입자 분류(악성코드 유무)
3. SVM : Support Vector Machine
- SVM 알고리즘 : 가상의 직선을 중심으로 거리를 계산하여 최대의 직사각형 형태(Margin)로 영역을 넓힌다.
즉 Margin을 최대로 만드는 알고리즘!
- 이진분류 : 두 범주를 직선으로 분류 / 선형분리 - 2개의 집합을 직선으로 분리
- kNN과 선형회귀 모델링 기법이 적용 => 분류와 수치 예측 가능
- 비선형 분류를 위해서 데이터의 차원을 고차원으로 변경하여 직선으로 분리 (커널 트릭)
- 커널 트릭(Kernel Trick) : 비선형(Non Linear)관계를 선형으로 변환하는 역할
- 커털 트릭에 사용되는 '커널 함수' 종류 : linear(Gaussian), polynomial radial, sigmoid
다음의 그림들은 커널 트릭의 개념을 설명한다.
- 다양한 데이터 셋에서 잘 동작하는 강력한 모델 (저차원, 고차원 데이터 모두에서 동작 잘됨)
- 데이터의 특징이 적어도 복잡한 결정 경계 생성, 모든 특징과 스케일이 비슷한 경우에 유리함
- 단, 데이터 전처리와 매개변수 설정에 주의 & 샘플(관측치)이 많은 경우 불리함 (100,000개 이상)
- 모델 분석이 어려움(블랙박스화 - 예측과정 이해가 어려움)
- 2000년대 초반에 많이 사용되는 분류 알고리즘
- 적용 분야 : 바이오인포매틱스의 마이크로 유전자 데이터 분류, 인간의 얼굴/ 문자/ 숫자 인식
- 이미지 데이터 패턴 인식에 적합
< 실습 내용 >
1. kNN
2. NB
3. SVM
4. npy파일 저장 및 불러오기
5. 스팸 메일 분류
1. kNN
import numpy as np # 다차원배열, 선형대수 연산
import matplotlib.pyplot as plt
# 1. 알려진 두 집단 x,y 산점도 시각화
plt.scatter(1.2, 1.1) # A 집단
plt.scatter(1.0, 1.0)
plt.scatter(1.8, 0.8) # B 집단
plt.scatter(2, 0.9)
plt.scatter(1.6, 0.85, color='r') # 분류대상
plt.show()
# 블럭실행
# 2. DATA 생성과 함수 정의
p1 = [1.2, 1.1] # A 집단
p2 = [1.0, 1.0]
p3 = [1.8, 0.8] # B 집단
p4 = [2, 0.9]
category = ['A','A','B','B'] # 알려진 집단 분류범주(Y변수)
p5 = [1.6, 0.85] # 분류대상
p1 - p2 # 오류
# list로는 연산 불가능 -> 선형대수연산이 가능한 numpy의 array로 변경
# data 생성 함수 정의
def data_set():
# 선형대수 연산 : numpy형 변환
know_group = np.array([p1, p2, p3, p4]) # 알려진 집단
not_know_group = np.array(p5) # 알려지지 않은 집단
class_category = np.array(category) # 정답(분류범주)
return know_group, not_know_group, class_category
# 함수 호출 : dataset 생성
know, not_know, cate = data_set()
know
'''
array([[1.2, 1.1],
[1. , 1. ],
[1.8, 0.8],
[2. , 0.9]])
'''
not_know # 분류대상
# array([1.6 , 0.85])
# 유클리드 거리계산식 : 차(-) -> 제곱 -> 합 -> 제곱근
diff = know - not_know # 차(-)
sq_diff = diff**2 # 제곱
sum_sq_diff = sq_diff.sum(axis = 1) # 행 단위 합계
distance = np.sqrt(sum_sq_diff) # 제곱근
distance
# [0.47169906, 0.61846584, 0.20615528, 0.40311289]
# 값이 가장 작은 것이 가장 가까운 거리를 의미
2. NB
from sklearn.datasets import load_iris # dataset
from sklearn.naive_bayes import GaussianNB # model 생성
from sklearn.model_selection import train_test_split # train/test set
from sklearn.metrics import accuracy_score, confusion_matrix # model 평가
# y변수 : 다항분류
# 1. data loading & 변수 생성
X, y = load_iris(return_X_y = True)
# 2. train/test split
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 123)
# 랜덤하게 샘플링하되 특정 번호를 지정함으로써 반복해서 시도하더라도 항상 같도록!
x_train.shape # (105, 4)
y_train.shape # (105,)
# 3. model
model = GaussianNB()
model.fit(X=x_train, y=y_train)
# 4. model 평가
y_pred = model.predict(x_test) # 예측치
y_true = y_test # 정답
# 분류정확도 - accuracy_score 함수 사용해서 구하기
acc = accuracy_score(y_true, y_pred)
acc # 0.9555555555555556
con_mat = confusion_matrix(y_true, y_pred)
con_mat
'''
array([[18, 0, 0],
[ 0, 10, 0],
[ 0, 2, 15]], dtype=int64)
'''
y_true[:10] # [1, 2, 2, 1, 0, 2, 1, 0, 0, 1]
y_pred[:10] # [1, 2, 2, 1, 0, 2, 1, 0, 0, 1]
type(con_mat) # numpy.ndarray
con_mat.shape # (3, 3)
# 분류정확도 - 식을 통해 구하기
acc = (con_mat[0,0] + con_mat[1,1] + con_mat[2,2]) / len(y_true)
acc # 0.9555555555555556
3. SVM
from sklearn.datasets import load_iris # dataset
from sklearn.svm import SVC # model 생성
from sklearn.model_selection import train_test_split # train/test set
from sklearn.metrics import accuracy_score, confusion_matrix # model 평가
# y변수 : 다항분류
# 1. data loading & 변수 생성
X, y = load_iris(return_X_y = True)
# 2. train/test split
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 123)
# 랜덤하게 샘플링하되 특정 번호를 지정함으로써 반복해서 시도하더라도 항상 같도록!
x_train.shape # (105, 4)
y_train.shape # (105,)
# 3. model
help(SVC)
model = SVC() # kernel = 'rbf' : default
# 데이터의 특징 때문에 분류정확도가 낮게 나오면 다른 커널 함수를 인수로 지정할 수 있음
# 'linear', 'poly', 'rbf', 'sigmoid' 등
model.fit(X=x_train, y=y_train)
# 4. model 평가
y_pred = model.predict(x_test) # 예측치
y_true = y_test # 정답
# 분류정확도 - accuracy_score 함수 사용해서 구하기
acc = accuracy_score(y_true, y_pred)
acc # 0.9777777777777777
con_mat = confusion_matrix(y_true, y_pred)
con_mat
'''
array([[18, 0, 0],
[ 0, 10, 0],
[ 0, 1, 16]], dtype=int64)
'''
y_true[:10] # [1, 2, 2, 1, 0, 2, 1, 0, 0, 1]
y_pred[:10] # [1, 2, 2, 1, 0, 1, 1, 0, 0, 1]
type(con_mat) # numpy.ndarray
con_mat.shape # (3, 3)
# 분류정확도 - 식을 통해 구하기
acc = (con_mat[0,0] + con_mat[1,1] + con_mat[2,2]) / len(y_true)
acc # 0.9777777777777777
## iris 데이터의 경우, NB모델보다 SVM모델을 사용할 때 분류정확도가 더 올라간 것을 확인할 수 있음
4. npy파일 저장 및 불러오기
# numpy dataset file save & load
import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
# 1. dataset load
X, y= load_iris(return_X_y=True)
X.shape # (150, 4)
type(X) # numpy.ndarray (numpy의 array 형태)
# 2. train/test
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
type(x_train) # numpy.ndarray
x_train.shape # (105, 4)
# 3. numpy dataset file save
iris_train_test = (x_train, x_test, y_train, y_test) # 하나의 변수에 데이터 담기!
np.save("../data/iris_train_test.npy", iris_train_test) # 파일이름 원하는대로 지정
# 'allow_pickle = True'가 default
# 4. numpy dataset file load
x_train, x_test, y_train, y_test = np.load("../data/iris_train_test.npy", allow_pickle=True)
# 'allow_pickle=True' 로 저장했으면 가져올때도 같은 값으로 지정해서 불러와야함!
# True로 저장하고 False로 불러오려고 하면 오류발생
type(x_train) # numpy.ndarray
x_train.shape # (105, 4)
5. 스팸 메일 분류
import numpy as np # np.load()
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score, confusion_matrix
# 1. dataset loading
x_train, x_test, y_train, y_test = np.load(file="../data/spam_train_test.npy", allow_pickle=True)
x_train.shape # (4459, 4000)
x_test.shape # (1115, 4000)
type(y_train) # list
type(y_test) # list
# list -> numpy
y_train = np.array(y_train)
y_test = np.array(y_test)
y_train.shape # (4459,)
y_test.shape # (1115,)
y_train[:10] # [0, 0, 0, 1, 0, 1, 0, 0, 0, 0] => 1은 스팸메일
# 2. GaussianNB vs SVM
model = GaussianNB()
model.fit(X=x_train, y=y_train)
model2 = SVC(kernel='linear')
model2.fit(X=x_train, y=y_train)
# 3. model 평가
# 1) 예측치
y_pred = model.predict(X = x_test)
y_pred2 = model2.predict(X = x_test)
y_true = y_test
# 2) 분류정확도
acc1 = accuracy_score(y_true, y_pred)
acc2 = accuracy_score(y_true, y_pred2)
print('accuracy1 (NB) =', acc1)
print('accuracy2 (SVM) =', acc2)
# accuracy1 (NB) = 0.8905829596412556
# accuracy2 (SVM) = 0.979372197309417
## SVM의 분류정확도가 더 높음
con_mat1 = confusion_matrix(y_true, y_pred)
con_mat1
'''
array([[853, 102],
[ 20, 140]], dtype=int64)
'''
con_mat2 = confusion_matrix(y_true, y_pred2)
con_mat2
'''
array([[952, 3],
[ 20, 140]], dtype=int64)
'''
-------------------------------------------------- example --------------------------------------------------
'Python 과 머신러닝 > III. 머신러닝 모델' 카테고리의 다른 글
[Python 머신러닝] 7장. 앙상블 (Ensemble) - (2) RandomForest (0) | 2019.10.25 |
---|---|
[Python 머신러닝] 7장. 앙상블 (Ensemble) - (1) 앙상블의 개념 (0) | 2019.10.25 |
[Python 머신러닝] 5장. 회귀분석 - (2) 로지스틱 회귀분석 (0) | 2019.10.24 |
[Python 머신러닝] 5장. 회귀분석 - (1) 선형 회귀분석 (1) | 2019.10.23 |
[Python 머신러닝] 지도학습과 비지도학습 (0) | 2019.10.23 |
댓글