Skip to content

기계학습 Logistic Regression #
Find similar titles

Structured data

Category
Programming

Logistic Regress #

회귀 분석 방식의 핵심 기능 중 하나가 바로 '로지스틱 회귀'이다. 이전의 선형 분석과 가장 큰 차이점은 바로 '값'이 아닌 '확률'로서 분류한다는 점이다. 기존의 선형 회귀 분석에서는 단순히 입력한 값을 그대로 독립변수(입력값, 원인이 되는 값을 의미한다)로 받아서 사용하다 보니 평균보다 차이가 큰 값이 입력되면 값이 크게 달라져 버리는 문제점이 있다는 것을 알게 되었다.

예를 들어 '인실 고등학교' DSC반 학생들의 키가 165~170으로 대체로 비슷비슷한데, 갑자기 키가 3m인 전학생이 와서 평균 키가 1m나 커져 버리는 문제가 발생했다. 키 하나만 계산한다면 괜찮을지 모르지만 평균 키, 평균 몸무게, 평균 식사량 등 다양한 정보들과 같이 비교 분석한다면 이는 허용할 수 있는 한계치를 벗어나 버리고 만다.

그래서 로지스틱에세는 시그모이드라는 계산을 사용한다. 입력값을 비율로 변환하여 항상 0과 1 사이 값으로 한정시킨다. 이런 효과로 인해 범위를 벗어나는 경우를 예방하고 정확도가 떨어지는 것을 방지한다.

Calculation #

입력값을 비율로 변환하는 것이 시그모이드의 가장 큰 기능이다. 입력값이 어느 숫자든 상관없이 결괏값이 항상 0과 1사이에 있도록 하며 중간값인 0.5 이상의 값은 성공, 그 이하의 값은 실패로 계산한다.

img

로지스틱 함수 - 위키백과

위 그래프를 보자. x축의 -6부터 6까지의 값은 입력값인 독립변수를 의미하고, y축의 0부터 1까지 값은 종속변수를 의미한다. 즉 -6일 때는 결괏값이 0, 6일 때는 결괏값이 1이라는 뜻이다. 그리고 사이의 값은 0 부터 1 사이 값으로 나오며 결괏값 0.5(중앙값)를 기준으로 왼쪽은 실패, 오른쪽은 성공으로 계산한다.

Sigmoid #

시그모이드 함수는 로지스틱 분석의 핵심 알고리즘이다. 그래서 로지스틱 함수라고도 하며 위에서 설명한 기능을 코드로 설명하면 아래와 같다. 기능별로 총 4단계로 나누어 설명한다.

Sigmoid Tutorial 1 - Import Library #

우선 코드에 사용할 변수를 위해 numpy를, 결과를 그래프로 그리기 위해 matplotlib를 호출한다.

    import numpy as np
    import matplotlib.pyplot as plt

Sigmoid Tutorial 2 - Define Function #

시그모이드 함수는 성공확률을 실패확률로 나누어 계산하다. 코드로 구현하면 아래와 같다. 'np.exp()'는 밑이 자연상수 e인 지수함수로 변환해준다. 아래 공식을 코드화시킨 것이다.

    def sigmoid(x):
        a = []
        for itr in x:
            a.append(1 / (1 + np.exp(-itr)))
        return a

Image

Sigmoid Tutorial 3 - Input Data #

제작한 함수를 사용하여 원하는 값을 독립변수로 적용한다.

    x = np.linspce(-8, 8, 100)
    sig = sigmoid(x)

Sigmoid Tutorial 4 - Print Graph #

계산한 결과를 눈으로 확인하기 위해 그래프로 출력해본다.

    plt.plot(x, sig)
    plt.grid(True)
    plt.show()

Image

위에서 작업한 결과물을 출력하면 이런 그래프를 확인할 수 있다. -8부터 8까지 실수를 100 등분 한 수들을 모아서 x라는 입력값을 만들고, 이 x값을 반복하면서 시그모이드 함수를 실행한 결괏값을 sig라는 변수에 모은다. 그리고 x와 sig를 그래프로 그린 결과 각각의 결괏값이 0에서 1 사이의 값으로 변한 것을 확인할 수 있다.

Image

응용하여 입력값을 불균등하게 차이가 심한 값으로 설정해보자. -500부터 100까지 10000 등분 하여 적용해도 결괏값이 0에서 1 사이 값으로 나오는 것을 확인할 수 있다. 이것이 시그모이드 함수의 가장 중요한 기능이다.

Implement #

로지스틱 회귀는 시그모이드 함수를 사용해서 입력값을 0과 1사이 값으로 변환한 후 최적화 함수를 통해 예상값을 구하는 방법이다. 그래서 구현과정을 보면 회귀 분석에 시그모이드 함수를 추가한 정도이다. 간단해 보이는 발상이지만 일반적인 선형 회귀에 비해 로지스틱 회귀는 큰 장점이 있다. 값이 아닌 비율로 계산하는 만큼 일반적인 범주형 데이터를 입력받을 수 있고, 이산형(0과1, 참거짓) 뿐만 아니라 다항형 또는 분화형으로 계산할 수 있어 예측과 분류 2가지 모델을 만들 수 있다.

의료, 통신, 데이터마이닝과 같은 다양한 분야에서 사용되는 만큼 회귀분석의 꽃이라고 할 수 있다. 이제 로지스틱 함수가 실제로 어떻게 사용하는지 간단한 예제를 통해 살펴본다.

Implement 1 - Set Training Data #

