아이펠 8일차

사이킷런으로 구현해 보는 머신러닝

학습목표

  • 머신러닝의 다양한 알고리즘을 소개합니다
  • 사이킷런 라이브러리 사용법을 익힙니다
  • 사이킷런에서 데이터를 표현하는 방법에 대해 이해하고 훈련용 데이터셋과 테스트용 데이터셋으로 데이터를 나누는 방법을 이해합니다

머신러닝 알고리즘 종류

지도학습

비지도학습

강화학습

알고리즘 선택시 고려사항

정확성, 학습 시간, 사용 편의성을 고려해야 합니다

데이터 세트가 제공됐을 때 가장 먼저 고려해야 할 것은 ‘어떤 결과가 나올 것 인지에 상관없이 어떻게 결과를 얻을 것인가’ 입니다

머신러닝 알고리즘

보통 지도학습, 비지도학습, 강화학습 크게 3가지로 구분할 수 있다

지도학습과 비지도학습

라벨(정답)의 존재 유무의 따라 머신러닝을 지도학습, 비지도학습으로 구분

정답 유무, 데이터의 종류, 특성, 문제 정의에 따라 머신러닝 알고리즘은 굉장히 복합적으로 사용

강화학습 역시 머신러닝에 있어 큰 분야이지만 내용이 방대하여 이번 강의에서 직접 다루지는 않을 예정입니다

사이킷런에서 가이드 하는 머신러닝 알고리즘

사이킷런에서 알고리즘의 Task는 몇 가지이며 각각 무엇인가요?

Classification(분류), Clustering(클러스터링), Dimensionality reduction(차원축소), Regression(회귀)

사이킷런에서는 알고리즘을 크게 어떤 기준에 따라 나누었나요?

데이터 수량, 라벨의 유뮤(정답의 유무), 데이터의 종류(수치형 데이터(quantity), 범주형 데이터(category) 등)

사이킷런에서 소개하는 Classification용 알고리즘은 몇 개이며 그 종류에는 무엇이 있나요?

LinerSVC, NaiveBayes, KNeighborsClassifier, SVC, EnsembleClassifiers, SGD Classifier, Kernel approximation 7개

사이킷런에서 소개하는 Regression용 알고리즘은 몇 개이며 그 종류에는 무엇이 있나요?

Lasso, ElasticNet, RidgeRegression, SVR(kernel='linear'), SVR(kernel='rbf'),
EnsembleRegressors, SGD Regressors 7개

Ensemble 기법은 어느 Task 카테고리에 사용되었나요?

Classsification, Regression

SGD 기법은 어느 Task 카테고리에 사용되었나요?

Classsification, Regression

Scikit-Learn에서 훈련 데이터와 테스트 데이터를 나누는 기능을 제공하는 함수의 이름은 무엇인가요?

sklearn.model_selection 안의 train_test_split

Scikit-Learn에서 ETL(Extract Transform Load) 기능을 수행하는 함수가 무엇인가요?

transformer()

Scikit-Learn에서 모델(Model)로 표현되는 클래스가 무엇인지 찾아보세요.

Estimator

Estimator 클래스의 메소드에는 어떤 것이 있었나요?

fit(), predict()

Estimator와 transformer() 2가지 기능을 수행하는 scikit-learn의 API는 무엇인가요?

Pipeline 혹은 meta-estimator

사이킷런의 주요 모듈 (1) 데이터 표현법

사이킷런의 알고리즘은 파이썬 클래스로 구현되어있다

데이터셋은 NumPy의 ndarray, Pandas의 DataFrame, SciPy의 Sparse Matrix를 이용해 나타낼 수 있다

데이터 표현법

사이킷런에서는 데이터 표현 방식을 보통 2가지로 나타낸다

특성 행렬(Feature Matrix)과 타겟 벡터(Target Vector)

특성 행렬(Feature Matrix)

입력 데이터를 의미합니다

특성(feature): 데이터에서 수치 값, 이산 값, 불리언 값으로 표현되는 개별 관측치를 의미합니다.

특성 행렬에서는 열에 해당하는 값입니다.

표본(sample): 각 입력 데이터, 특성 행렬에서는 행에 해당하는 값입니다.

n_samples : 행의 개수(표본의 개수)

n_features : 열의 개수(특성의 개수)

x : 특성 행렬은 보통 변수명을 x로 표기합니다

[n_samples, n_features]은 [행, 열] 형태의 2차원 배열 구조를 사용하며 이는 NumPy의 ndaaray, Pandas의 DataFrame, SciPy의 Sparse Matrix를 사용하여 나타낼 수 있습니다.

타겟 벡터 (Target Vector)

입력 데이터의 라벨(정답) 을 의미합니다.

목표(Target): 라벨, 타겟값, 목표값이라고도 부르며 특성 행렬(Feature Matrix)로부터 예측하고자 하는 것을 말합니다.

n_samples : 벡터의 길이(라벨의 개수)

타겟 벡터에서 n_features는 없다

y : 타켓 벡터는 보통 변수명을 y로 표기합니다

