본문 바로가기

Python/Data Analysis

Data Analysis / ML / Logistic Regression(1)

< Logistic Regression >

▷ 동작과정

  1. Linear Regression을 이용해서 Training Data Set의 특성과 분포를 파악해서 직선을 찾음
  2. 그 직선을 기준으로 데이터를 분류 (0 or 1)

※ mglearn 모듈에서 Data set을 가져와서 파악해보자

## Logistic Regression
import numpy as np
from sklearn import linear_model
import mglearn # Data Set을 가져오기 위한 utility module
import matplotlib.pyplot as plt
# Training Data Set
x, y = mglearn.datasets.make_forge()
# 데이터 구성 형태
# x: [[10,20], [30,40], ...]
# y: [1 0 1 0 ...]
# x 데이터를 x축, y축으로 사용
# y 데이터는 2차원 평면의 점이 0인지 1인지를 나타내는 데이터
mglearn.discrete_scatter(x[:,0], x[:,1], y)
# Linear Regression을 x 데이터를 학습해서
# 각 점들을 가장 잘 표현할 수 있는 직선을 그려보자
model = linear_model.LinearRegression()
model.fit(x[:,0].reshape(-1,1), x[:,1].reshape(-1,1))
print(model.coef_) # [[-0.17382295]]
print(model.intercept_) # [4.5982984]
plt.plot(x[:,0], x[:,0]*model.coef_.ravel() + model.intercept_)

Logistic Regression

▷ 과정그래프

Logistic Regression 과정 그래프

▶ Q) Linear Regression으로 학습과 예측을 할 수 있지 않을까?

  • 직선이 1 이상의 값이 도출되므로 Linear Regression으로는 Classification 작업을 하는데 문제가 있음
  • 이를 해결하기 위해서 Sigmoid 함수 도입
  • 직선을 S 모양의 곡선으로 변환 (최소 0, 최대 1)

< Sigmoid 함수 >

Sigmoid 수식

# Sigmoid 모양 확인
import numpy as np
import matplotlib.pyplot as plt
x_data = np.arange(-7, 8)
y_data = 1 / (1 + np.exp(-1 * x_data))
plt.plot(x_data, y_data)
plt.show()
view raw sigmoid.py hosted with ❤ by GitHub

Sigmoid function

< Sigmoid - loss function >

Sigmoid 함수를 사용하면 loss function의 식과 그래프가 바뀐다.

  • Convex function이 되지 않음
  • local minimum과 global minimum이 생김

non-convex function

▷ 어떻게 하면 convex function 으로 만들 수 있을까?

< Cross Entropy >

▷ Logistic의 loss function

▷ 아래의 식을 사용하면 Convex function 형태로 그래프가 나타난다.

Cross Entropy 수식

< Tensorflow를 이용한 Logistic Regression 구현 >

import tensorflow as tf
import numpy as np
# Training Data Set
x_data = np.array([ [1,0], [2,0], [5,1], [2,3], [3,3], [8,1], [10,0] ])
t_data = np.array([ [0], [0], [0], [1], [1], [1], [1] ])
# placeholder
X = tf.placeholder(shape=[None,2], dtype=tf.float32)
T = tf.placeholder(shape=[None,1], dtype=tf.float32)
# Weight & bias
W = tf.Variable(tf.random.normal([2,1]), name='weight')
b = tf.Variable(tf.random.normal([1]), name='bias')
# Hypothesis (Logistic Model)
logits = tf.matmul(X,W) + b
H = tf.sigmoid(logits)
# loss function
loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=logits, labels=T))
# train 노드 생성
train = tf.train.GradientDescentOptimizer(learning_rate=0.001).minimize(loss)
# Session 생성 & 초기화
sess = tf.Session()
sess.run(tf.global_variables_initializer())
# 학습 진행(Graph 실행)
for step in range(30000):
_, W_val, b_val, loss_val = sess.run([train, W, b, loss], feed_dict={X:x_data, T:t_data})
if step % 3000 == 0:
print('W : {}, b : {}, loss : {}'.format(W_val, b_val, loss_val))
### 결과 ###
# 마지막 출력문만 확인
# W : [[0.32362196]
# [1.1052394 ]], b : [-1.9940497], loss : 0.31068849563598633
# predict
print(sess.run(H, feed_dict={X:[[4,2]]})) # [0.8195257]]