이것저것 기록

[DL, PyTorch] nn.Module로 로지스틱회귀 (logistic regression) 구현하기 본문

Data Science/ML & DL

[DL, PyTorch] nn.Module로 로지스틱회귀 (logistic regression) 구현하기

anweh 2020. 10. 15. 12:29

로지스틱회귀는 회귀를 사용하여 데이터가 어떤 범주 (class)에 속할 확률을 0에서 1사이의 값으로 예측하고,

그 확률에 따라 가능성이 더 높은 범주 (class)에 속하는 것으로 분류 (classification)해주는 지도학습 알고리즘이다. 

로지스틱회귀에선 확률값이 0과 1사이의 값을 가져야하는데, 선형회귀의 회귀식인 y = ax + b에서는 -무한대 ~ +무한대의 값을 가지게 된다. 

그래서 이 값을 0~1사이의 값으로 변환해주는 장치가 필요한데, 그게 바로 시그모이드 함수이다.

 

시그모이드 함수를 활용하여 얻은 로지스틱회귀의 회귀식은 다음과 같다.

로지스틱 회귀의 로스함수는 다음과 같다. 


 

1. 로지스틱회귀 분석을 한다는 것은

로지스틱회귀는 두 개의 카테고리 (binary)로 분류되는 범주형 데이터를 예측할 때 적합하다.

선형회귀만으론 해결이 안되던 문제, 어떤 값을 넣든 결과값이 0에서 1사이를 출력해야하는 문제에 적합함. 

 

 

2. 실제 적용 사례

  • 고객의 신용도 평가 (우량/불량)

  • 고객 지속 평가 (유지/번호이동)

  • 제과 판매 (판매/폐기)

  • 질병 예측 (악성종양/양성종양) 

 

 

3. 구현

3.1 사용한 라이브러리

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt

3.2 데이터 생성

torch.manual_seed(425)
x_data = [[1, 2], [2, 3], [3, 1], [4, 3], [5, 3], [6, 2]]
y_data = [[0], [0], [0], [1], [1], [1]]
x_train = torch.FloatTensor(x_data)
y_train = torch.FloatTensor(y_data)

3.3 nn.Module로 모델 설계

model = nn.Sequential(
   nn.Linear(2, 1),
   nn.Sigmoid() 
)
model(x_train)

클래스로 선형회귀를 구현한 지난번과 달리, 간단하게 nn.Module을 사용해서 구현해줬다. 

nn.Sequential()은 각 레이어를 데이터가 순차적으로 지나갈 때 사용하면 좋은 방법 같다. 

여러 nn.Module을 한 컨테이너에 넣어 정리해서 한 번에 돌리는 방법이다. 

nn.Sequential()자체를 함수화 시키는 방법도 있는데 다음 링크를 참고! 

 

Pytorch: how and when to use Module, Sequential, ModuleList and ModuleDict

Updated at Pytorch 1.5

towardsdatascience.com

 

 

3.4 학습

# optimizer 설정
optimizer = optim.SGD(model.parameters(), lr = 1)

epochs = 300
running_loss = []
for epoch in range(epochs + 1):

    y_pred = model(x_train) # h(x) 계산
    loss = F.binary_cross_entropy(y_pred, y_train) # loss 계산
    running_loss.append(loss)

    # cost로 h(x) 개선
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    # 5번마다 로그 출력
    if epoch % 5 == 0:
        prediction = y_pred >= torch.FloatTensor([0.5]) # 예측값이 0.5를 넘으면 True로 간주
        correct_prediction = prediction.float() == y_train # 실제값과 일치하는 경우만 True로 간주
        accuracy = correct_prediction.sum().item() / len(correct_prediction) # 정확도를 계산
        print('Epoch: {:4d}/{}    |    Loss: {:.6f}     |    Accuracy: {:2.2f}%'.format(
            epoch, epochs, loss.item(), accuracy * 100,
        ))
  
ax = plt.subplot()
plt.plot(np.array(running_loss), 'r')
ax.set_title('Loss graph of logistic regression (demo)')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.show()

 

 

 

 

4. 결과

콘솔 실행 결과
plt로 시각화 한 Loss 그래프

 

Comments