on my way

금융공학6: ANN 기초부터 TensorFlow를 활용한 심층 신경망 구현까지 본문

etc

금융공학6: ANN 기초부터 TensorFlow를 활용한 심층 신경망 구현까지

wingbeat 2024. 8. 17. 00:00
반응형

1. ANN from Scratch

이제 우리가 간단한 인공 신경망(ANN)을 만들어보자. 우리가 할 일은 데이터를 이용해 모델을 학습시키고, 그 모델을 사용해 새로운 데이터를 예측하는 것이다.

1.1 라이브러리 불러오기

import numpy as np
  • 여기서는 numpy라는 라이브러리를 사용한다. numpy는 숫자 계산을 도와주는 도구이다.

1.2 데이터 정의

# 독립 변수 (입력 데이터)
input_set = np.array([[0,1,0],
                      [0,0,1],
                      [1,0,0],
                      [1,1,0],
                      [1,1,1],
                      [0,1,1],
                      [0,1,0]])

# 종속 변수 (출력 데이터)
labels = np.array([[1],
                   [0],
                   [0],
                   [1],
                   [1],
                   [0],
                   [1]])
  • input_set은 입력 데이터이고, labels는 우리가 예측하고자 하는 출력 데이터이다.

1.3 파라미터 설정

np.random.seed(42)
weights = np.random.rand(3,1)
bias = np.random.rand(1)
lr = 0.05 # 학습률
  • weights는 가중치이고, bias는 편향이다. 이 두 가지는 모델이 학습하면서 조정하는 값들이다.
  • lr은 학습률로, 모델이 얼마나 빠르게 학습할지를 결정하는 값이다.

Sigmoid 함수 그래프

  • 이 그래프는 머신러닝에서 많이 사용하는 활성화 함수 중 하나인 시그모이드 함수의 형태를 보여줍니다.
  • 시그모이드 함수는 어떤 입력 값 zz를 받아서 0과 1 사이의 값으로 변 환해줍니다.
  • 수식:

    이 함수는 신경망에서 뉴런이 활성화될 확률을 결정할 때 많이 사용됩니다.

평균 제곱 오차 (Mean Squared Error, MSE)

  • 평균 제곱 오차는 예측 값과 실제 값 간의 차이를 제곱하여 평균을 낸 값을 의미합니다.
  • 수식:
    n 은 데이터의 개수,  Yi​^​ 는 예측 값,  Yi​ 는 실제 값입니다.
    이 값을 통해 모델의 예측이 실제 값과 얼마나 가까운지를 알 수 있습니다

 

경사 하강법 (Gradient Descent)

  • 이 그림은 경사 하강법을 통한 가중치 업데이트 과정을 보여줍니다.
  • 경사 하강법은 비용 함수의 최솟값을 찾기 위해 반복적으로 가중치를 업데이트하는 최적화 알고리즘입니다.
  • 가중치 업데이트 공식
    α는 학습률, (∂Error/∂Wx)​는 가중치에 대한 오류의 기울기

1.4 활성화 함수 정의

# 활성화 함수
def sigmoid(x):
    return 1/(1+np.exp(-x))

# 시그모이드 함수의 미분
def sigmoid_derivative(x):
    return sigmoid(x)*(1-sigmoid(x))
  • sigmoid 함수는 출력값을 0과 1 사이로 만들어주는 함수이다.
  • sigmoid_derivative 함수는 시그모이드 함수의 미분값을 구해준다. 이는 역전파(Backpropagation)에 필요하다.

1.5 모델 학습

# 2000번의 학습을 반복
for epoch in range(2000):
    inputs = input_set
    # 순전파
    XW = np.dot(inputs, weights) + bias
    z = sigmoid(XW)
    
    # 오차 계산
    error = z - labels
    print(error.sum())

    # 역전파
    dcost = error
    dpred = sigmoid_derivative(z)
    z_del = dcost * dpred
    inputs = input_set.T
    
    # 가중치 조정
    weights = weights - lr * np.dot(inputs, z_del)
    for num in z_del:
        bias = bias - lr * num
  • 모델이 2000번 반복해서 학습한다.
  • 순전파(Forward Propagation): 입력 데이터를 이용해 예측값을 계산한다.
  • 오차 계산: 예측값과 실제값의 차이를 구한다.
  • 역전파(Backpropagation): 오차를 줄이기 위해 가중치와 편향을 조정한다.

