군침이 싹 도는 코딩

텐서플로우로 분류의 문제 모델링 하는 방법 본문

Python/Deep Learning

텐서플로우로 분류의 문제 모델링 하는 방법

mugoori 2022. 12. 27. 16:26
df = pd.read_csv('Churn_Modelling.csv')

# 먼저 데이터 프레임을 불러온다

 

 

 

df.isna().sum()
>>> 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 = df.loc[:,'CreditScore':'EstimatedSalary']
y = df['Exited']

변수 X 에 저장한 데이터
변수 y에 저장한 데이터

# X,y로 분리한다

 

 

 

 

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

X['Geography'].nunique()
>>> 3

X['Gender'].nunique()
>>> 2

# 변수 X 에 있는 데이터중 문자열을 숫자로 바꿔주는 작업을 해야한다

먼저 필요한 라이브러리를 임포트해준다음

카테고리컬 데이터의 갯수를 확인한다

 

 

 

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

# 젠더 컬럼의 경우 카테고리컬 데이터가 2개이므로 레이블 인코딩을 한다

X를 찍어보니 잘 변환 되었다

 

 

 

 

ct = ColumnTransformer( [ ('encoder',OneHotEncoder(),[1])  ] , remainder='passthrough' )
X = ct.fit_transform( X.values )
X
>>> array([[1.0, 0.0, 0.0, ..., 1, 1, 101348.88],
           [0.0, 0.0, 1.0, ..., 0, 1, 112542.58],
           [1.0, 0.0, 0.0, ..., 1, 0, 113931.57],
           ...,
           [1.0, 0.0, 0.0, ..., 0, 1, 42085.58],
           [0.0, 1.0, 0.0, ..., 1, 0, 92888.52],
           [1.0, 0.0, 0.0, ..., 1, 0, 38190.78]], dtype=object)

#지오그래피의 경우 3개이므로 원핫 인코딩으로 해준다

역시 잘 변환 되었다

 

 

 

 

# 더미 바리에이블 트랩을 사용해서 부하를 줄여준다
더미 바리에이블의 설명은 이 글을 참고한다 : https://mugoori.tistory.com/123
 

Dummy variable trap