타겟 벡터는 보통 1차원 벡터로 나타내며, 이는 NumPy의 ndarray, Pandas의 Series를 사용하여 나타낼 수 있습니다.(단, 타겟 벡터는 경우에 따라 1차원으로 나타내지 않을 수도 있습니다. 이 노드에서 사용되는 예제는 모두 1차원 벡터입니다.)

특성 행렬 X의 n_samples와 타겟 벡터 y의 n_samples는 동일해야 합니다.

사이킷런의 주요 모듈(2) 회귀 모델 실습

# 랜덤 데이터?
import numpy as np
import matplotlib.pyplot as plt
r = np.random.RandomState(10)
x = 10 * r.rand(100)
y = 2 * x - 3 * r.rand(100)
plt.scatter(x,y)

x.shape # (100,)
y.shape # (100,)
# x와 y의 모양은 (100,)으로 1차원 벡터

from sklearn.linear_model import LinearRegression # 모델은 sklearn.liner_model 여기 있음
model = LinearRegression() # 모델 이름 지정

model.fit(x, y) # fit()은 훈련시키는 메서드 fit(특성행렬,타겟벡터) 넣어줌

# 새로운 데이터 넣고 예측하기
x_new = np.linspace(-1, 11, 100) # .linspace() 사용해서 새로운 데이터 생성
X_new = x_new.reshape(100,1)
y_new = model.predict(X_new) # 예측은 predict()로 인자는 행렬로 넣어야한다

# reshape() 함수에서 나머지 숫자를 -1로 넣으면 자동으로 남은 숫자를 계산해 줍니다. 
# 즉, x_new의 인자의 개수가 100개이므로, (100, 1)의 형태나 (2, 50)의 형태 등으로 변환
# (2, -1)을 인자로 넣으면 (2, 50)의 형태로 자동으로 변환해 줍니다
X_ = x_new.reshape(-1,1) # -1개로 모양을 다시만들면 남은숫자인 100이 들어가고 1개로 구성
X_.shape
# (100, 1)
X_ = x_new.reshape(2,-1) # 2개로 모양을 다시 만드니까 나머지가 50이다
X_.shape
# (2, 50)

# 뒤에 코드 해보는거 하긴 했는데 맞는지 알수없음

사이킷런의 주요 모듈 (3) datasets 모듈

sklearn.datasets 모듈은 크게 dataset loaders와 dataset fetchers로 나뉘며, 각가 Toy dataset과 Real World dataset을 제공하고 있습니다. 우리는 Toy dataset을 다뤄볼 예정

# Toy dataset에 있는 예시 중 하나인 dataset.load_wine()
# datasets.load_wine(): 분류 문제, 와인 분류

# **datasets.load_wine() 뜯어보기=로드하기**
from sklearn.datasets import load_wine # 불러오기
data = load_wine() # data라는 변수에 할당
type(data) # 타입(자료형) 알아보기
# sklearn.utils.Bunch 이라는 데이터 타입으로 나옴 
# Bunch는 파이썬의 딕셔너리와 유사한 형태의 데이터 타입
print(data) # print(data) 해서 출력해보면 데이터들이 {}에 담겨있고 : 으로 구분되어있음

data.keys()
# dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names'])
# 데이터의 각 키값이 의미하는 것이 무엇인지 하나씩 알아보자
# **1.data**
data.data # data는 특성 행렬 : 특성 행렬은 2차원이다
# 행에는 데이터의 개수(n_samples)가 열에는 특성의 개수(n_features)가 들어 있습니다
data.data.shape # 데이터 모양 확인하기
# (178, 13) # 178행 13열 # 특성 행렬 데이터 수
data.data.ndim # 차원 확인하기
# 2 # 2차원이라는 말이겠지
# **2.target** : target은 타켓 벡터이고 1차원이다
data.target # 타켓 벡터 길이는 특성 행렬의 길이와 같아야 한다
data.target.shape # 타겟 벡터 모양 확인
# (178,) # 특성 행렬 데이터수와 일치
# **3.feature_name** # data 키에 접근해서 확인해 본 결과 특성이 13개임을 확인
data.feature_names # feature_names란 키에 특성들의 이름이 저장
len(data.feature_names) # feature_names 개수 확인
# **4.target_names** # 분류하고자 하는 대상
data.target_names
# array(['class_0', 'class_1', 'class_2'], dtype='<U7')
# 데이터를 각각 class_0과 class_1, class_2로 분류한다는 뜻
# **5. DESCR
print(data.DESCR) # describe**

사이킷런의 주요 모듈 (4) 사이킷런 데이터셋을 이용한 분류 문제 실습

# **DataFrame으로 나타내기**
import pandas as pd
# 특성 행렬을 pandas에 DataFrame으로 나타낼수 있음
pd.DataFrame(data.data, columns=data.feature_names)
**# 머신러닝**
X = data.data   # 특성 행렬은 변수명 X에 저장
y = data.target # 타겟 벡터는 y에 저장

****from sklearn.ensemble import RandomForestClassifier **# 모델을 생성하자**
# 분류 문제라 RandomForestClassifier 사용해본다고 한다
model = RandomForestClassifier()