1.6 예측

# 예측
single_pt = np.array([0,1,0])
result = sigmoid(np.dot(single_pt, weights) + bias)
print(result)
  • 새로운 데이터 single_pt를 입력해서 예측값을 구한다.


2. TensorFlow로 ANN 연습

인공신경망(Artificial Neural Network, ANN)은 뇌의 뉴런을 본떠 만든 기계 학습 모델입니다. ANN은 여러 층(layer)으로 구성된 노드(node)를 통해 데이터의 패턴을 학습합니다. 여기서, 노드는 뇌의 뉴런과 비슷한 역할을 하고, 층은 데이터가 처리되는 단계라고 생각하면 됩니다. ANN은 이미지 인식, 음성 인식, 자연어 처리 등 다양한 분야에서 사용됩니다.

 

이번에는 TensorFlow를 이용해 ANN을 만들어보자. TensorFlow는 딥러닝을 쉽게 구현할 수 있게 도와주는 도구이다.

2.1 라이브러리 불러오기

import pandas as pd  # 데이터 처리를 위한 라이브러리
import numpy as np  # 수치 연산을 위한 라이브러리
import tensorflow as tf  # 딥러닝을 위한 라이브러리

from sklearn.model_selection import train_test_split  # 데이터셋을 나누기 위한 함수
from sklearn.preprocessing import MinMaxScaler  # 데이터 스케일링을 위한 함수
from tensorflow.keras.utils import to_categorical  # 원핫 인코딩을 위한 함수
  • tensorflow, pandas, numpy와 같은 라이브러리를 불러온다.
  • train_test_split은 데이터를 훈련용과 테스트용으로 나눌 때 사용한다.
  • MinMaxScaler는 데이터를 0과 1 사이의 값으로 변환해준다.
  • to_categorical은 종속 변수를 원-핫 인코딩해준다.

2.2 데이터 전처리

# 1) 데이터 읽기
df = pd.read_csv("creditset2.csv")

# 2) 변수 선택 (특징 X)
x = df[['income', 'age', 'loan']]  # 'income', 'age', 'loan' 컬럼 선택

# 3) 타겟 변수 선택 (y) 및 원핫 인코딩
y = to_categorical(df[['default10yr']])  # 'default10yr' 컬럼을 원핫 인코딩

# 4) 데이터셋을 학습용(train)과 테스트용(test)으로 나누기 (8:2 비율)
train_x, test_x, train_y, test_y = train_test_split(x, y, test_size=0.2, random_state=42)

# 5) 학습용과 테스트용 데이터의 스케일링
scaler = MinMaxScaler()  # MinMaxScaler 객체 생성
train_x = scaler.fit_transform(train_x)  # 학습용 데이터를 스케일링
test_x = scaler.transform(test_x)  # 테스트용 데이터를 스케일링
  • 데이터를 불러와서 훈련용과 테스트용으로 나눈다.
  • income, age, loan 컬럼을 독립 변수로, default10yr 컬럼을 종속 변수로 사용한다.
  • 데이터를 0과 1 사이의 값으로 변환한다.

2.3 모델링 및 학습

#DNN
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

#Hidden layer 구성하기
model = Sequential()
model.add(Dense(3, activation = 'relu', input_shape = (3, ))) #첫번째 은닉층, 3개입력->2개 은닉층 노드, Desnse: 일반적인 은닉층, Fully connected hidden layer
model.add(Dense(6, activation = 'relu')) #두번째 은닉층, 2개입력->6개 은닉층 노드, Desnse: 일반적인 은닉층, Fully connected hidden layer
model.add(Dense(2, activation = 'softmax')) #Desnse: 마지막 은닉층, Fully connected hidden layer, 분류의 경우 softmax

#모형 컴파일
model.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['acc']) #분류모형은 이대로 사용하기
model.summary()