X >>> array([[1.0, 0.0, 0.0, ..., 1, 1, 101348.88], [0.0, 0.0, 1.0, ..., 0, 1, 112542.58], [1.0, 0.0, 0.0, ..., 1, 0, 113931.57], ..., [1.0, 0.0, 0.0, ..., 0, 1, 42085.58], [0.0, 1.0, 0.0, ..., 1, 0, 92888.52], [1.0, 0.0, 0.0, ..., 1, 0, 38190.78]], dtype=

mugoori.tistory.com

 
 
 
 
 
from sklearn.preprocessing import MinMaxScaler
scaler_X = MinMaxScaler()
X = scaler_X.fit_transform(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)

# 데이터를 학습용과 테스트용으로 나눈다

 

 

 

 

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

# 텐서 플로우에 필요한 라이브러리를 임포트한다

 

 

 

 

 

model = Sequential() # 비어 있는 틀을 만듬
model.add( Dense(units=6,activation='relu',input_shape=(11,)   )      ) # 히든레이어를 만들어주는 작업 units : 레이어 , input_shape : 데이터 열의 갯수
model.add( Dense(units=8,activation= tf.nn.relu ) ) # 히든레이어의 activation은 통일해야 한다
model.add(Dense(units=1,activation='sigmoid'))

# 모델링을 해준다 먼저 비어있는 틀(Sequential())을 만들어준다

그 후 히든 레이어를 만들어준다 히든 레이어의 유닛이란 파라미터는 레이어의 갯수를 말한다

첫 히든 레이어만 인풋 쉐입을 적는다

인풋 쉐입은 데이터 프레임에 열을 말한다 히든레이어의 액티비션은 모두 통일해야한다

예시에서 쓴 relu 와 tf.nn.relu 는 같은거다

마지막으로 분류의 작업이므로 아웃풋을 시그모어로 만들어준다 (시그모어는 0과 1로만 나타내준다)

 

 

 

 

 

model.summary()
>>>
Model: "sequential_3"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 dense_6 (Dense)             (None, 6)                 72        
                                                                 
 dense_7 (Dense)             (None, 8)                 56        
                                                                 
 dense_8 (Dense)             (None, 1)                 9         
                                                                 
=================================================================
Total params: 137
Trainable params: 137
Non-trainable params: 0
_________________________________________________________________

# 서머리를 찍어본다 

파라미터는 선의 갯수이며 상수항이 1개씩 생기므로 레이어가 서머리에 찍히는거보다

실제로는 1개씩 더 늘어나서 파라미터가 늘어난것이다

 

 

 

 

 

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

옵티마이저에 대한 설명

# 모델링이 끝났다면 컴파일을 해준다

옵티마이저는 위 사진을 참조한다 로스는 로스펑션, 오차함수, 손실함수등으로 불린다

binary_crossentropy라는것은 두가지라는 것이다

매트릭스는 검증하는 방법인데 여기서는 분류하는것이므로 정확도 (accuracy)로 검증

 

 

 

 

 

model.fit(X_train,y_train,batch_size=10, epochs=20)
>>>
Epoch 1/20
800/800 [==============================] - 2s 2ms/step - loss: 0.5123 - accuracy: 0.7931
Epoch 2/20
800/800 [==============================] - 2s 2ms/step - loss: 0.4698 - accuracy: 0.7960
Epoch 3/20
800/800 [==============================] - 2s 2ms/step - loss: 0.4561 - accuracy: 0.7959
Epoch 4/20
800/800 [==============================] - 2s 2ms/step - loss: 0.4455 - accuracy: 0.8005
Epoch 5/20
800/800 [==============================] - 1s 2ms/step - loss: 0.4370 - accuracy: 0.8077
Epoch 6/20
800/800 [==============================] - 2s 2ms/step - loss: 0.4299 - accuracy: 0.8135
Epoch 7/20
800/800 [==============================] - 3s 4ms/step - loss: 0.4223 - accuracy: 0.8169
Epoch 8/20
800/800 [==============================] - 2s 2ms/step - loss: 0.4114 - accuracy: 0.8229
Epoch 9/20
800/800 [==============================] - 2s 2ms/step - loss: 0.3953 - accuracy: 0.8320
Epoch 10/20
800/800 [==============================] - 2s 2ms/step - loss: 0.3804 - accuracy: 0.8404
Epoch 11/20
800/800 [==============================] - 1s 2ms/step - loss: 0.3707 - accuracy: 0.8460
Epoch 12/20
800/800 [==============================] - 1s 2ms/step - loss: 0.3636 - accuracy: 0.8491
Epoch 13/20
800/800 [==============================] - 1s 2ms/step - loss: 0.3611 - accuracy: 0.8514
Epoch 14/20
800/800 [==============================] - 2s 2ms/step - loss: 0.3578 - accuracy: 0.8531
Epoch 15/20
800/800 [==============================] - 1s 2ms/step - loss: 0.3564 - accuracy: 0.8537
Epoch 16/20
800/800 [==============================] - 2s 2ms/step - loss: 0.3551 - accuracy: 0.8547
Epoch 17/20
800/800 [==============================] - 1s 2ms/step - loss: 0.3531 - accuracy: 0.8566
Epoch 18/20
800/800 [==============================] - 2s 2ms/step - loss: 0.3523 - accuracy: 0.8562
Epoch 19/20
800/800 [==============================] - 1s 2ms/step - loss: 0.3516 - accuracy: 0.8564
Epoch 20/20
800/800 [==============================] - 1s 2ms/step - loss: 0.3502 - accuracy: 0.8564
<keras.callbacks.History at 0x7fc201288ee0>

# 컴파일이 끝났다면 학습을 진행한다

Epoch 와 batch_size에 관한것은 이 글을 참고한다 : https://mugoori.tistory.com/122

학습시에 주의할점은 만약 재 학습을 하고 싶다면 모델링부터 다시해야한다

 

텐서플로우에서 학습시 epoch 와 batch_size에 대한 설명

model.fit(X_train,y_train,batch_size=10, epochs=20) >>> Epoch 1/20 800/800 [==============================] - 2s 2ms/step - loss: 0.5123 - accuracy: 0.7931 Epoch 2/20 800/800 [==============================] - 2s 2ms/step - loss: 0.4698 - accuracy: 0.7960

mugoori.tistory.com

 

 

 

 

model.evaluate(X_test,y_test)
>>> 63/63 [==============================] - 0s 2ms/step - loss: 0.3456 - accuracy: 0.8655
    [0.3456152081489563, 0.8654999732971191]

# 텐서 플로우의 평가는 evaluate 라는 함수를 사용한다

아까 나눠주었던 테스트 데이터를 넣어준다

로스펑션(loss) : 0.3456 에 정확도(accuracy) : 0.8655 가 나왔다

 

 

 

 

 

 

from sklearn.metrics import confusion_matrix, accuracy_score
y_pred = model.predict(X_test)
y_pred
>>> array([[0.27285683],
           [0.29254028],
           [0.18399401],
           ...,
           [0.13799249],
           [0.11607304],
           [0.1476748 ]], dtype=float32)
           
y_pred = (y_pred > 0.5).astype(int)
>>> array([[0],
           [0],
           [0],
           ...,
           [0],
           [0],
           [0]])

# 검증을 위한 컨퓨전 매트릭스를 사용하기위해 임포트 해준다

테스트 데이터를 y_pred에 저장해주고

이것을 y_test 데이터와 비교하기위해서

0과 1로 이루어진 데이터로 바꿔준다

 

 

 

 

 

cm = confusion_matrix(y_test,y_pred)
cm
>>> array([[1557,   38],
           [ 231,  174]])
           
accuracy_score(y_test,y_pred)
>>> 0.8655

# 컨퓨전 매트릭스를 사용해본다

실제값이 0일때 예측값이 0인 것 1557

실제값이 0일때 예측값이 1인 것 38 (오차)

실제값이 1일때 예측값이 0인 것 231(오차)

실제값이 1일때 예측값이 1인것 174

accuracy_score를 사용해보니 위에서와 같은 0.8655의 정확도가 나온다