본문 바로가기

Computer Science/Machine Learning

Getting started with the Scikit-Learn library

Scikit Learn 라이브러리는 이전 포스팅에서도 언급한 적이 있는데요. 이 라이브러리 하나만으로도 데이터 셋을 쪼개고, 모델에 훈련시키고 테스트 하기에 무리가 없습니다. 이번 포스팅에서는 간단한 데이터 split과 모델 훈련 데이터에 대해 알아보고자 합니다.

 

싸이킷런을 활용해보는 것에 중점을 두고자, 데이터는 파이썬에 업로드 되어있는 데이터를 활용했어요. 따라서 데이터 전처리는 건너뛰도록 하겠습니다. (7. Dataset loading utilities — scikit-learn 0.23.2 documentation (scikit-learn.org)

 

7. Dataset loading utilities — scikit-learn 0.23.2 documentation

The 20 newsgroups dataset comprises around 18000 newsgroups posts on 20 topics split in two subsets: one for training (or development) and the other one for testing (or for performance evaluation). The split between the train and test set is based upon a m

scikit-learn.org

 

Breast cancer wisconsin (diagnostic) dataset

 

 

import matplotlib.pyplot as plt

from sklearn.datasets import load_breast_cancer

from sklearn.model_selection import train_test_split

from sklearn.tree import DecisionTreeClassifier, plot_tree

from sklearn.metrics import confusion_matrix, plot_confusion_matrix
from sklearn.metrics import accuracy_score

 

 

필요한 라이브러리들을 import합니다.

이제 데이터를 train과 test data set으로 나눠보겠습니다.

 

input_data = load_breast_cancer()
X, y, X_names = input_data.data, input_data.target, input_data.feature_names
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=10)

 

1행 : input data를 파이썬에 저장된 데이터에서 불러옵니다.

2행 : X, y 그리고 X_names 세 변수를 한 줄에 호출합니다.

3행 : X_train, X_test, y_train, y_test 네 데이터로 쪼개주는 split 함수를 사용합니다. test_size = 0.2로 지정하면 데이터의 20%가 테스트 데이터로 지정됩니다. 80%는 훈련용입니다.

* random_state는 난수를 정해줌으로써, 일정한 환경에서 개발하기위해 지정해줍니다. split 함수는 랜덤하게 set을 쪼개기 때문에, 코드를 돌릴때 마다 결과가 달라집니다. 많은 개발환경에서는 이 randomness를 고정하고, 코딩 시 발생하는 오류를 고쳐나가는데, 이를 고정하고 코드를 돌릴 때 마다 같은 splitting을 갖기 위해서 지정하는 것입니다.

* stratify라는 유용한 인자도 소개하고자 합니다. 이 인자는 starify에 지정한 비율 만큼 sample 데이터를 split합니다. 따라서 imbalanced dataset에 대해 유용하게 사용할 수 있습니다.

 

 

이제 Decision Tree에 피팅해보겠습니다.

 

clf = DecisionTreeClassifier()
clf.fit(X_train, y_train)

fig = plt.figure(figsize=(50,50))
plot_tree(clf, feature_names = X_names, filled=True, rounded=True)

 

clf(classifier)라는 변수에 의사결정 나무를 저장하고, 다음 줄에서 .fit 함수를 사용해 train 데이터에 대해 훈련시킵니다. 1행의 괄호 안에 다른 인자들을 지정할 수 있는데, 이는 조금 후에 언급하도록 하겠습니다.

3행에서는 plot하기 위해 지정, 4행에서는 decision tree를 첫번째 인자로 넣어주고, 숫자로 지정되어 있던 feature name을 문자로 바꿔주는 인자 feature_name을 사용합니다. filled 인자는 그래프 상자에 색을 넣어주는 인자이고, rounded 인자는 상자의 모서리를 둥글게 만들어 주는 인자입니다.

 

 

 

실행하면 위와 같은 의사결정 나무가 출력되는데요. 맨 위 상자부터 보면, 어떤 feature에 따라 샘플들이 나뉘었는지 나타나 있습니다. gini 불순도도 나타나 있는데, 이는 집합에 이질적인 것이 얼마나 섞였는지를 나타내는 지표라고 합니다. 따라서 이를 이용해 entropy도 계산해 낼 수 있습니다. tree의 맨 끝단에 몇개의 샘플이 있는지도 확인할 수 있습니다.

* 흰색 상자의 경우 gini = 0.5 이기 때문에 색이 칠해지지 않았습니다.

 

 

다음으로, 이 decision tree의 정확도를 확인해보겠습니다.

 

y_pred_train = clf.predict(X_train)
y_pred_test = clf.predict(X_test)

print(confusion_matrix(y_train, y_pred_train))
print(confusion_matrix(y_test, y_pred_test))

acc_train = accuracy_score(y_train, y_pred_train)
acc_test = accuracy_score(y_test, y_pred_test)
print("Train/test accuracy: %.2f/%.2f"  % (acc_train, acc_test))