#모형 학습 및 가중치 확인
model.fit(train_x,train_y,epochs = 20)  #epoch수를 조정

 

  • Sequential 모델을 이용해 ANN을 만든다.
  • Dense 레이어를 이용해 은닉층과 출력층을 구성한다.
  • adam 옵티마이저와 categorical_crossentropy 손실 함수를 사용해 모델을 컴파일한다.
  • 모델을 학습시킨다.

np.argmax 예제

np.argmax 함수는 배열에서 가장 큰 값의 인덱스를 반환합니다.

# np.argmax를 사용한 예제
print(np.argmax([1, 10, 100]))  # 배열에서 가장 큰 값(100)의 인덱스(2)를 반환

# 2x3 행렬 생성 후 값 10 더하기
a = np.arange(6).reshape(2, 3) + 10
print(a)
# 출력:
# [[10 11 12]
#  [13 14 15]]

# 각 열에서 가장 큰 값의 인덱스 반환
print(np.argmax(a, axis=0))
# 출력: [1 1 1] - 각 열에서 가장 큰 값이 있는 행의 인덱스

# 각 행에서 가장 큰 값의 인덱스 반환
print(np.argmax(a, axis=1))
# 출력: [2 2] - 각 행에서 가장 큰 값이 있는 열의 인덱스

  • np.argmax([1, 10, 100]): 주어진 배열에서 가장 큰 값(100)의 인덱스(2)를 반환합니다.
  • a = np.arange(6).reshape(2, 3) + 10: 2x3 행렬을 생성하고 각 값에 10을 더합니다.
  • np.argmax(a, axis=0): 각 열에서 가장 큰 값의 인덱스를 반환합니다.
  • np.argmax(a, axis=1): 각 행에서 가장 큰 값의 인덱스를 반환합니다.


2.4 결과 확인 및 평가

  • 테스트 데이터를 이용해 모델의 예측값을 구한다.
  • 예측값과 실제값을 비교해 정확도를 계산한다.

모델 예측 및 평가

이 부분은 학습된 모델을 사용해 테스트 데이터를 예측하고, 그 결과를 평가하는 과정입니다.

# 예측 수행
predicted = model.predict(test_x)  # 테스트 데이터에 대한 예측 수행
predicted2 = np.argmax(predicted, axis=-1)  # 예측 값 중 가장 큰 값을 갖는 인덱스 반환
actual = np.argmax(test_y, axis=-1)  # 실제 값 중 가장 큰 값을 갖는 인덱스 반환

# 정확도 계산
print("Accuracy:", np.mean(predicted2 == actual))
# 예측 값(predicted2)과 실제 값(actual)이 일치하는 비율을 계산하여 정확도 출력

# 모델 요약 및 가중치 확인
model.summary()  # 모델의 구조를 요약해서 보여줌
print(model.get_weights())  # 모델의 가중치(학습된 값) 출력

 

  • model.predict(test_x): 테스트 데이터를 사용하여 모델이 예측한 결과를 반환합니다.
  • np.argmax(predicted, axis=-1): 예측 결과에서 가장 큰 값의 인덱스를 반환하여 예측된 클래스(label)를 얻습니다.
  • np.argmax(test_y, axis=-1): 실제 결과에서 가장 큰 값의 인덱스를 반환하여 실제 클래스(label)를 얻습니다.
  • np.mean(predicted2 == actual): 예측된 클래스와 실제 클래스가 일치하는 비율을 계산하여 정확도를 출력합니다.
  • model.summary(): 모델의 구조(레이어 구성, 파라미터 수 등)를 요약하여 출력합니다.
  • model.get_weights(): 학습된 가중치 값을 출력합니다.

 

 

 

분류 보고서 출력

모델의 예측 성능을 자세히 평가하기 위해 분류 보고서를 생성합니다.

from sklearn.metrics import classification_report, confusion_matrix

# 분류 보고서 출력
print('\n', classification_report(actual, predicted2))
# classification_report 함수는 precision, recall, f1-score, support를 포함한 자세한 성능 지표를 출력

 

  • classification_report(actual, predicted2): 실제 값과 예측 값을 비교하여 precision, recall, f1-score, support 등을 포함한 성능 지표를 출력합니다.
  • precision: 모델이 True라고 예측한 것 중 실제로 True인 비율.
  • recall: 실제 True인 것 중 모델이 True라고 예측한 비율.
  • f1-score: precision과 recall의 조화 평균.
  • support: 각 클래스의 실제 샘플 수.

 

 