model.fit(X, y) **# 훈련 시키기**

y_pred = model.predict(X) **# 예측하기는 predict**

**# 성능 평가 하기** # 성능은 sklearn.metrics 모듈
from sklearn.metrics import accuracy_score  # accuracy_score 분류 문제
from sklearn.metrics import classification_report # classification_report 분류 문제
#타겟 벡터 즉 라벨인 변수명 y와 예측값 y_pred을 각각 인자로 넣습니다. 
print(classification_report(y, y_pred)) # 타겟 벡터 라벨 변수명 y, y의 예측값 y_pred
print("accuracy = ", accuracy_score(y, y_pred)) #정확도를 출력합니다. 

사이킷런의 주요 모듈 (5) Estimator

Estimator : 데이터셋을 기반으로 머신러닝 모델의 파라미터를 추정하는 객체

사이킷런의 모든 머신러닝 모델은 Estimator라는 파이썬 클래스로 구현되어 있다

훈련은 Estimaor의 fit() 메서드, 예측은 predict() 메서드 통해 이루어짐

LinearRegression() 과 RandomForestClassifier()가 Estimator 객체임

만약 타겟 벡터가 없다면 어떻게 표현할 수 있을까요?

정답이 없는 데이터인 비지도학습의 경우는 fit() 메서드의 인자로 Target Vector가 들어가지 않는다

사이킷런의 Estimator 객체를 사용한다면 비지도학습, 지도학습에 관계없이 학습과 예측 가능

훈련 데이터와 테스트 데이터 분리하기

훈련 데이터와 테스트 데이터 직접 분리하기

# 보통 훈련데이터와 테스트 데이터의 비율은 8:2로 한다
from sklearn.datasets import load_wine
data = load_wine()
print(data.data.shape)
print(data.target.shape)
# (178, 13) # 전체 데이터 178개를 8:2로 특성행렬과 타켓벡터로 나누기
# (178,) # 데이터 개수는 정수만 가능하기때문에 142 36개로 나누기

# 특성행렬과 타겟벡터는 ndarray type이니 numpy의 슬라이싱 사용 :
X_train = data.data[:142] 
X_test = data.data[142:]
print(X_train.shape, X_test.shape) # 특성행렬
# (142, 13) (36, 13)
y_train = data.target[:142]
y_test = data.target[142:]
print(y_train.shape, y_test.shape) # 타겟벡터
# (142,) (36,)
# 훈련 데이터와 테스트 데이터 분리 완료

from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier() # 모델 만들고
model.fit(X_train, y_train) # 훈련하기
y_pred = model.predict(X_test) # 예측하기

from sklearn.metrics import accuracy_score # 정확도 평가하기
print("정답률=", accuracy_score(y_test, y_pred))

train_test_split() 사용해서 분리하기

훈련에 쓴 데이터를 예측에 사용하면 정확도가 항상 100%가 나오기 때문에 훈련 데이터와 테스트 데이터는 분리가 필수다.

분리하는 기능을 API로 제공하고 있는데 model_selection의 train_test_split() 함수이다

from sklearn.model_selection import train_test_split

result = train_test_split(X, y, test_size=0.2, random_state=42)
# 인자로 특성행렬 X와, 타겟벡터 y를 넣고, 데이터비율을 키워드 인자로 20%로 지정
# random_state 인자에 seeed번호를 입력하면 된다. seed번호는 임의로 결정할수 있다
# 같은 번호를 지정하면 언제든 같은결과가 나온다
# train_test_split()은 반환값으로 4개의 원소로 이루어진 list를 반환
# 타입은 array, ()로 해서 array?!
print(type(result)) # <class 'list'> # list를 반환
print(len(result))  # 4 # 4개의 원소
# 모양 확인
result[0].shape # (142, 13) # 훈련 데이터용 특성 행렬
result[1].shape # (36, 13)  # 데스트 데이터용 특성 행렬
result[2].shape # (142,)    # 훈련 데이터용 타겟 벡터
result[3].shape # (36,)     # 테스트 데이터용 타겟 벡터

# 위에 함수를 이렇게 언패킹해서 사용해도 된다는 뜻이겠지?
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

실습

앞서 와인 분류 문제의 데이터를 훈련용 데이터셋과 테스트용 데이터셋으로 나눈 뒤 훈련하고 예측하는 전체 코드를 직접 작성해 보자

# 데이터셋 로드하기
# [[your code]
from sklearn.datasets import load_wine # 불러오기
data = load_wine()
# 훈련용 데이터셋 나누기
# [[your code]
X = data.data   # 특성 행렬은 변수명 X에 저장
y = data.target # 타겟 벡터는 y에 저장
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 훈련하기
# [[your code]
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier()
model.fit(X_train, y_train) # 훈련하기
# 예측하기
# [[your code]
y_pred = model.predict(X_test)
# 정답률 출력하기
# [[your code]
from sklearn.metrics import accuracy_score # 정확도 평가하기
print("정답률=", accuracy_score(y_test, y_pred))

좋은 웹페이지 즐겨찾기