ML (MachineLearning)

๋”ฅ๋Ÿฌ๋‹ : Neural Networks ์œผ๋กœ Classification(๋ถ„๋ฅ˜) ํ•˜๊ธฐ

567Rabbit 2024. 4. 16. 17:10

๋”ฅ๋Ÿฌ๋‹์€ ์ด๋ฏธ์ง€ ์ธ์‹, ์ž์—ฐ์–ด ์ฒ˜๋ฆฌ, ์Œ์„ฑ ์ธ์‹ ๋“ฑ ๋‹ค์–‘ํ•œ ์˜์—ญ์—์„œ ๋งค์šฐ ์„ฑ๊ณต์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋‹ค.

 

๋”ฅ๋Ÿฌ๋‹์€ ํžˆ๋“ ๋ ˆ์ด์–ด๊ฐ€ ๋งŽ๋‹ค๋Š” ๊ฒƒ์ด ํŠน์ง•์ด๋‹ค

- ๋”ฅ๋Ÿฌ๋‹์—์„œ "ํžˆ๋“  ๋ ˆ์ด์–ด"๋Š” ์ž…๋ ฅ์ธต(input layer)๊ณผ ์ถœ๋ ฅ์ธต(output layer) ์‚ฌ์ด์— ์žˆ๋Š” ์ค‘๊ฐ„ ๋ ˆ์ด์–ด๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค. ํžˆ๋“  ๋ ˆ์ด์–ด๊ฐ€ ๋งŽ์„์ˆ˜๋ก, ๋ชจ๋ธ์€ ๋” ๋ณต์žกํ•œ ํŒจํ„ด์ด๋‚˜ ๊ด€๊ณ„๋ฅผ ํ•™์Šตํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. ์ด๋Š” ์ž…๋ ฅ๊ณผ ์ถœ๋ ฅ ๊ฐ„์˜ ๋ณต์žกํ•œ ๋น„์„ ํ˜• ๊ด€๊ณ„๋ฅผ ๋ชจ๋ธ๋งํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

- ๋” ๋งŽ์€ ํžˆ๋“  ๋ ˆ์ด์–ด๋ฅผ ๊ฐ€์ง„ ์‹ ๊ฒฝ๋ง์€ ๋” ๋งŽ์€ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ€์ง€๊ธฐ ๋•Œ๋ฌธ์—, ๋” ๋งŽ์€ ๋ฐ์ดํ„ฐ์™€ ์—ฐ์‚ฐ ๋ฆฌ์†Œ์Šค๋ฅผ ํ•„์š”๋กœ ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ถฉ๋ถ„ํ•œ ๋ฐ์ดํ„ฐ์™€ ๋ฆฌ์†Œ์Šค๊ฐ€ ์ œ๊ณต๋œ๋‹ค๋ฉด, ๊นŠ์€ ์‹ ๊ฒฝ๋ง์€ ๋งค์šฐ ๋ณต์žกํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ํšจ๊ณผ์ ์ผ ์ˆ˜ ์žˆ๋‹ค.

 

 
 
 
 

๊ธˆ์œต์ƒํ’ˆ ๊ฐฑ์‹ (0 ๋˜๋Š” 1) ์—ฌ๋ถ€ ์˜ˆ์ธกํ•˜๋Š” ANN ๋งŒ๋“ค๊ธฐ

 

Churn_Modelling.csv ํŒŒ์ผ์„ ๋ณด๋ฉด, ๊ณ ๊ฐ ์ •๋ณด์™€ ํ•ด๋‹น ๊ณ ๊ฐ์ด ๊ธˆ์œต์ƒํ’ˆ์„ ๊ฐฑ์‹ ํ–ˆ๋Š”์ง€ ์•ˆํ–ˆ๋Š”์ง€์˜ ์—ฌ๋ถ€์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋‹ค. ์ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ๊ฐฑ์‹ ์—ฌ๋ถ€๋ฅผ ์˜ˆ์ธกํ•˜๋Š” ๋”ฅ๋Ÿฌ๋‹์„ ๊ตฌ์„ฑํ•˜์‹œ์˜ค.

 

 

df

 

 

 