3. MNIST 데이터셋에 대한 DNN

이번에는 MNIST 데이터셋을 이용해 딥러닝 모델을 만들어보자. MNIST 데이터셋은 손글씨 숫자 이미지 데이터이다.

3.1 라이브러리 불러오기

import tensorflow as tf
import numpy as np
  • tensorflow와 numpy 라이브러리를 불러온다.

3.2 MNIST 데이터셋 로드

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()

손글씨 숫자 데이터셋을 불러옵니다. x_train과 y_train은 훈련 데이터와 레이블, x_test와 y_test는 테스트 데이터와 레이블입니다.

데이터 시각화 

import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (5, 5)
plt.imshow(x_train[0])
plt.show()

첫 번째 훈련 이미지를 화면에 표시합니다.

손글씨 숫자 이미지가 어떻게 생겼는지 볼 수 있습니다.

데이터 전처리

# 데이터 형태 변환 및 정규화
x_train = x_train.reshape((60000, 28 * 28)) / 255.0
x_test = x_test.reshape((10000, 28 * 28)) / 255.0

y_train = tf.keras.utils.to_categorical(y_train, 10)
y_test = tf.keras.utils.to_categorical(y_test, 10)
  • 데이터를 2차원 배열로 변환하고, 0과 1 사이의 값으로 스케일링한다.( 이미지를 2차원 배열에서 1차원 배열로 바꾸고, 픽셀 값을 0에서 1 사이로 정규화합니다.)
  • 종속 변수를 원-핫 인코딩한다. 예를 들어, 숫자 3은 [0, 0, 0, 1, 0, 0, 0, 0, 0, 0]로 변환됩니다.

3.3 모델링 및 학습

신경망 모델 구성

# Sequential 모델 생성
model = tf.keras.models.Sequential()

# 은닉층 추가
model.add(tf.keras.layers.Dense(units=128, activation='relu', input_shape=(28*28,)))
model.add(tf.keras.layers.Dense(units=64, activation='relu'))
model.add(tf.keras.layers.Dense(units=32, activation='relu'))
model.add(tf.keras.layers.Dense(units=16, activation='relu'))
model.add(tf.keras.layers.Dense(units=10, activation='softmax'))
  • Sequential 모델을 이용해 DNN을 만든다.
  • 여러 개의 Dense 레이어를 추가해 은닉층을 구성한다.
  • 신경망 모델을 구성합니다. Dense 레이어는 완전히 연결된 레이어를 의미하며, activation='relu'는 활성화 함수로 렐루 함수를 사용합니다. 마지막 레이어는 클래스 확률을 나타내기 위해 softmax를 사용합니다.

모델 요약, 컴파일, 학습, 저장

# 모델 요약
model.summary()

# 모델 컴파일
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# model.compile(optimizer=keras.optimizers.Adam(learning_rate=0.01), loss=keras.losses.categorical_crossentropy)

# 모델 학습
model.fit(x_train, y_train, epochs=5, verbose=1, validation_split=0.2)

# 모델 평가
model.evaluate(x_test, y_test)

# 모델 저장 및 불러오기
model.save('mnist_dnn_model.h5')
new_model = tf.keras.models.load_model('mnist_dnn_model.h5')
new_model.summary()
  • 모델을 컴파일합니다. 옵티마이저는 adam을 사용하고, 손실 함수는 categorical_crossentropy, 평가 지표는 accuracy를 사용합니다.
  • 모델을 훈련 데이터로 학습시킵니다. epochs=5는 데이터를 5번 반복해서 학습한다는 의미이고, validation_split=0.2는 훈련 데이터의 20%를 검증 데이터로 사용합니다.
  • 테스트 데이터로 모델을 평가합니다. 손실 값과 정확도를 출력합니다.

3.4 예측 수행 및 시각화

