티스토리 뷰

반응형

전복 나이를 예측하는 문제는 동일한 입력자료에 대해서 종속변수를 숫자 값이나 클래스 레이블로 모두 예측할 수 있어야 한다.  이를 해결하기 위한 접근 방식은 동일한 입력데이터에 대해 회귀 및 분류 예측 모델을 모두 개발하고 모델을 순차적으로 사용하는 것입니다.
또 다른 방법으로는 동일한 입력 데이터를 이묭해서 숫자 및 클래스 레이블 값을 모두 예측할 수 있는 단일 신경망 모델을 개발하는 것입니다. 이를 다중 출력 모델이라고 하며 Keras 및 TensorFlow와 같은 최신 딥 러닝 라이브러리를 사용하여 비교적 쉽게 개발하고 평가할 수 있다.
이 글에서는 회귀 및 분류 예측을 결합한 신경망을 개발하는 과정을 설명합니다.

반응형

1. 자료 설명


전복 데이터 세트
실습데이터로 '전복' 데이터셋을 사용할 것입니다.
전복의 나이를 결정하는 것은 시간이 많이 걸리는 작업이며 물리적 세부 사항만으로 나이를 결정하는 것이 바람직합니다.
이것은 전복의 물리적인 세부 사항을 설명하고 생물의 나이를 나타내는 전복의 고리 수를 예측해야 하는 데이터 세트입니다.