우선 예제로 사용할 데이터를 입력한다. 이전에는 84, 213, 56.8 같이 한 번에 1개의 실수를 입력했지만, 이번에는 한 번에 2개의 수(범주형)를 입력한다.

  • x_data는 입력값, [1, 2] 같이 한번에 2개의 숫자로 형성됨.
  • y_data는 결괏값. [1, 2] 입력시 결괏값은 0, [4, 3]일 때는 1이라는 의미.
  • X, Y는 각각 x_data, y_data가 들어갈 독립변수와 종속변수이다.

    import tensorflow as tf
    
    x_data = [ [1,2], [2,3], [3,1], [4,3], [5,3], [6,2]]
    y_data = [ [0], [0], [0], [1], [1], [1] ]
    
    X = tf.placeholder(tf.float32, shape=[None, 2])
    Y = tf.placeholder(tf.float32, shape=[None, 1])
    

Implement 2 - Set Weight, Bias #

그다음 가중치(Weight)편향(Bias)을 설정한다. 가중치는 가설의 기울기를 의미하며 편향은 오차를 의미한다.

  • 가중치와 편향은 기계학습을 통해 최적의 값으로 계산되므로 형태만 설정함.
  • 입력값은 2개씩, 결괏값은 1개가 나오므로 [2, 1] 형태의 행렬이 됨.
  • 편찻값은 크게 중요하지 않기 때문에 1형태의 스칼라값으로 설정.

    W = tf.Variable(tf.random_normal([2,1]), name='weight')
    b = tf.Variable(tf.random_normal([1]), name='bias')
    

Implement 3 - Set Hypothesis, Cost #

설정한 가중치와 편향 변수를 이용해 가설을 설정한다. 이 과정에서 시그모이드 함수가 적용된다.

  • tf.sigmoid()로 시그모이드 함수를 적용.
  • tf.matmul()은 텐서플로우에서 행렬을 곱하는 기능.
  • tf.log()는 로그계산으로 0과 1 사이 값으로 바꾸어준다.

    hypothesis = tf.sigmoid(tf.matmul(X, W) + b)
    cost = - tf.reduce_mean(Y+tf.log(hypothesis) 
            + (1-Y)*tf.log(1-hypothesis))
    

Implement 4 - Set Train #

설정한 가중치 함수를 최적화할 함수를 설정한다. 경사타기 알고리즘을 적용한다.

    train = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(cost)

Implement 5 - Set Computation #

설정한 모든 값을 계산할 예측 알고리즘을 설정한다.

  • 가설(hypothesis)이 0.5보다 크면 참, 작으면 거짓으로 설정.
  • 정확도(accuracy) 함수를 추가.
  • 예측값(predicted)이 실제값(Y)과 같은지 비교하여 평균을 계산.

    predicted = tf.cast(hypothesis > 0.5, dtype=tf.float32)
    accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, Y), dtype=tf.float32))
    

Implement 6 - Train the Model #

기계학습으로 제작한 모델을 훈련시킨다.

  • with를 통해 Session을 생성 후 자동으로 닫아줌.
  • 각 step 별로 cost 값을 출력해서 확인.
  • x_data의 두 가지 값 중 첫 번째 값만 출력됨.
  • 훈련 완료 후 실제 데이터와 비교하여 정확도를 출력.

    with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    
    for step in range(10001):
        cost_val, _ = sess.run([cost, train], 
        feed_dict={X:x_data, Y:y_data})
    
        if step % 200 == 0:
            print('step{:4} : cost={:6.4f}'.format(step, cost_val))
    
    # Accuracy report
    h, c, a = sess.run([hypothesis, predicted, accuracy], 
        feed_dict={X:x_data, Y:y_data})
    print("\n hypothesis : {}, Correct: {}, 
        Accuracy: {}".format(h, c, a))
    

Implement 7 - Result #

해당 내용을 정상적으로 출력하면 아래와 같이 계산된다. 기계학습은 훈련하는 컴퓨터와 환경에 따라 값이 달라질 수 있다.

Image

Image

Image

Image

설명한 코드를 모아서 작성하였다. 보면 100단위 단계마다 계산 값이 출력되는데 출력 결과를 보면 시그모이드를 적용한 가설 값(hypothesis)이 0.05, 0.66, 0.58등 0과 1 사이로 나오는 것을 확인할 수 있다. 이런 가설 값을 가지고 반복 학습을 통해 0 또는 1을 예측한다. 처음에는 cost가 5.52로 높았지만, 훈련이 반복될수록 값이 낮아지면서 정확도(accuracy)가 점점 높아지는 것을 확인할 수 있다.

  • 진행 중 변화되는 변수들의 값을 출력.
  • hypothesis는 가설로써 W와 X의 곱을 의미. 예측값을 의미
  • logistic에서는 참, 거짓으로 결과나 나옴. predicted는 예측값이 참(1)인지 거짓(0)인지 판별.
  • cost는 예측값과 실제값의 차이로써 처음에는 높게 나오지만 진행될수록 차이가 작아짐.
  • accuracy은는 예측값과 실제값을 비교하여 같은 정도를 나타냄

Summary #

이상으로 로지스틱 회귀 분석의 주요 기능인 시그모이드 함수와, 이를 활용한 간단한 예제를 알아보았다. 로지스틱 회귀 분석은 실무에서 자주 사용되고, 다양한 분야에서 활용되는 만큼 회귀 분석의 꽃이라고 할 수 있다. 해당 예제는 이해를 돕기 위해 정제된 데이터에 간단한 결과만을 출력했지만 실제로는 훨씬 더 많은 정보, 복잡한 연산 과정, 그리고 분석을 하기 위해 이상값을 제거하고 필요한 데이터를 추출하는 전처리 과정 등의 작업이 필요하다. 하지만 로지스틱 회귀가 어떤 원리로 작동하고 어떤 정보가 필요한지 이해하면 데이터 분석에 큰 도움이 될 것이다.

0.0.1_20140628_0