preds = model.predict(x_test, batch_size=128)
np.argmax(preds[0])
plt.imshow(x_test[0].reshape(28, 28))
plt.show()
  • 테스트 데이터를 이용해 모델의 성능을 평가한다.
  • 첫 번째 테스트 데이터를 시각화하고, 예측값을 출력한다.

 

이와 같이, MNIST 데이터셋을 사용하여 신경망 모델을 구성하고, 학습시키고, 평가하는 과정을 쉽게 설명해드렸습니다. 각 단계는 데이터의 준비부터 모델의 평가까지를 포함하고 있습니다.


4. 데이터에 대한 DL 적용

여기서는 데이터 파일 data.csv를 읽어와서 딥러닝 모델을 적용하는 방법을 단계별로 설명합니다.

1. 데이터 읽기 및 전처리

먼저 데이터 파일을 읽고, 데이터를 훈련 데이터와 테스트 데이터로 나눕니다. 그런 다음 데이터를 스케일링하여 값의 범위를 0과 1 사이로 맞춥니다.

import pandas as pd
data = pd.read_csv("data.csv")
print(data.columns)

데이터 파일을 읽고, 열 이름을 출력합니다. 이 파일에는 여러 가지 특성(피처)들이 있고, 마지막 열은 'Pass.Fail'이라는 타겟(목표) 값입니다.

from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split

# 타겟 변수를 제외한 나머지 데이터를 X에 저장
X_train, X_test, y_train, y_test = train_test_split(data.drop('Pass.Fail', axis=1), data["Pass.Fail"], test_size=0.2)

# 데이터 스케일링
scaler = MinMaxScaler()
X_train = pd.DataFrame(scaler.fit_transform(X_train), columns=X_train.columns)
X_test = pd.DataFrame(scaler.fit_transform(X_test), columns=X_test.columns)

데이터를 80%는 훈련 데이터로, 20%는 테스트 데이터로 나눕니다. MinMaxScaler를 사용하여 모든 피처의 값을 0과 1 사이로 변환합니다.

2. 타겟 변수를 원-핫 인코딩

import tensorflow as tf
y_train = tf.keras.utils.to_categorical(y_train, 2)
y_test = tf.keras.utils.to_categorical(y_test, 2)

y_train.shape

타겟 변수인 Pass.Fail을 원-핫 인코딩합니다. 원-핫 인코딩은 타겟 값을 0과 1로 변환하는 것을 의미합니다.

3. 모델 정의하기

from keras.models import Sequential
from keras.layers import Dense, Dropout