nan๊ฐ’ ์ •๋ฆฌํ•˜๊ธฐ

 

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

 

 

 

 

ํŠน์„ฑ์—ด๊ณผ ๋Œ€์ƒ์—ด๋กœ ๋‚˜๋ˆ„๊ธฐ

 

ํŠน์„ฑ ์—ด(X)์€ ๋ฐ์ดํ„ฐ์…‹์—์„œ ๊ฐ๊ฐ์˜ ๊ด€์ธก์น˜์— ๋Œ€ํ•œ ์„ค๋ช…๋ณ€์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค
๋Œ€์ƒ ์—ด(y)์€ ์˜ˆ์ธกํ•˜๋ ค๋Š” ๊ฐ’์ด ํฌํ•จ๋œ ์—ด์ด๋‹ค

 

y = df['Exited']

 

X = df.loc[: , 'CreditScore':'EstimatedSalary' ]

 

X

 

 

 

 

๋ฌธ์ž์—ด์„ ์ˆซ์ž์—ด๋กœ ๋ฐ”๊พธ๊ธฐ

 

X['Geography'].nunique() # ์›ํ•ซ ์ธ์ฝ”๋”ฉ

3

 

X['Gender'].nunique() # ๋ ˆ์ด๋ธ” ์ธ์ฝ”๋”ฉ

2

 

from sklearn.preprocessing import OneHotEncoder, LabelEncoder

from sklearn.compose import ColumnTransformer

 

 

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

 

 

 

sorted(X['Geography'].unique())

['France', 'Germany', 'Spain']

 

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

 

 

 

 

Dummy Variable Trap (๋”๋ฏธ)

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

 

์„ฑ๋Šฅ์„ ์œ„ํ•ด์„œ ํ•˜๋‚˜์˜ ์ปฌ๋Ÿผ์„ ์‚ญ์ œํ•˜๋Š” ๊ฒƒ์ด๋‹ค
์› ํ•ซ ์ธ์ฝ”๋”ฉํ•œ ๊ฒฐ๊ณผ์—์„œ, ๊ฐ€์žฅ ์™ผ์ชฝ์˜ ์ปฌ๋Ÿผ์€ ์‚ญ์ œํ•ด๋„ ๋ฐ์ดํ„ฐ๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ฐ๋Š” ์•„๋ฌด ๋ฌธ์ œ ์—†๋‹ค.


     'France', 'Germany', 'Spain' 
          1          0         0
          0          1         0
          0          0         1

 

๋งจ ์™ผ์ชฝ France ์ปฌ๋Ÿผ์„ ์‚ญ์ œํ•ด๋„,
0   0 => France
1   0 => Germany
0   1 => Spain

 

์•„๋ฌด ๋ฌธ์ œ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค

 

 

 

 

 

 

ํ”ผ์ณ์Šค์ผ€์ผ๋ง

 

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

 

 

 

 

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)

 

 

 

 

 

๋ชจ๋ธ๋ง (ANN)

import tensorflow as tf
from tensorflow import keras
from keras.models import Sequential
from keras.layers import Dense   # Dense๋Š” ์™„์ „ ์—ฐ๊ฒฐ ์ธต์„ ์˜๋ฏธํ•œ๋‹ค

 

 

model = Sequential()    # Sequential ์ธ๊ณต์ง€๋Šฅ(API)์„ ์‚ฌ์šฉํ•˜์—ฌ ์ˆœ์ฐจ์ ์œผ๋กœ ์ธต์„ ์Œ“์•„๊ฐ„๋‹ค

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

# ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๋Š” ์ธต.  11๊ฐœ์˜ ์ž…๋ ฅ ํŠน์„ฑ์„ ๋ฐ›์•„ 8๊ฐœ์˜ ๋‰ด๋Ÿฐ์œผ๋กœ ์—ฐ๊ฒฐ๋œ๋‹ค. ํžˆ๋“ ๋ ˆ์ด์–ด์˜ ํ™œ์„ฑํ™” ํ•จ์ˆ˜๋Š” ReLU๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค

 

model.add( Dense(6, 'relu') )   