plot_confusion_matrix(clf, X_test, y_test, cmap=plt.cm.Blues)

 

1행과 2행 : train과 test set에 대해 .predict 함수를 이용해 예측을 진행합니다.

3행과 4행 : confusion matrix = 어떤 데이터들이 정확히 예측되었는지 나타내는 행렬, 실행 시 결과가 아래와 같이 나오는데

[[169   0]
 [  0 286]]  : train set 에서, 잘못 맞춘 데이터는 0개. 
[[39  4]
 [ 4 67]] : test set에서 틀린 데이터는 4개 + 4개 = 8개

 

5행과 6행 : 정확도를 수치로 나타내는 함수 accuracy_score 호출

7행 : 출력, 실행 시 결과는 Train/test accuracy: 1.00/0.93 으로 나타납니다.

8행 : confusion matrix를 c-map으로 표현.

 

 

트레이닝 셋의 정확도는 항상(거의) 100%입니다. 이것은 over fitting의 증거이기도 한데요, 이런 이유로 test set을 지정해야 합니다. 그리고 절대로 fitting에 활용되어서는 안됩니다.

 

또한, 코드를 계속 돌려보면 알겠지만 random_state를 지정했음에도 불구하고 실행할 때마다 결과가 다르게 나옵니다. 그 이유는 DecisionTreeClassifier 함수 안의 인자에 관련되어 있습니다. 아무것도 지정하지 않고 실행하면 random_state = None이 기본값입니다. max_features < n_features인 경우 알고리즘은 각각의 split 중 best를 찾아내기 전에 max_features를 선택합니다. 그런데 이 best split이 max_features = n_features 인 경우에도 실행마다 계속 바뀔 수 있습니다. 따라서 피팅하는 동안 determinisctic behavior를 원한다면 randon_state를 정수로 고정해주어야 합니다. 즉, 위의 코드에서 DecisionTreeClassifier( random_state = 10 ) 으로 잡으면 몇 번 실행하더라도 결과는 동일하게 나옵니다.

 

만약 random_state 인자를 다 없애면 decision tree부터 실행할 때 마다 바뀝니다.

 

 

K-Nearest Neighbour and Linear Regression

 

이번에는 조금 다른 데이터를 사용해보고자 합니다.

7. Dataset loading utilities — scikit-learn 0.23.2 documentation (scikit-learn.org)

 

7. Dataset loading utilities — scikit-learn 0.23.2 documentation

The 20 newsgroups dataset comprises around 18000 newsgroups posts on 20 topics split in two subsets: one for training (or development) and the other one for testing (or for performance evaluation). The split between the train and test set is based upon a m

scikit-learn.org

 

Diabetes dataset

 

import matplotlib.pyplot as plt

from sklearn.datasets import load_diabetes

from sklearn.model_selection import train_test_split

from sklearn.neighbors import KNeighborsRegressor
from sklearn.linear_model import LinearRegression

from sklearn.metrics import mean_squared_error

 

필요한 라이브러리와 데이터셋을 불러옵니다.

 

 

X, y = load_diabetes(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state = 10)

 

평균을 내거나 플롯하지 않을 거라, x와 y값만 불러옵니다. 그리고 동일하게 split을 진행합니다.

 

 

clf = LinearRegression()
clf.fit(X_train, y_train)

y_pred_train = clf.predict(X_train)
y_pred_test = clf.predict(X_test)
mse_train = mean_squared_error(y_train, y_pred_train)
mse_test = mean_squared_error(y_test, y_pred_test)
print("Train/test MSE: %.1f/%.1f"  % (mse_train, mse_test))

 

1행 : Liniear Regression 함수를 호출

2행 : 모델에 x와 y train 데이터를 피팅

4행, 5행 : train과 test 데이터 각각 결과를 예측

6행, 7행 : mean squared error 함수를 사용, 오차율 계산

결과는 Train/test MSE: 2851.0/2911.8 로 나옵니다.

 

 

plt.scatter(y_train, y_pred_train, color='black')
plt.scatter(y_test, y_pred_test, color='blue')
plt.show()

 

 

y축은 Predicted label, x축은 True label입니다. 

 

 

clf = KNeighborsRegressor(n_neighbors = 10)
clf.fit(X_train, y_train)

 

KNeighborsRegressor 함수를 사용해 KNN 모델을 사용할 수도 있습니다. 이때 인자에 n값을 넣어주면 지정도 가능합니다.

'Computer Science > Machine Learning' 카테고리의 다른 글

Learning Curves  (0) 2020.12.28
Cross Validation, Grid Search with GridSearchCV  (0) 2020.12.28
Dendrograms and Heat Plots  (0) 2020.12.14
Hierarchical Clustering에 대하여  (0) 2020.12.13
Random Forest 배워보기  (0) 2020.07.10