model = Sequential()
model.add(Dense(32, activation='relu', input_shape=(48,)))
model.add(Dense(16, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(2, activation='softmax'))

딥러닝 모델을 정의합니다. 여기서는 4개의 Dense(밀집) 레이어를 사용했습니다. 첫 번째 레이어는 입력 데이터가 48개의 피처를 가지고, 32개의 노드로 구성되어 있습니다. 각 레이어는 ReLU 활성화 함수를 사용합니다. 마지막 레이어는 분류 문제를 해결하기 위해 Softmax 활성화 함수를 사용합니다.

4. 모델 컴파일하기

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

모델을 컴파일합니다. 손실 함수는 categorical_crossentropy를 사용하고, 옵티마이저는 adam을 사용합니다. 모델의 성능을 평가하기 위해 정확도를 사용합니다.

5. 모델 학습하기

hist = model.fit(X_train, y_train, batch_size=32, epochs=20, verbose=1, validation_split=0.1)

모델을 학습시킵니다. 배치 크기는 32이고, 에포크는 20으로 설정했습니다. 데이터의 10%는 검증 데이터로 사용합니다.

6. 모델 평가하기

score = model.evaluate(X_test, y_test, verbose=1)
print('정답률=', score[1], 'loss=', score[0])

테스트 데이터로 모델을 평가합니다. 정확도와 손실 값을 출력합니다.

7. 예측 및 평가

from sklearn.metrics import classification_report
import numpy as np

pred = np.argmax(model.predict(X_test), axis=1)
y_test = np.argmax(y_test, axis=1)
print(classification_report(y_test, pred))

테스트 데이터에 대해 예측을 수행하고, 예측 결과를 평가합니다. classification_report를 사용하여 정확도, 정밀도, 재현율, F1 점수를 출력합니다.

8. 학습 상태 시각화

import matplotlib.pyplot as plt

plt.plot(hist.history['accuracy'])
plt.plot(hist.history['val_accuracy'])
plt.title('Accuracy')
plt.legend(['train', 'test'], loc='upper left')
plt.show()

plt.plot(hist.history['loss'])
plt.plot(hist.history['val_loss'])
plt.title('Loss')
plt.legend(['train', 'val'], loc='upper left')
plt.show()

학습 과정에서의 정확도와 손실 값을 시각화합니다. 이를 통해 학습 과정에서 모델의 성능이 어떻게 변했는지 확인할 수 있습니다.

이와 같이, 데이터 전처리부터 딥러닝 모델 학습, 평가, 시각화까지의 전체 과정을 초등학생도 이해할 수 있도록 설명했습니다. 각 단계의 코드를 실행하면서 모델의 성능을 확인하고, 시각화를 통해 결과를 쉽게 이해할 수 있습니다.

 

정확도(Accuracy) 그래프

  • 이 그래프는 학습 과정에서의 정확도(Accuracy)의 변화를 보여줍니다.
  • 파란색 선은 훈련 데이터(train)의 정확도를, 주황색 선은 검증 데이터(val)의 정확도를 나타냅니다.
  • 그래프를 통해 훈련이 진행됨에 따라 모델의 정확도가 어떻게 변하는지를 알 수 있습니다.
  • 정확도가 증가한다면 모델이 점점 더 잘 예측하고 있다는 것을 의미합니다.

손실 함수 그래프

  • 이 그래프는 학습 과정에서의 손실(Loss) 값의 변화를 보여줍니다.
  • 파란색 선은 훈련 데이터(train)의 손실 값을, 주황색 선은 검증 데이터(val)의 손실 값을 나타냅니다.
  • 그래프를 통해 훈련이 진행됨에 따라 손실 값이 어떻게 변하는지를 알 수 있습니다.
  • 손실 값이 감소한다면 모델이 점점 더 잘 학습하고 있다는 것을 의미합니다.

데이터의 불균형 해결하기: 오버샘플링과 다운샘플링

데이터가 불균형할 때, 즉 어떤 클래스가 다른 클래스보다 훨씬 더 많은 경우 모델 학습에 문제가 발생할 수 있습니다. 이를 해결하기 위해 오버샘플링과 다운샘플링을 사용합니다.

  • 다운샘플링: 데이터 수가 많은 클래스를 줄이는 것
  • 오버샘플링: 데이터 수가 적은 클래스를 늘리는 것

여기서는 오버샘플링을 통해 적은 클래스의 데이터를 늘리는 방법을 설명합니다.

1. 필요한 라이브러리 불러오기

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn.metrics import recall_score
from imblearn.over_sampling import SMOTE

필요한 라이브러리를 불러옵니다. numpy와 pandas는 데이터 처리, matplotlib와 seaborn은 시각화, scikit-learn은 머신러닝 모델링, imblearn은 오버샘플링에 사용됩니다.

2. 데이터 불러오기 및 확인하기

data = pd.read_csv("data.csv")
data.info()
data['Pass.Fail'].value_counts()

데이터를 읽어와서 정보와 각 클래스의 개수를 확인합니다.

여기서 0 클래스가 1 클래스보다 훨씬 많음을 알 수 있습니다.

3. 데이터 전처리와 업샘플링 (Data Preprocessing and Upsampling)

data[~data.applymap(np.isreal).all(1)]ㅌ

데이터 확인하고 결측값 채우기

  • 목적: 숫자가 아닌 값이 있는 행을 찾기.
  • 방법: 모든 값을 확인해서 숫자가 아닌 값이 있는 행을 보여줌.
  • applymap(np.isreal): 데이터의 모든 값을 숫자인지 확인.
  • ~: 부정 연산자로, 숫자가 아닌 값을 찾음.

 

data = data.fillna(data.median())

 

  • 목적: 비어 있는 값을 채우기.
  • 방법: 각 열의 중앙값으로 비어 있는 값을 채움.
  • fillna: 비어 있는 값을 채움.
  • data.median(): 각 열의 중앙값을 계산.
data.describe().transpose()

 

  • 목적: 데이터의 기본 통계를 확인.
  • 방법: 데이터의 평균, 표준편차, 최소값, 최대값 등을 계산하고 보여줌.
  • describe(): 데이터의 요약 통계를 계산.
  • transpose(): 행과 열을 바꿔서 통계를 더 쉽게 보기 좋게 만듦.

 

 

data.groupby(["Pass.Fail"]).count()
  • 목적: 각 그룹의 데이터 개수를 세기.
  • 방법: Pass.Fail 값에 따라 데이터를 그룹화하고 각 그룹의 개수를 셈.
  • groupby(["Pass.Fail"]): Pass.Fail 값에 따라 데이터를 그룹화.
  • count(): 각 그룹의 데이터 개수를 셈.
  • 오버샘플링은 주로 데이터 불균형 문제를 해결하기 위해 소수 클래스 데이터를 늘리는 데 사용되며, 새로운 합성 데이터를 생성하는 방법이 포함됩니다.
  • 업샘플링은 주로 시간 시계열 데이터의 해상도를 높이기 위해 기존 데이터 포인트 사이에 새로운 데이터를 추가하는 방법입니다.

 

2. 업샘플링 (Up sampling)

  • 목적: 데이터가 적은 그룹(소수 클래스)을 늘려서 데이터를 더 균형 있게 만듦.
  • 방법: 주로 데이터 불균형 문제를 해결하기 위해 사용하며, 새로운 합성 데이터를 생성하는 방법이 포함됩니다.
array = data.values
X = array[:,0:48]  # 입력 데이터 (특징들)
Y = array[:,48]    # 목표 데이터 (결과 값)

오버샘플링 (Oversampling)

  • 목적: 주로 데이터 불균형 문제를 해결하기 위해 소수 클래스 데이터를 늘리는 데 사용됩니다.
  • 방법: 소수 클래스 데이터를 복제하거나 새로운 합성 데이터를 생성하여 늘립니다. 대표적인 방법으로 SMOTE가 있습니다.
  • 비교:
    • 업샘플링은 보통 시간 시계열 데이터에서 해상도를 높이는 방법을 의미하지만, 여기서는 오버샘플링의 의미로 사용되었습니다.
    • 오버샘플링은 주로 데이터 불균형 문제를 해결하기 위해 사용됩니다.

4. 데이터 나누기 및 SMOTE를 이용한 오버샘플링

  • 데이터 나누기:
array = data.values
X = array[:, 0:48]
Y = array[:, 48]

 

  • 방법: 입력 데이터와 목표 데이터를 나눔.
  • data.values: 데이터프레임을 배열로 변환.
  • X: 첫 48개의 열을 선택 (특징들).
  • Y: 49번째 열을 선택 (결과 값). 
test_size = 0.30  # 70:30 비율로 학습과 테스트 데이터 나눔
seed = 7  # 랜덤 시드 값
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=test_size, random_state=seed)
  • 목적: 데이터를 학습용과 테스트용으로 나누기.
  • 방법: 70%는 학습용, 30%는 테스트용으로 나눔.
  • train_test_split: 데이터를 학습용과 테스트용으로 나눔.
  • test_size=0.30: 데이터의 30%는 테스트용으로 사용.
  • random_state=seed: 재현 가능성을 위해 랜덤 시드를 설정.