์€๋‹‰์ธต. ์ž…๋ ฅ ํŠน์„ฑ์„ ๋ฐ›์•„๋“ค์ด๊ณ  6๊ฐœ์˜ ๋‰ด๋Ÿฐ์„ ๊ฐ€์ง€๋ฉฐ, ํžˆ๋“ ๋ ˆ์ด์–ด์˜ ํ™œ์„ฑํ™” ํ•จ์ˆ˜๋Š” ReLU๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค

 

model.add( Dense(1, 'sigmoid') ) 

์ถœ๋ ฅ์ธต. ํ•˜๋‚˜์˜ ๋‰ด๋Ÿฐ์„ ๊ฐ€์ง€๋ฉฐ, ํ™œ์„ฑํ™” ํ•จ์ˆ˜๋กœ๋Š” ์‹œ๊ทธ๋ชจ์ด๋“œ(Sigmoid) ํ•จ์ˆ˜๊ฐ€ ์‚ฌ์šฉ๋œ๋‹ค. ์ด๋Š” ์ด์ง„ ๋ถ„๋ฅ˜ ๋ฌธ์ œ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜๋กœ, ์ถœ๋ ฅ๊ฐ’์„ 0๊ณผ 1 ์‚ฌ์ด์˜ ํ™•๋ฅ  ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜์‹œ์ผœ์ค€๋‹ค.

 

 

 

 

 

 

model.summary()     # ๋ชจ๋ธ์˜ ๊ตฌ์กฐ๋ฅผ ์š”์•ฝํ•˜์—ฌ ๋ณด์—ฌ์ฃผ๋Š” ํ•จ์ˆ˜

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense (Dense)                (None, 8)                 96        
_________________________________________________________________
dense_1 (Dense)              (None, 6)                 54        
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 7         
=================================================================
Total params: 157
Trainable params: 157
Non-trainable params: 0
_________________________________________________________________

 

์š”์•ฝ์„ ํ†ตํ•ด ๊ฐ ์ธต์˜ ๊ตฌ์„ฑ๊ณผ ์ถœ๋ ฅ ํ˜•ํƒœ, ํŒŒ๋ผ๋ฏธํ„ฐ ์ˆ˜๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค

Param #๋Š” ํ•ด๋‹น ์ธต์˜ ๊ฐ€์ค‘์น˜(weight)์™€ ํŽธํ–ฅ(bias)์„ ๋‚˜ํƒ€๋‚ด๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ ์ˆ˜๋ฅผ ์˜๋ฏธํ•œ๋‹ค

 

 

 

 

 

 

์ปดํŒŒ์ผ(Compile)


์ปดํŒŒ์ผ์€

 

1. ์˜ตํ‹ฐ๋งˆ์ด์ €(optimizer)     # ์˜ค์ฐจ๋ฅผ ์ค„์ด๋Š” ๊ฐ€์žฅ ๋น ๋ฅด๊ณ  ํšจ์œจ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ตœ์ (์ตœ์ €๋น„์šฉ)์˜ ์ฒ˜๋ฆฌ๊ฒฝ๋กœ๋ฅผ ์ƒ์„ฑํ•ด์ค€๋‹ค

2. ๋กœ์ŠคํŽ‘์…˜(loss function ์˜ค์ฐจํ•จ์ˆ˜, ์†์‹คํ•จ์ˆ˜) ์…‹ํŒ…   

  - 2๊ฐœ๋กœ ๋ถ„๋ฅ˜ํ•˜๋Š” ๋ฌธ์ œ์˜ loss๋Š” 'binary_crossentropy'๋กœ ์„ค์ •

  - ex ) ๋งŒ์•ฝ mse๋กœ ์„ค์ •ํ•˜๋ฉด ๋ชจ๋ธ์ด ํ›ˆ๋ จ๋  ๋•Œ MSE๋ฅผ ์ตœ์†Œํ™”ํ•˜๋„๋ก ํ•™์Šต๋œ๋‹ค

3. ๊ฒ€์ฆ๋ฐฉ๋ฒ• ์…‹ํŒ…

 

์ˆœ์„œ๋กœ ์ง„ํ–‰ํ•œ๋‹ค

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

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

 

