본문 바로가기
딥러닝

[딥러닝] 텐서플로우 분류 ANN: loss= 'binary_crossentropy', activation= 'sigmoid', epoch, batch_size

by eyoo 2022. 6. 10.

고객 정보와 해당 고객이 금융상품을 갱신했는지 안했는지의 여부에 대한 데이터가 있다.

 

이 데이터를 사용하여 갱신여부를 예측하는 딥러닝을 만들자.

 

먼저 머신러닝에서 했던것처럼 데이터의 전처리를 해줘야 한다.

 

데이터를 확인하자.

 

in:

df.head(3)

out:

# CreditScore 부터 EstimatedSalary까지 X로 설정하고, Exited를 y로 설정하면 될것이다.

 

 

Nan을 확인하자.

 

in:

df.isna().sum()

out:

RowNumber          0
CustomerId         0
Surname            0
CreditScore        0
Geography          0
Gender             0
Age                0
Tenure             0
Balance            0
NumOfProducts      0
HasCrCard          0
IsActiveMember     0
EstimatedSalary    0
Exited             0
dtype: int64

# Nan이 없는것을 확인했다.

 

 

X와 y로 분리한다.

 

X = df.iloc[:,3:-1]
y = df['Exited']

 

 

 

그 후 인코딩한다.

 

인코딩하기전 원핫인코딩과 레이블 인코딩을 할 컬럼을 확인한다.

 

in:

X.dtypes

out:

CreditScore          int64
Geography           object
Gender              object
Age                  int64
Tenure               int64
Balance            float64
NumOfProducts        int64
HasCrCard            int64
IsActiveMember       int64
EstimatedSalary    float64
Exited               int64
dtype: object

# Geography와 Gender를 인코딩 해야한다.

# Geography는 2개 이상의 카테고리컬 데이터가 있으므로 원핫 인코딩하고 Gender는 2개이니 레이블인코딩 한다.

 

 

먼저 레이블 인코딩부터 하고 그 다음에 원핫 인코딩 한다. 

 

from sklearn.preprocessing import OneHotEncoder, LabelEncoder
from sklearn.compose import ColumnTransformer

l_encoder = LabelEncoder()
X['Gender'] = l_encoder.fit_transform(X['Gender'])

ct = ColumnTransformer( [ ('encoder',OneHotEncoder(), [1] ) ] , remainder='passthrough' )
X = ct.fit_transform(X)

 

 

추가적으로 더미 변수처리를 한다.

 

Geography 컬럼에는 France, Germany, Spain 이렇게 세개의 카테고리컬 데이터로 구성되어있다.

딥러닝 학습을 조금 더 빠르게 처리하기 위해 원핫인코딩으로 변환된 Geography 컬럼들중 하나를 제외하여 더미변수처리를 한다.

 

# 더미 변수
# Germany, Spain
#   0        0       <-France
#   1        0
#   0        1
# France 컬럼 제외
X = X[:,1:]

# France 컬럼을 제외하여 데이터 수를 줄였다.

# Germany와 Spain이 모두 0이면 France인것으로 알수있다.

# 카테고리컬 데이터가 3개일때 가능하다.

 

 

이제 피쳐 스케일링 작업을 한다.

 

from sklearn.preprocessing import StandardScaler
scaler_X = StandardScaler()
X = scaler_X.fit_transform(X)

# y는 0과 1로 이루어져있기에 X만 스케일링한다.

 

 

그리고 학습용과 검증용으로 나눈다.

 

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=0)

 

 

여기까지는 머신러닝 전처리 방식과 같다고 보면된다.

 

이제 ANN(Artificial Neural Network: 인공신경망)을 만들자

 

먼저 시퀀셜로 틀을 잡는다.

 

import tensorflow as tf
from tensorflow import keras
from keras.models import Sequential
from keras.layers import Dense

model = Sequential()

 

 

그 후 인풋 레이어, 히든 레이어, 아웃풋 레이어를 추가한다.

 

먼저 히든 레이어를 relu 엑티베이션으로 구성한다.

 

model.add(Dense(units = 6, activation='relu', input_shape= (11,)))

# X_train의 shape이 (8000,11) 으로 나오니 받을 데이터는 11개다.

# 인풋 레이어는 첫번째 히든 레이어를 만들때 input_shape 함수를 이용하여 만든다.

# 노드는 6개로 만들어 보자.

 

 

그 후 노드가 8개인 히든 레이어를 만들어 보자.

 

model.add(Dense(units = 8, activation= tf.nn.relu))

