사이킷런은 파이썬 머신러닝 라이브러리 중 가장 많이 사용되는 라이브러리다.
사이킷런의 특징은 다음과 같다.
- 파이썬 기반의 다른 머신러닝 패키지도 사이킷런 스타일의 API를 지향할 정도로 쉽고 가장 파이썬스러운 API를 제공
- 머신러닝을 위한 매우 다양한 알고리즘 개발을 위한 편리한 프레임워크와 API를 제공
- 오랜 기간 실전 환경에서 검증됐으며, 매우 많은 환경에서 사용되는 성숙한 라이브러리이다.
<02 .첫 번째 머신러닝 만들어보기 - 붓꽃 품종 예측하기>
사이킷런을 통해 첫 번째로 만들어볼 머신러닝 모델은 붓꽃 데이터 세트로 붓꽃의 품종을 분류(Classfication)하는 것이다.
붓꽃 데이터 세트는 꽃잎의 길이와 넓이, 꽃받침의 길이와 너비 피처(Feature)를 기반으로 꽃의 품종을 예측하기 위한 것이다.
분류는 대표적인 지도학습 방법의 하나이다.
지도학습은 명확한 정답이 주어진 데이터를 먼저 학습한 뒤 미지의 정답을 예측하는 방식이다.
이때 학습을 위해 주어진 데이터 세트를 학습 데이터 세트, 머신러닝 모델의 예측 성능을 평가하기 위해 별도로 주어진 데이터 세트를 테스트 데이터 세트로 지칭한다.
사이킷런 패키지 내의 모듈명은 sklearn으로 시작하는 명명규칙이 있다.
#sklearn.datasets : 사이킷런에서 자체적으로 제공하는 데이터 세트를 생성하는 모듈의 모임
from sklearn.datasets import load_iris
#sklearn.tree : 모듈 트리 기반 ML 알고리즘을 구현한 클래스의 모임
from sklearn.tree import DecisionTreeClassifier
#sklearn.model_selection : 학습데이터, 검증데이터, 예측데이터로 데이터를 분리하거나 최적의 하이퍼 파라미터로 평가하기 위한 모듈 모임
from sklearn.model_selection import train_test_split
하이퍼 파라미터란?
머신러닝 알고리즘별로 최적의 학습을 위해 직접 입력하는 파라미터들을 통칭하며, 하이퍼 파라미터를 통해 머신러닝 알고리즘 성능을 튜닝할 수 있다.
붓꽃데이터 세트를 생성하는 데는 load_iris()를 이용하며, ML 알고리즘은 의사결정트리(Decision Tree)알고리즘으로, 이를 구현한 DecisionTreeClassifier을 사용한다.
그리고 데이터 세트를 학습, 테스트 데이터로 분리하는 데는 train_test_split()함수를 사용할 것이다.
import pandas as pd
#붓꽃 데이터 세트 로딩
iris = load_iris()
#iris.data는 Iris 데이터 세트에서 피처(feature)만으로 된 데이터를 numpy로 가지고 있다.
iris_data = iris.data
#iris.target은 붓꽃 데이터 세트에서 레이블(결정 값)데이터를 numpy로 가지고 잇다.
iris_label = iris.target
print('iris target값:', iris_label)
print('iris target명:', iris.target_names)
#붓꽃 데이터 세트를 자세히 보기 위해 DataFrame으로 변환
iris_df = pd.DataFrame(data = iris_data, columns = iris.feature_names) #칼럼명 설정
iris_df['lable'] = iris.target
iris_df.head(3)
[output]
iris target값: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2]
iris target명: ['setosa' 'versicolor' 'virginica']
피처에는 sepal length, sepal width, petal length, petal width 가 있다.
레이블은 0,1,2 세 가지 값으로 돼 있으며 0이 setosa 품종, 1이 versicolor 품종, 2가 virginica 품종을 의미한다.
다음으로 학습용 데이터와 테스트용 데이터를 분리해보자.
이 둘을 반드시 분리하는 이유는 학습 데이터로 학습된 모델이 얼마나 뛰어난 성능을 가지는지 평가하려면 테스트 데이터 세트가 필요하기 때문이다.
train_test_spilt()을 이용하면 학습 데이터와 테스트 데이터를 test_size 파라미터 입력값의 비율로 쉽게 분할한다.
예를 들어 test_size = 0.2로 입력 파라미터를 설정하면 전체 데이터 중 테스트 데이터가 20%, 학습 데이터가 80%로 데이터를 분할한다.
X_train, X_test, y_train, y_test = train_test_split(iris_data, iris_label,
test_size=0.2, random_state=11)
train_test_split()의 첫 번째 파라미터인 iris_data는 피처 데이터 세트이다.
두 번째 파라미터 iris_label은 레이블(label)데이터 세트이다.
test_size=0.2는 전체 데이터 세트 중 테스트 데이터 세트의 비율이다.
random_state는 호출할 때마다 같은 학습/테스트 용 데이터 세트를 생성하기 위해 주어지는 난수 발생 값이다.
train_test_split()는 호출 시 무작위로 데이터를 분리하므로 random_state를 지정하지 않으면 수행할 때마다 다른 학습/테스토용 데이터를 만들 수 있다.
위 예제에서 train_test_split()는 학습용 피처 데이터 세트를 X_train으로, 테스트용 피처 데이터 세트를 X_test로, 학습용 레이블 데이터 세트를 y_train으로, 테스트용 레이블 데이터 세트를 y_test로 반환한다.
학습 데이터를 확보했으니 이 데이터를 기반으로 의사 결정 트리를 이용해 학습과 예측을 수행해보자.
먼저 사이킷런의 의사결정 트리 클래스인 DecisionTreeClassifer을 객체로 생성한다.
생성된 DecisionTreeClassfier 객체의 fit()메서드에 학습용 피처 데이터 속성과 결정값(label) 데이터 세트를 입력해 호출하면 학습을 수행한다.
#DecisionTreeClassfier 객체 생성
dt_clf = DecisionTreeClassifier(random_state=11)
#학습 수행
dt_clf.fit(X_train, y_train)
이제 학습된 DecisionTreeClassfier 객체를 사용해 예측을 수행해보자.
예측은 반드시 학습 데이터가 아닌 다른 데이터를 이용해야 하며, 일반적으로 테스트 데이터 세트를 이용한다.
DecisionTreeClassfier 객체의 predict()메서드에 테스트용 피처 데이터 세트를 입력해 호출하면 학습된 모델 기반에서 테스트 데이터 세트에 대한 예측값을 반환하게 된다.
# 학습이 완료된 DecisionTreeclassifier 객체에서 테스트 데이터 세트로 예측 수행
pred = dt_clf.predict(X_test)
예측 결과를 기반으로 의사 결정 트리 기반의 DecisionTreeClassfier의 예측 성능을 평가해보자.
머신러닝의 모델 성능 평가는 여러가지 방법이 있지만 여기서는 정확도를 평가한다.
정확도는 예측 결과가 실제 레이블 값과 얼마나 정확하게 맞는지를 평가하는 지표이다.
예측한 붓꽃 품종과 실제 테스트 데이터 세트의 붓꽃 품종이 얼마나 일치하는지 확인해보자
사이킷런은 정확도 측정을 위해 accuracy_score() 함수를 제공한다.
이 함수의 첫 번째 파라미터로 실제 레이블 데이터 세트(테스트 데이터 세트), 두 번째 파라미터로 예측 레이블 데이터 세트를 입력하면 된다.
from sklearn.metrics import accuracy_score
print('예측 정확도:{0:.4f}'.format(accuracy_score(y_test, pred)))
[output]
예측 정확도:0.9333
앞의 붓꽃 데이터 세트로 분류를 예측한 프로세스를 정리해보면,
- 데이터 세트 분리: 데이터를 학습 데이터와 테스트 데이터로 분리한다. (*train_test_split()이용)
- 모델 학습: 학습 데이터를 기반으로 ML 알고리즘을 적용해 모델을 학습시킨다. (*의사결정 트리 클래스인 DecisionTreeClassifer을 객체로 생성 -> fit()메서드 적용)
- 예측 수행: 학습된 ML 모델을 이용해 테스트 데이터의 분류(즉, 붓꽃 종류)를 예측한다. (*predict()메서드 이용)
- 평가 : 이렇게 예측된 결괏값과 테스트 데이터의 실제 결괏값을 비교해 ML 모델 성능을 평가한다. (*accuracy _score()메서드 이용)
<03 .사이킷런의 기반 프레임 워크 익히기>
[Estimator 이해 및 fit(), predict() 메서드]
지도학습의 주요 두 축인 분류(Classification)와 회귀(Regression)의 다양한 알고리즘을 구현한 모든 사이킷런 클래스는 fit(), predict()만을 이용해 간단하게 학습과 예측 결과를 반환한다.
분류 알고리즘을 구현한 클래스인 Classifier
회귀 알고리즘을 구현한 클래스인 Regressor
이 둘을 합쳐서 Estimator 클래스라고 부른다.
즉, Estimor 클래스는 fit(), predict()를 내부에서 구현하고 있다.
cross_val_score()와 같은 evaluation 함수, GridSearchCV와 같은 하이퍼 파라미터 튜닝을 지원하는 클래스의 경우 이 Estimator를 인자로 받는다.
인자로 받은 estimator에 대해서 cross_val_score(), GridSearchCV.fit() 함수 내에서 이 Estimator의 fit(),predict()를 호출해서 평가를 하거나 하이퍼 파라미터 튜닝을 수행하는 것이다.
비지도학습인 차원 축소, 클러스터링, 피처 추출 등을 구현한 클래스 역시 대부분 fit()과 transform()을 사용한다.
비지도학습과 피처 추출에서 fit()은 데이터의 형태에 맞춰 데이터를 변환하기 위한 사전 구조를 맞추는 작업이다.
사전구조를 맞춘 후 입력데이터의 차원 변환, 클러스터링, 피처 추출등의 실제 작업은 transform()으로 작업한다.
사이킷런은 이들을 하나로 결합한 fit_transform()도 함께 제공한다.
[사이킷런의 주요 모듈]
일반적으로 머신러닝 모델을 구축하는 주요 프로세스는 피처 처리, ML 알고리즘 학습/예측 수행, 그리고 모델 평가의 단계를 반복적으로 수행하는 것이다.
사이킷런 패키지는 머신러닝 모델을 구축하는 주요 프로세스를 지원하기 위해 매우 편리하고 다양하며 유연한 모델을 지원한다.
[내장된 예제 데이터 세트]
사이킷런에는 별도의 외부 웹사이트에서 데이터 세트를 내려받을 필요 없이 예제로 활용할 수 있는 좋은 데이터세트를 내장하고 있다.
이 데이터는 datasets 모듈에 있는 여러 API를 호출해 만들 수 있다.
분류나 회귀를 연습하기 위한 예제용도의 데이터 세트와 분류나 클러스터링을 위해 표본 데이터로 생성될 수 있는 데이터 세트로 나누어진다.
분류, 회귀를 위한 연습용 예제 데이터가 어떻게 구성되어있는지 살펴보자
사이킷런에 내장된 데이터 세트는 일반적으로 딕셔너리 형태로 되어있다.
개별 키가 가리키는 데이터 세트의 의미에 대해서 살펴보자
- data는 피처의 데이터 세트를 가리킨다. - 넘파이(ndarray) 타입
- target은 분류 시 레이블 값, 회귀일 때는 숫자 결괏값 데이터 세트이다. - 넘파이(ndarray) 타입
- target_names는 개별 레이블의 이름을 나타낸다. - 넘파이 또는 리스트 타입
- feature_names는 피처의 이름을 나타낸다. - 넘파이 또는 리스트 타입
- DESCR은 데이터 세트에 대한 설명과 각 피처의 설명을 나타낸다. - 스트링 타입
피처의 데이터 값을 반환받기 위해서는 내장 데이터 세트 API를 호출한 뒤에 그 Key값을 지정하면 된다.
from sklearn.datasets import load_iris
iris_data = load_iris()
print(type(iris_data))
[output]
<class 'sklearn.utils.Bunch'>
Bunch 클래스는 파이썬의 딕셔너리 자료형과 유사하다.
데이터 세트에 내장돼 있는 대부분의 데이터 세트는 이와 같이 딕셔너리 형태의 값을 반환한다.
딕셔너리 형태의 load_iris() 데이터 세트의 key값을 확인해보자
keys = iris_data.keys()
print('붓꽃 데이터 세트드의 키들:', keys)
[output]
붓꽃 데이터 세트드의 키들: dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])
데이터 키는 피처들의 데이터 값을 가리킨다.
데이터 세트가 딕셔너리 형태이기 때문에 피처 데이터 값을 추출하기 위해서는 데이터세트.data를 이용하면 된다.
load_iris()가 반환하는 객체의 키인 feature_names, target_name, data, target이 가리키는 값을 다음 예제 코드에 출력했다.
print('\n feature_names의 type:', type(iris_data.feature_names))
print('feature_names의 shape:', len(iris_data.feature_names))
print(iris_data.feature_names)
print('\n target_names의 type:', type(iris_data.target_names))
print('\n target_names의 shape:', len(iris_data.target_names))
print(iris_data.target_names)
print('\n data의 type:', type(iris_data.data))
print('\n data의 shape:', iris_data.data.shape) # data는 넘파이 배열
print(iris_data['data'])
print('\n target의 type:', type(iris_data.target))
print('target의 shape:', iris_data.target.shape) #넘파이 배열
print(iris_data.target)
[output]
feature_names의 type: <class 'list'>
feature_names의 shape: 4
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
target_names의 type: <class 'numpy.ndarray'>
target_names의 shape: 3
['setosa' 'versicolor' 'virginica']
data의 type: <class 'numpy.ndarray'>
data의 shape: (150, 4)
[[5.1 3.5 1.4 0.2]
[4.9 3. 1.4 0.2]
[4.7 3.2 1.3 0.2]
[4.6 3.1 1.5 0.2]
.........................
[6.5 3. 5.2 2. ]
[6.2 3.4 5.4 2.3]
[5.9 3. 5.1 1.8]]
target의 type: <class 'numpy.ndarray'>
target의 shape: (150,)
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2]
Ref) 파이썬 머신러닝 완벽가이드