SMOTE를 사용한 업샘플링

SMOTE (Synthetic Minority Over-sampling Technique) 기법을 사용해서 적은 데이터를 늘림.

sm = SMOTE(sampling_strategy=0.5, k_neighbors=3, random_state=1)
X_train_res, y_train_res = sm.fit_resample(X_train, y_train)

 

  • 목적: 적은 데이터를 늘리기.
  • 방법:
    • SMOTE: 소수 클래스의 데이터를 합성하여 데이터를 늘림.
    • fit_resample: 데이터를 오버샘플링하여 학습용 데이터를 증가시킴.

 

print("Before UpSampling, counts of label '1': {}".format(sum(y_train==1)))
print("Before UpSampling, counts of label '0': {} \n".format(sum(y_train==0)))

 

  • 목적: 업샘플링 전 데이터 개수 확인.
  • 방법: Pass.Fail 값이 1인 데이터와 0인 데이터의 개수를 셈.

 

 

print("After UpSampling, counts of label '1': {}".format(sum(y_train_res==1)))
print("After UpSampling, counts of label '0': {} \n".format(sum(y_train_res==0)))
print('After UpSampling, the shape of train_X: {}'.format(X_train_res.shape))
print('After UpSampling, the shape of train_y: {} \n'.format(y_train_res.shape))

