이전 포스팅까지는
'종속 변수 Y와 한 개 이상의 독립변수 X와의 선형(Linear) 상관 관계를 모델링하는 회기분석기법',
single & multi value(s) 학습에 대해 배웠습니다.
이번 포스팅에서는
'종속 변수 Y에 대해, 결과적으로 True(1)와 False(0)로써 구분하도록 하는 독립변수 X와의 관계 모델링 회기분석기법',
Logistic Regression에 대해 학습하겠습니다.
기존의, Linear Regression Hypothesis이란?
다음과 같이, 종속 변수 Y와 한 개 이상의 독립변수 X와의 선형(Linear) 상관 관계를 위한 Hypothesis 식을 뜻한다
Hypothesis: H(x) = Wx + b
Logistic Regression의 목적?
Logistic Regression은 '종속 변수 Y에 대해, 결과적으로 True(1)와 False(0)로써 구분하도록 하는 독립변수 X와의 관계를 모델링하는 것'
을 목표로 한다.
예를 들어, 한 학생의 공부한 기간(Day), 공부한 시간(Study-hour), 잠을 잔 시간(Sleep-hour)라는 독립변수(X)들이 있을 때, 해당 과목에 대한 PASS / No Pass(Y)의 기록(record)들을 회기 분석하는 것이 Logistic Regression의 관점이다.
Logistic Regression의 Hypothesis이란?
위와 같이 Logistic Regression의 목적에 부합하기 위해서는, 기존의 Linear Regression의 Hypothesis의 사용은 문제가 있다.
예를 들어 Y = H(X) = WX + b에서, W(기울기)와 X(독립변수)가 1을 초과할 경우, Y의 값이 0과 1사이가 아닌 값(1을 초과)이 나오므로 이를 토대로 True / False의 구분이 어렵다.
그렇기에, Logistic Regression의 Hypothesis에서는 기존의 WX(기울기 * 독립변수) 식에 0과 1로 이분할 시키기 위한, 시그모이드 함수(sigmoid function)를 적용한다.
시그모이드 함수(sigmoid function)
z값에 WX를 대입한다.(독립변수(X)에 대한, 올바른 W(기울기)찾아야 하기에)
시그모이드 함수(sigmoid function)를 적용한
Logistic Regression의 Hypothesis
Logistic Regression의 Cost function이란?
결론부터 이야기하자면, 기존의 Linear Regression의 Cost function과 다르게 Logistic Regression의 Cost function은 다음과 같다.
H(X) = Sigmoid(WX) 라는, 사실상 자연상수의 지수(e)를 사용하는 Logistic Regression의 Hypothesis의 Cost를 판단하기 위해서는, Log의 사용이 불가피한 것이다.
또한 0과 1로 이분할 시키기 위한 시그모이드 함수를 적용하였기에, Y의 값에 따라 해당 Hypothesis의 Cost또한 분리해야 한다.
이 때, 반드시 확인해야될 것은 기존의 Linear Regression의 Cost function과 마찬가지로, 독립변수(X)에 대한, 올바른 W(기울기)찾아야 하기에, Cost(W)는 항상 Cost들의 평균 값이라는 것을 기억해야한다.
Logistic Regression의 Cost function에서 Cost인, C(H(x),y)의 의미란?
위의 Logistic Regression의 Cost function 공식에서 C(H(x),y)는 y의 값이 0과 1일 때를 이분할 하였다. 이를 해석 하면 다음과 같다.
- y가 1일 때
- H(X) = 1가 되었다면(Hypothesis의 독립변수 X에 의해 H(X)이 1이되 었다) 예측이 성공했다는 뜻이고, 이때의 비용은 0이다.
- H(X) = 0가 되었다면(Hypothesis의 독립변수 X에 의해 H(X)이 0이되 었다) 예측이 실패했다는 뜻이고, 이때의 비용은 무한대이다.
- y가 0일 때
- H(X) = 0가 되었다면(Hypothesis의 독립변수 X에 의해 H(X)이 0이되 었다) 예측이 성공했다는 뜻이고, 이때의 비용은 0이다.
- H(X) = 1가 되었다면(Hypothesis의 독립변수 X에 의해 H(X)이 1이되 었다) 예측이 실패했다는 뜻이고, 이때의 비용은 무한대이다.
하지만, 위와 같은 식으로 직접 코드에 적용할 경우, 조건문(if)에 따라 늘 분할 하여 Cost들을 정리해야하는 번거로움이 생긴다. 이를 해결하기 위해, Cost function을 다음과 같이 정의하였고, 이 공식은 위의 조건들을 만족한다.
늘 그랬듯이, 항상 머신러닝의 기본방식인
1. 목표에 따른 가설(Hypothesis)과 Cost function설정
2. 가설에 대한 Cost들을 최소화
3. 실제 데이터 통한 반복 학습
이 3가지 순서를 다시 한번 기억하면서,
실전예제를 접하겠습니다.
실전예제
여러 독립 변수들과 'Pima 인디언 당뇨병(pima indians diabetes)' 진단 결과(True / False)의 상관 관계를 통해, 병에 걸린 여부를 예측하라
tensorflow가 학습할 데이터
(이때, test 항목에 negatif는 0으로, positif는 1로 치환하여 진행한다)
참조 데이터 출처: https://www.kaggle.com
위의 출처에서 CSV파일을 다운받은 뒤,
이전 포스팅 에서 했던 방식과 같이 Jupyter notebook 디렉토리에 해당 파일을 넣는다.
이 파일을 통해,
'Pima 인디언 당뇨병(pima indians diabetes)' 진단 결과(True / False)를 예측하는 프로그래밍(하단의 코드)을 시작한다.
실전코드
import tensorflow as tf # numpy는 python 다차원 배열을 사용하기 위한 패키지 import numpy as np # 1. Logistic Regression Hypothesis 생성 # numpy.loadtxt() 또는 numpy.genfromtxt()로 파일을 읽어들인다. datas = np.loadtxt('pimaindiansdiabetes.csv', delimiter = ',' , dtype = np.float32) x_data = datas[:, 0:-1] y_data = datas[:, [-1]] # feed_dict에 feed될(to be fed) tensor를 위한 placeholder 설정 X = tf.placeholder(tf.float32, shape=[None, 8]) Y = tf.placeholder(tf.float32, shape=[None, 1]) # tf.Variable(변수)에 random number를 각각 assign W = tf.Variable(tf.random_normal([8, 1], mean=0.01, stddev=0.01), name='weight') b = tf.Variable(tf.random_normal([1]), name='bias') # logistic regression Hypothesis 설정(tf.sigmoid() == 0과 1 사이의 값을 만들기 위한 시그모이드 함수) hypothesis = tf.sigmoid(tf.matmul(X, W) + b) # 2. Cost function 최소화 #cost function(logistic regression에서, W와 b를 찾기 위한 cost) cost = -tf.reduce_mean(Y * tf.log(hypothesis) + (1 - Y) * tf.log(1 - hypothesis)) train = tf.train.GradientDescentOptimizer(learning_rate=0.0001).minimize(cost) # 정확성 측정 # tf.cast()의 첫 번째 파라미터 'if hypothesis > 0.5' then 1' 1 을 float32로 캐스팅(=1.0) predicted = tf.cast(hypothesis > 0.5, dtype=tf.float32) accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, Y), dtype=tf.float32)) # 3. 학습을 통해 실행 with tf.Session() as sess: sess.run(tf.global_variables_initializer()) feed = {X: x_data, Y: y_data} for step in range(10001): sess.run(train, feed_dict=feed) if step % 2000 == 0: print(step, sess.run(cost, feed_dict=feed)) h, c, a = sess.run([hypothesis, predicted, accuracy], feed_dict=feed) print("\nHypothesis: ", h,"\nCorrect (Y): ", c, "\nAccuracy: ", a)
결과
Accuracy: 0.710938
실전 코드의 중요 사항 및 해설
# tf.Variable(변수)에 random number를 각각 assign W = tf.Variable(tf.random_normal([8, 1], mean=0.01, stddev=0.01), name='weight') #cost function(logistic regression에서, W와 b를 찾기 위한 cost) cost = -tf.reduce_mean(Y * tf.log(hypothesis) + (1 - Y) * tf.log(1 - hypothesis)) train = tf.train.GradientDescentOptimizer(learning_rate=0.0001).minimize(cost)
위 코드에서,
1. tf.random_normal([8, 1], mean=0.01, stddev=0.01) 를 쓴 이유는?
tf.random_normal() 함수에서 mean은 평균값을 의미하고 stddev는 표준편차를 의미한다. 이를 각각 0.01로 할당한 이유는
tf.matmul(X, W)에서 W(기울기)의 값이 X(독립변수)와 곱하여 더해지는데 X(독립변수) 값이 크면 클 수록 tensorflow에서 값이 안보이는 경우가 생길 수 있기 때문에(ex. NaN) 이를 방지하고자 한 것이다.
2. tf.train.GradientDescentOptimizer(learning_rate=0.0001).minimize(cost) 를 쓴 이유는?
일단, Gradient Descent Algorithm은 기울기의 크기가 줄어드는 쪽으로 하강하여 Cost function의 최소화를 통해 원하는 값을 찾아낸다는 것이 주된 목적이다.
이 때, 기울기의 크기가 줄어 드는 Step(Cost의 미분 값 + Step)을 'Learning Rate'이라 한다.
결국, 이 Learning Rate 조절을 통해 그래프 상에서 이동하는 step의 크기를 조절한다.(가장 중요한 작업)
3. Learning Rate 조절이 가장 중요한 이유는?
Learning Rate의 값이 클 경우에는,
기울기가 줄어드는 지점으로 이동하다가 큰 Step의 간격에 의해 최소값에 도달하기 전에 그래프 반대편으로 튀어 나가 발산(overshooting)해버린다.
Learning Rate의 값이 작을 경우에는,
실제 학습(train)을 하는 과정에서 작은 Step의 간격에 의해 최소값을 찾아가는 속도가 느리게 되어, 원하는 값을 찾지 못하고 학습이 끝날 수도 있다. (ex. 반복문을 통한 학습(train)을 해도, Cost값이 줄지 않는 현상)
4. 그렇다면, Learning Rate 조절을 어떻게 해야되는지?
보통은 Learning rate의 값을 0.01로 시작해서 발산(overshooting)여부를 확인하고, 더 작게 할지 크게 할지를 조절하며 테스트한다.
'AI > 머신러닝' 카테고리의 다른 글
XGBoost 이해하기 (0) | 2021.12.01 |
---|---|
Ensemble Learning Boosting 이해하기 (0) | 2021.12.01 |
[머신러닝] Multi-variable Linear Regression (csv data, File load) (2) | 2021.09.25 |
[머신러닝] Gradient Descent Algorithm (0) | 2021.09.25 |
[머신러닝] 선형회귀(Linear Regression) (0) | 2021.09.25 |