첫 만남 – 머신러닝 with 파이썬

사용할 모듈 포함문

from sklearn import datasets #머신 러닝 학습에 사용할 수 있는 데이터들
from sklearn.preprocessing import MinMaxScaler #전처리 공정 중에 MinMaxScaler
from sklearn.model_selection import train_test_split #데이터를 학습 및 테스트 용으로 분리
from sklearn import neighbors,linear_model #이웃 및 선형 모델
from sklearn.metrics import accuracy_score #평가 방법 중에 적합도
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

테스트에 사용할 데이터

첫 번째 머신러닝에 사용할 데이터는 붓꽃 데이터입니다. 

사이킷 런(sklearn)에서는 datasets 모듈을 통해 머신러닝 학습에 사용할 수 있는 몇 가지 데이터를 제공하고 있습니다.

그 중에 이번에는 붓꽃 데이터를 사용할 거예요.

iris = datasets.load_iris() #붓꽃 데이터 로드

붓꽃 데이터의 키 목록을 확인해 봅시다.

print(iris.keys())
[out]
dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])

키 별로 데이터 타입을 확인한 후에 하나씩 살펴볼게요.

for key in iris.keys():
  print(key,":",type(iris[key]))
[out]
data : <class 'numpy.ndarray'>
target : <class 'numpy.ndarray'>
frame : <class 'NoneType'>
target_names : <class 'numpy.ndarray'>
DESCR : <class 'str'>
feature_names : <class 'list'>
filename : <class 'str'>
data_module : <class 'str'>

iris.data

data가 무엇인지 먼저 살펴볼게요. (feature_names 키도 data 설명에 필요합니다.)

print(iris.data[0])
print(iris.data.shape)
print(iris.feature_names)
[out]
[5.1 3.5 1.4 0.2]
(150, 4)
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']

결과를 보면 4개의 특성을 갖는 150개의 데이터로 구성하고 있습니다.

그리고 각 특성은 꽃받침(sepal) 길이와 너비, 꽃잎(petal) 길이와 너비를 의미합니다.

iris.target

target이 무엇인지 알아봅시다. (target_names 키도 target 설명에 필요합니다.)

print(iris.target .shape)
print(np.unique(iris.target,return_counts=True))
print(iris.target_names)
[out]
(150,)
(array([0, 1, 2]), array([50, 50, 50]))
['setosa' 'versicolor' 'virginica']

결과를 보면 data의 개수처럼 150개입니다.

그리고 값의 종류는 0, 1, 2 이며 각 50개씩 있네요.

타겟 이름은 0은 setosa, 1은 versicolor, 2는 virginica임을 알 수 있어요.

여기에서는 iris.data를 독립변수, iris.target을 종속변수로 사용할 원본 데이터입니다.

데이터 전처리

독립변수는 학습 목적과 모델링 과정에서 보다 나은 결과를 위해 전처리 작업을 할 수 있습니다.

결측치 처리나 이상값 처리 외에도 전처리 작업에서 하는 일은 다양합니다.

여기에서는 독립변수의 크기를 일정하게 조절하는 작업을 할게요.

스케일 변환 방법은 크게 표준 점수로 스케일 조절하는 StandardScaler를 이용하는 방법과 0~1 사이의 값으로 조절하는 MinMaxScaler 등이 있습니다.

여기에서는 MinMaxScaler를 사용할게요.

mms = MinMaxScaler()
x_data = mms.fit_transform(iris.data)

스케일 조절하기 전과 후의 값의 기초 통계를 확인해 볼게요.

o_df = pd.DataFrame(iris.data)
display(o_df.describe())

df = pd.DataFrame(x_data)
display(df.describe())
[out]
원본 iris 데이터 통계
원본 iris 데이터 통계
변환 후 iris 데이터 통계
변환 후 iris 데이터 통계

변환 후 값을 보면 모든 컬럼의 최솟값은 0, 최댓값은 1로 바뀐 것을 알 수 있습니다.

참고로 MinMaxScaler에 의해 변환한 값은 (표본-최솟값)/(최댓값-최솟값) 입니다.

모델 학습하기 전에 학습에 사용할 데이터와 테스트(평가)에 사용할 데이터로 분리합니다.

sklearn.model_selection.train_test_split(*arraystest_size=Nonetrain_size=Nonerandom_state=Noneshuffle=Truestratify=None)

train_test_split 메뉴얼 사이트
x_train, x_test, y_train, y_test = train_test_split(x_data, iris.target)
print(x_train.shape, x_test.shape, y_train.shape, y_test.shape)
[out]
(112, 4) (38, 4) (112,) (38,)

기본적으로 75%는 학습 데이터,  25%는 평가 데이터로 분리합니다. 원하는 크기로 조절하기 원한다면 test_size 옵션을 이용하세요.

학습 데이터는 다시 실제 학습 데이터와 검증 데이터로 분리하는 것을 권장합니다.

x_train2, x_val, y_train2, y_val = train_test_split(x_train, y_train)
print(x_train2.shape, x_val.shape, y_train2.shape, y_val.shape)
[out]
(84, 4) (28, 4) (84,) (28,)

모델링 (데이터 학습)

모델링 작업에서는 다양한 모델로 학습하고 예측 결과를 확인하고 더 나은 모델을 찾는 작업을 수행합니다.

이를 위해 데이터를 다시 가공하거나 모델에 하이퍼 파라미터를 바꾸는 등의 다양한 작업을 수행합니다.

여기에서는 두 가지 모델(로지스틱 회귀, K-최근접 이웃)을 이용하여 분류 학습을 해 보기로 할게요.

로지스틱 회귀는 이름은 회귀 모델이지만 실제 분류 작업에 사용합니다.

모델을 생성한 후에 학습은 모델의 fit 메서드를 이용하고 예측은 predict 메서드를 이용합니다.

예측을 잘 하는지 평가하는 방법은 여러 가지 방법이 있는데 여기에서는 적합도(accuracy)로 평가할게요.

model1 = linear_model.LogisticRegression()
model2 = neighbors.KNeighborsClassifier()
for model in [model1,model2]:
  print(model.__class__.__name__,"###")
  model.fit(x_train2,y_train2)
  val_pred = model.predict(x_val)
  print(f"accuray:{accuracy_score(val_pred,y_val):.3f}")
[out]
LogisticRegression ###
accuray:0.750
KNeighborsClassifier ###
accuray:0.964

두 개의 모델 중에 KNeighborsClassifier 모델이 더 나은 점수를 얻었네요.

최종 평가는 테스트 데이터로 수행합니다.

print("선정 모델:",model2.__class__.__name__)
test_pred = model2.predict(x_test)
print(f"최종 accuray:{accuracy_score(test_pred,y_test):.3f}")
[out]
선정 모델: KNeighborsClassifier
최종 accuray:0.974

예측 값과 실제 값을 도식화 해 볼게요.

plt.plot(y_test,'ro',label='actual')
plt.plot(test_pred,'b.',label='pred')
plt.legend()
plt.show()

예측 결과와 실제 값
예측 결과와 실제 값