# tf.nn으로 엑티베이션을 설정했다. (엑티베이션의 결과는 위의 히든레이어와 같은 relu다.)

 

 

이제 0과 1로 분류하는 엑티베이션인 sigmoid를 사용하여 아웃풋 레이어를 만든다.

 

model.add(Dense(units = 1, activation= 'sigmoid'))

# 아웃풋 레이어는 하나의 결과만을 도출해야하므로 1개의 노드만 나오도록 한다.

# 시그모이드 함수는 분류할때 아웃풋 레이어에서만 사용할수있다.

 

 

이제 만들어진 모델을 adam과 binary_crossentropy로 컴파일한다.

 

model.compile(optimizer= 'adam', loss= 'binary_crossentropy',metrics= ['accuracy'])

# 예측이 아닌 0과1, 두가지로 분류하는 것이기 때문에 loss에 mse가 아닌 binary_crossentropy 사용한다.

# 정확도를 보여주기위해 metrics파라미터에 ['accuracy']를 입력한다.

 

 

만들어진 신경망의 형태를 summary함수로 볼수있다.

 

in:

model.summary()

out:

Model: "sequential_83"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 dense_249 (Dense)           (None, 6)                 72        
                                                                 
 dense_250 (Dense)           (None, 8)                 56        
                                                                 
 dense_251 (Dense)           (None, 1)                 9         
                                                                 
=================================================================
Total params: 137
Trainable params: 137
Non-trainable params: 0
_________________________________________________________________

# Param #은 파라미터(가중치)의 수를 나타낸다.

# 11개의 데이터를 받고 노드가 6개인데 파라미터가 72인 이유는 각 레이어마다 상수가 하나씩 더 추가되기 때문이다.

 

 

이제 ANN을 fit으로 학습 시킨다.

 

model.fit(X_train, y_train, epochs = 20, batch_size = 10)

# epoch는 신경망에서 전체 데이터 셋에 대해 forward pass/backward pass 과정을 거친 것을 말함. (전체 데이터 셋에 대해 한 번 학습을 완료한 상태)

# 한 번의 epoch에서 모든 데이터를 한번에 넣을 수 없기 때문에 데이터를 나누어 주는데 이 때 나누어 주는 데이터 사이즈를 batch size라고한다.

 

 

evaluate함수로 학습이 잘 진행되었는지 확인할수있다.
 

in:

model.evaluate(X_test, y_test)

out:

63/63 [==============================] - 0s 1ms/step - loss: 0.3367 - accuracy: 0.8580
[0.3367190361022949, 0.8579999804496765]

# 오차가 0.33 정확도가 0.85 인것을 확인할수있다.

 

 

아래의 신규 데이터를 통해 분류해 보자

 

  • Geography: France
  • Credit Score: 600
  • Gender: Male
  • Age: 40
  • Tenure: 3
  • Balance: 60000
  • Number of Products: 2
  • Has Credit Card: Yes
  • Is Active Member: Yes
  • Estimated Salary: 50000

먼저 넘파이 어레이를 만들어서 컴퓨터가 읽을수있도록 만든다.

 

new_data = np.array([600,'France','Male',40,3,60000,2,1,1,50000])

 

 

현재 데이터가 1차원이기 때문에 2차원으로 만들어준다.

 

new_data = new_data.reshape(1,10)

# 1차원일때의 shape은 (10,)

 

 

레이블 인코딩 먼저 해준다.

 

new_data[:,2] = l_encoder.transform(new_data[:,2])

# Gender인 Male을 변환해줬다.

 

 

이제 ct변수로 원핫인코딩 해준다.

 

new_data = ct.transform(new_data)

# France가 변환되어 3개의 컬럼으로 나누어졌다.

 

 

더미 변수 처리를 했었기 때문에 똑같이 처리해준다.

 

new_data = new_data[:,1:]

 

 

피쳐스케일링 해준다.

 

new_data = scaler_X.transform(new_data)

 

 

예측하기 좋은 데이터로 변환된 새로운 데이터를 예측한다.

 

in:

y_pred = model.predict(new_data)
y_pred

out:

array([[0.04310161]], dtype=float32)

 

 

시그모이드의 특성은 0.5 이상은 1 이하는 0으로 분류하는것이다. 이것을 정수로 나타내도록 하자.

 

in:

(y_pred>0.5).astype(int)

 

out:

array([[0]])

# 해당 고객은 금융상품을 갱신하지 않는걸로 예측된다.

 

 

 

 

 

댓글