개발/머신러닝

파이썬 머신러닝 - 텐서플로우를 이용한 ANN , Dummy variable trap,batch_size , epochs

웅'jk 2022. 12. 27. 17:07

먼저 텐서플로우는 파이썬에서 딥러닝과 머신러닝을 위한 라이브러리 입니다.

 

우리는 이 텐서플로우로 ANN을 만들어보도록 하겠습니다.

 

먼저 기존의 머신러닝과는 다르게 ANN은 딥러닝 으로 구글의 코랩 이라는 서버를 빌려 작동을 시키겠습니다.

( 이유는 코랩이 보다 사양이 높기 때문입니다. 머신러닝과는 다르게 여러번의 수행이 필요합니다. )

 

https://colab.research.google.com/?hl=ko 

 

Google Colaboratory

 

colab.research.google.com

구글 코랩에서 파이썬 파일을 실행하여 작동하도록 하겠습니다.

 

1. 먼저 데이터를 가져오도록합니다. 

 - 다만 이때 데이터파일을 코랩 서버 경로에 옮겨야하기때문에 구글드라이브를 이용하여 파일을 업로드합니다.

 - 업로드된 파일을 코랩에서 구글드라이브로 가져오도록 다음과 같이 작성합니다.

from google.colab import drive
drive.mount('/content/drive')

 - 구글 코랩 좌측 상단에 다음과 같이 눌러 파일을 추가합니다.

 - 이제 코랩서버에서 내 파일이 있는 경로로 가 데이터 파일을 읽어옵니다.

import os
os.chdir('/content/drive/MyDrive/Colab Notebooks/ml_plus/data')
df = pd.read_csv('Churn_Modelling.csv')

 

2. 읽어온 df를 분석하여 X,y 축을 설정합니다.

#  1. NaN 있는지 확인
df.isna().sum()

# 2. X, y 로 분리
y = df['Exited']
X = df.iloc[:,3:-1]

이때 y축의 결과는 0,1 로 분류의 문제 모델링을 진행하도록 합니다.

 

 

3.  문자열 데이터가 있다면 인코더를 통해 바꿔주도록 합니다.

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

# 3 - 1. gender 컬럼 label 인코더
label_encoder = LabelEncoder()
X['Gender'] = label_encoder.fit_transform(X['Gender'])

# 3 - 2. Geography one - hot 인코더
ct = ColumnTransformer([('encoder',OneHotEncoder(),[1])], remainder = 'passthrough' )
X = ct.fit_transform(X.values)

여기서 제 파일의 경우 gender 는 unique한 값이 2개라 레이블을 , geography 항목은 3개 이상이라 one-hot을 적용하였습니다.

 

3 - 1. dummy variable trap 

 여기서 우리가 알아봐야할 것이 있습니다. 바로 geography 항목입니다. 

geography 는

France , Germerny, Spain

위 3가지 항목으로 이루어져 있으며 이 항목들을 원핫을 통해 나타낸다면 

France 의 경우 

1 , 0 , 0

Germerny 의 경우

0 , 1 , 0

Spain의 경우

0 , 0 , 1

로 나타내게 됩니다. 여기서 잘 생각해보면 France의 값이 없다고 해서 우리가 이 값들에 의미를 알 수가 없을까요?

만약 프랑스를 의미하는 컬럼을 삭제하고 생각해봅시다.

 

그럼 Germerny 의 경우 1,0  , Spain의 경우 0 , 1 을 타내게 됩니다.

그럼 France 는 어떻게 될까요? 바로 0,0 이 됩니다. 

 

이런식으로 France 항목을 지웠음에도 알 수 있도록 하는 방법이 dummy variable trap 방식입니다.

 

따라서 이번에는 이 방식을 적용하여 개발해보도록 하겠습니다.

 

X_df = pd.DataFrame(X)
X_df.drop(0,axis = 1 , inplace = True)
X = X_df.values

 

4. 피처스케일링을 진행합니다.

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

 

5.학습용 train 과 test 를 나눕니다.

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)

 

6. ANN 모델링을 만들어봅시다.

# 빈모델링
model = Sequential()

# 첫번째 레이어
model.add( Dense(units = 6 , activation = 'relu' , input_shape = (11,) )  )
# 두번째 레이어
model.add( Dense(units = 8 , activation = tf.nn.relu ) )

# 아웃풋 레이어
# 최종 결과가 0 , 1 2 가지의 분류이기 때문에 시그모이드 함수를 이용한다.
model.add(Dense(units = 1 , activation = 'sigmoid'))

# 모델링 확인
model.summary()

 

7. 만든 모델링은 컴파일을 진행해줘야합니다.

# 컴파일이란, 옵티마이저(optimizer)의 로스펑션(loss function, 오차함수 or 손실함수), 검증방법을 셋팅하는 과정을 의미한다.
# 2개로 분류하는 문제의 loss 은 'binary_crossentropy' 이것을 설정한다. , 검증방법(metrics) 는 정확도로 설정한다.
model.compile(optimizer='adam',loss='binary_crossentropy',metrics=[ 'accuracy'] )

#epoch

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

#batch_size

#메모리의 한계와 속도 저하 때문에 대부분의 경우에는 한 번의 epoch에서 모든 데이터를 한꺼번에 집어넣을 수는 없습니다. 
#그래서 데이터를 나누어서 주게 되는데 이때 몇 번 나누어서 주는가를 iteration, 각 iteration마다 주는 데이터 사이즈를 batch size라고 합니다.

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

즉 여기서 epochs 는 내가 설정한 데이터셋을 몇번 이용할 것인가.

batch_size는 내 데이터를 몇개로 나누어 설정할 것인가 이다.

 

지금 제 X_train 은 8천개 이므로 10개씩 들어갈 것이고, 이 8천개의 데이터를 20번 사용할 뜻이다.

 

8.모델링에 테스트값 넣어 평가한다.

# 모델에 테스트값 평가
model.evaluate(X_test,y_test)

# 정확도 및 컨퓨전 매트릭스 확인
from sklearn.metrics import confusion_matrix, accuracy_score
y_pred = model.predict(X_test)
y_pred = (y_pred > 0.5).astype(int)
cm = confusion_matrix(y_test , y_pred)
(1568 + 139) / cm.sum()
accuracy_score(y_test, y_pred)

 

9. 이제 내가 직접 값을 넣어 확인한다.

# 신규데이터를 numpy로 저장합니다.
new_data = np.array([600,'France','Male',40,3,60000,2,1,1,50000])

# 신규데이터의 차원을 2차원으로 만들어줍니다.
new_data = new_data.reshape(1,10)

# label 인코더를 통해 male 값을 바꿔줍니다.
label_encoder.transform(new_data[ : , 2])
new_data[:,2] = label_encoder.transform(new_data[ : , 2])

# one-hot 인코더로 france 값을 바꿔줍니다.
ct.transform(new_data)
new_data = ct.transform(new_data)

# X_test 처럼 france 항목을 지워버립니다.
new_data=new_data[:,1:]

# 피처스케일링을 진행합니다.
scaler_X.transform(new_data)

# 예측을해 값을 구합니다.
model.predict(new_data)
new_data_predict = model.predict(new_data)

# 구한 값을 0,1 로 구분합니다.
( new_data_predict > 0.5 ).astype(int)