SMOTE를 사용하여 오버샘플링을 수행합니다.

오버샘플링 후 클래스의 개수와 데이터 모양을 출력합니다.

종합 설명

  • 업샘플링과 오버샘플링: 업샘플링은 데이터 포인트의 수를 늘려서 해상도를 높이는 반면, 오버샘플링은 소수 클래스의 데이터를 늘려 데이터 불균형 문제를 해결합니다. 여기서 설명된 업샘플링은 실제로는 오버샘플링의 방법 중 하나로, SMOTE 기법을 사용하여 소수 클래스를 늘렸습니다.

 

5. 데이터 스케일링 및 원-핫 인코딩

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
X_train = pd.DataFrame(scaler.fit_transform(X_train_res), columns=data.columns[0:48])
X_test = pd.DataFrame(scaler.fit_transform(X_test), columns=data.columns[0:48])

import tensorflow as tf
y_train = tf.keras.utils.to_categorical(y_train_res, 2)
y_test = tf.keras.utils.to_categorical(y_test, 2)

 

  • 목적: 데이터 정규화.
  • 방법: 모든 특징 값을 0과 1 사이로 변환.
  • MinMaxScaler(): 데이터 정규화 객체 생성.
  • fit_transform(): 데이터를 정규화. 

 

 

 

6. 딥러닝 모델 정의 및 학습

import tensorflow as tf
y_train = tf.keras.utils.to_categorical(y_train_res, 2)
y_test = tf.keras.utils.to_categorical(y_test, 2)
  • 목적: 목표 데이터를 원-핫 인코딩.
  • 방법: Pass.Fail 값을 0과 1로 변환.
  • to_categorical: 원-핫 인코딩
from keras.models import Sequential
from keras.layers import Dense, Dropout

model = Sequential()
model.add(Dense(32, activation='relu', input_shape=(48,)))
model.add(Dense(16, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(2, activation='softmax'))

 

  • 방법: 여러 층을 가진 신경망 모델 생성.
  • Sequential(): 순차 모델 생성.
  • Dense: 밀집 층 (fully connected layer) 추가.

 

7. 모델 컴파일하기

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

 

  • 방법: 손실 함수와 최적화 알고리즘 설정.
  • compile(): 모델 컴파일.
  • loss='categorical_crossentropy': 다중 클래스 분류 손실 함수.
  • optimizer='adam': Adam 최적화 알고리즘.

 

hist = model.fit(X_train, y_train, batch_size=32, epochs=20, verbose=1, validation_split=0.1)

 

  • 목적: 모델 학습.
  • 방법: 학습 데이터를 사용해서 모델을 학습.
  • fit(): 모델 학습.
  • batch_size=32: 배치 크기 설정.
  • epochs=20: 학습 횟수 설정.
  • validation_split=0.1: 검증 데이터 비율 설정.

 

score = model.evaluate(X_test, y_test, verbose=1)
print('정답률=', score[1], 'loss=', score[0])

 

  • 목적: 모델 평가.
  • 방법: 테스트 데이터를 사용해서 모델의 성능 평가.
  • evaluate(): 모델 평가.

 

from sklearn.metrics import classification_report
import numpy as np
pred = np.argmax(model.predict(X_test), axis=1)
y_test = np.argmax(y_test, axis=1)
print(classification_report(y_test, pred))

 

  • 방법: 예측 결과와 실제 결과를 비교해서 성능 평가.
  • predict(): 테스트 데이터를 사용해서 예측.
  • classification_report(): 성능 평가 보고서 생성.

 


 

반응형