여기에서 데이터세트에 대해 자세히 알아볼 수 있습니다.
데이터세트(abalone.csv) [https://raw.githubusercontent.com/jbrownlee/Datasets/master/abalone.csv]
데이터세트 세부정보(abalone.names) [https://raw.githubusercontent.com/jbrownlee/Datasets/master/abalone.names]

 

전복데이터의 독립변수는 8개와 종속변수 1개로 구성되어 있다. 독립변수는 성별, 길이, 지름, 높이, 무게, 껍질 벗긴 무게, 내장무게, 껍질무게이고 종속변수 전복의 나이를 나타내는 Rings이다.

여기서 전복의 '나이'는 숫자 값(년 단위) 또는 클래스 레이블(클래스로서의 서수)로 예측할 수 있습니다.

- Sex(성별)                          nominal        M, F, and I (infant)
- Length(길이)                      continuous    mm    Longest shell measurement
- Diameter(지름)                  continuous    mm    perpendicular to length
- Height(높이)                      continuous    mm    with meat in shell
- Whole weight(무개)              continuous    grams    whole abalone
- Shucked weight(껍질 벗긴 무게)  continuous    grams    weight of meat
- Viscera weight(내장무게)        continuous      grams    gut weight (after bleeding)
- Shell weight(껍질무게)            continuous      grams    after being dried
- Rings            integer            +1.5 gives    the age in years

2. 자료 다운로드 및 요약

먼저 데이터 세트를 다운로드하고 요약하는 예제를 개발해 보겠습니다.

# load and summarize the abalone dataset
import pandas as pd
from matplotlib import pyplot
# load dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/abalone.csv'
dataframe = pd.read_csv(url, header=None)
# summarize shape
print(dataframe.shape)
# summarize first few lines
print(dataframe.head())

먼저 예제를 실행하면 데이터 세트의 모양이 다운로드되고 요약됩니다.
4,177개의 데이터(행)와 대상 변수를 포함한 9개의 특성(열)이 있음을 알 수 있습니다.

 

독립변수 8개

0: 성별, 1:길이, 2:지름, 3:높이, 4:무게, 5:껍질 벗긴 무게, 6:내장무게, 7:껍질무게,

종속변수 1개

8:나이
(4177, 9)
   0      1      2      3       4       5       6      7   8
0  M  0.455  0.365  0.095  0.5140  0.2245  0.1010  0.150  15
1  M  0.350  0.265  0.090  0.2255  0.0995  0.0485  0.070   7
2  F  0.530  0.420  0.135  0.6770  0.2565  0.1415  0.210   9
3  M  0.440  0.365  0.125  0.5160  0.2155  0.1140  0.155  10
4  I  0.330  0.255  0.080  0.2050  0.0895  0.0395  0.055   7


3. 딥러닝 기반 회귀 모델 개발

 

이번 과정은 나이를 숫자형태의 종속변수로 하고 전복 데이터 세트에 대한 회귀 MLP 모델을 개발할 것입니다.
먼저 열을 입력 및 출력 요소로 분리하고 문자열 값이 포함된 첫 번째 열인 성별을 삭제해야 합니다.
또한 로드된 모든 열이 float 유형(신경망 모델에서 예상됨)을 갖도록 강제하고 나중에 모델에서 알아야 하는 입력 기능의 수를 기록합니다.

 

우선 딥러닝 기반 회귀모델을 수행하기 위한 딥러닝 패키지를 불러옵니다.

# regression mlp model for the abalone dataset
import pandas as pd
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from sklearn.metrics import mean_absolute_error
from sklearn.model_selection import train_test_split

다음으로 전복데이터를 독립변수 8개를 X변수에 종속변수 1개를 변수에 저장하고 자료형태를 실수형으로 지정한다. 또한  n_features 변수에 독립변수 8개 개수를 저장한다.

 

# split into input (X) and output (y) variables
dataset = dataframe.values
X, y = dataset[:, 1:-1], dataset[:, -1]
X, y = X.astype('float'), y.astype('float')
n_features = X.shape[1]

다음으로 데이터 세트를 train_test_split()함수를 이용해서 학습 데이터와 검증 데이터로 분할할 수 있습니다.
67% 무작위 샘플을 사용하여 모델을 훈련하고 나머지 33%를 사용하여 모델을 평가합니다.

# split data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1)

그런 다음 다층 신경망 모델을 정의한다.

이 모델은 두 개의 은닉 레이어로 구성하고, 첫 번째는 20개의 노드가 있고 두 번째는 10개의 노드가 있으며 둘 다 ReLU 활성화 함수와 가중치 초기화는 he_normal를 사용합니다. 
출력 레이어에는 숫자 값을 예측하기 위한 단일 노드와 선형 활성화 함수가 있습니다.

# define the keras model
model = Sequential()
model.add(Dense(20, input_dim=n_features, activation='relu', kernel_initializer='he_normal'))
model.add(Dense(10, activation='relu', kernel_initializer='he_normal'))
model.add(Dense(1, activation='linear'))

모델 개발은 확률적 경사하강법의 효과적인 Adam 버전을 사용하여 평균 제곱 오차(MSE) 손실 함수를 최소화하도록 훈련됩니다.

# compile the keras model
model.compile(loss='mse', optimizer='adam')

 

model.fit()함수를 이용하여 전체 전복데이터를 32개씩 데이터로 나눈 미니 배치 크기로 150개의 반복하여 모델을 학습한다.

# fit the keras model on the dataset
model.fit(X_train, y_train, epochs=150, batch_size=32, verbose=2)

모델 학습을 마치면 마지막으로 검증데이터로 모델을 평균 절대 오차(MAE)를 이용하여 평가한다.

# evaluate on test set
yhat = model.predict(X_test)
error = mean_absolute_error(y_test, yhat)
print('MAE: %.3f' % error)

검증데이터로 이용해서 평가한 결과 약 1.5(rings)의 오차를 달성했음을 알 수 있습니다.

Epoch 145/150
88/88 - 0s - loss: 4.6130
Epoch 146/150
88/88 - 0s - loss: 4.6182
Epoch 147/150
88/88 - 0s - loss: 4.6277
Epoch 148/150
88/88 - 0s - loss: 4.6437
Epoch 149/150
88/88 - 0s - loss: 4.6166
Epoch 150/150
88/88 - 0s - loss: 4.6132
MAE: 1.554

 

4. 전체 코딩

 

앞서 순차적으로 설명된 전체 코드는 다음과 같다.

# regression mlp model for the abalone dataset
from pandas import read_csv
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from sklearn.metrics import mean_absolute_error
from sklearn.model_selection import train_test_split
# load dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/abalone.csv'
dataframe = read_csv(url, header=None)
dataset = dataframe.values
# split into input (X) and output (y) variables
X, y = dataset[:, 1:-1], dataset[:, -1]
X, y = X.astype('float'), y.astype('float')
n_features = X.shape[1]
# split data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1)
# define the keras model
model = Sequential()
model.add(Dense(20, input_dim=n_features, activation='relu', kernel_initializer='he_normal'))
model.add(Dense(10, activation='relu', kernel_initializer='he_normal'))
model.add(Dense(1, activation='linear'))
# compile the keras model
model.compile(loss='mse', optimizer='adam')
# fit the keras model on the dataset
model.fit(X_train, y_train, epochs=150, batch_size=32, verbose=2)
# evaluate on test set
yhat = model.predict(X_test)
error = mean_absolute_error(y_test, yhat)
print('MAE: %.3f' % error)

 

반응형
댓글