๋”ฅ๋Ÿฌ๋‹์—์„œ "์—ํฌํฌ(epochs)"๋ž€ ํ•œ ๋ฒˆ์˜ ํ•™์Šต ๊ณผ์ •์—์„œ ์ „์ฒด ๋ฐ์ดํ„ฐ์…‹์ด ๋ชจ๋ธ์— ๋Œ€ํ•ด ํ•œ ๋ฒˆ ํ†ต๊ณผํ•˜๋Š” ํšŸ์ˆ˜๋ฅผ ๋งํ•œ๋‹ค

์ฆ‰, ์—ํฌํฌ๋ž€ ๋ชจ๋ธ์ด ํ›ˆ๋ จ ๋ฐ์ดํ„ฐ์…‹ ์ „์ฒด๋ฅผ ๋ช‡ ๋ฒˆ์ด๋‚˜ ๋ฐ˜๋ณตํ•ด์„œ ํ•™์Šตํ•˜๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ง€ํ‘œ๋ฅผ ๋œปํ•œ๋‹ค

 

 

 

 

๊ฒ€์‚ฌ(Test) ํ•˜๊ธฐ

 

model.evaluate(X_test, y_test)

63/63 [==============================] - 0s 2ms/step - loss: 0.3386 - accuracy: 0.8570
[0.3385504186153412, 0.8569999933242798]

 

 

 

# confusion matrix๋กœ ํ™•์ธํ•˜๊ธฐ

from sklearn.metrics import confusion_matrix, accuracy_score
y_pred = model.predict(X_test)
y_pred = (y_pred > 0.5)
cm = confusion_matrix(y_test, y_pred)
print(cm)
63/63 [==============================] - 0s 1ms/step

[[1496 99]
[ 187 218]]

 

(1496 + 218) / cm.sum()    #์ •ํ™•๋„

0.857

 

accuracy_score(y_test, y_pred)  #์ •ํ™•๋„

0.857

 

 

 

 

 

์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ ์ž…๋ ฅ๋ฐ›์•˜์„ ๋•Œ

 

new_data2 = [{'CreditScore': 600,'Geography':'France','Gender':'Male', 'Age':40, 'Tenure':3, 'Balance':60000, 'NumOfProducts':2,'HasCrCard': 1, 'IsActiveMember':1, 'EstimatedSalary':50000}]

# ์ด๋ ‡๊ฒŒ [{ํ‚ค-๊ฐ’}]์Œ์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ๊ฒƒ์„ JSON๋ฐ์ดํ„ฐ ํ˜•ํƒœ๋ผ๊ณ  ํ•œ๋‹ค
# JSON(JavaScript Object Notation)์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ์ „์†กํ•˜๊ธฐ ์œ„ํ•œ ๊ฒฝ๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ ํ˜•์‹์ด๋‹ค.
# JSON ๋ฐ์ดํ„ฐ์—์„œ ๊ฐ์ฒด๋Š” ์ค‘๊ด„ํ˜ธ({})๋กœ ํ‘œ์‹œ๋˜๋ฉฐ, ๋ฐฐ์—ด์€ ๋Œ€๊ด„ํ˜ธ([])๋กœ ํ‘œ์‹œ๋œ๋‹ค

 

new_data = pd.DataFrame(new_data2)

 

#๋ผ๋ฒจ์ธ์ฝ”๋”ฉ ํ•ด์ฃผ๊ธฐ

new_data['Gender'] = le.transform(new_data['Gender'])

 

#์›ํ•ซ์ธ์ฝ”๋”ฉ ํ•ด์ฃผ๊ธฐ

new_data = ct.transform(new_data)

 

#๋”๋ฏธ (์›ํ•ซ์ธ์ฝ”๋”ฉ์—์„œ ์ฒซ๋ฒˆ์งธ ์—ด ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ)

new_data = pd.DataFrame(new_data).drop(0, axis=1).values

 

#ํ”ผ์ฒ˜์Šค์ผ€์ผ๋ง

new_data = sc.transform(new_data)

 

#์˜ˆ์ธกํ•˜๊ธฐ

y_pred = model.predict(new_data2)

(y_pred > 0.5).astype(int)

array([[0]])

 

๊ฒฐ๊ณผ : ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ์˜ ๊ณ ๊ฐ์€ ๊ฐฑ์‹ ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค.