<pre class="brush:python">
code
</pre> 


Linear Regression의 Hypothesis와 cost의 개념 연습

Hypothesis와 cost(loss) 함수

  • 가설(hypothesis) : 주어진 \(x\)에 대해서 예측(\(H(x)\))을 어떻게 할 것인가?
    • weight \(W\)와 bias \(b\)로 표현된다.
$$H(x) = Wx + b$$

  • cost(loss) 함수 : 예측을 얼마나 잘 했는가?를 표현한 것으로 차이의 제곱에 대한 평균
    • \(H(x_i)\) : 예측값
    • \(b_i\) : 실제값
$$\textrm{cost(loss)}(W,b)=\frac{1}{m}\sum_{i=1}^{m}(H(x_i)-b_i)^2$$


  • 학습을 한다는 것
    • \(W\)와 \(b\)를 조절해서 cost(loss) 함수의 가장 작은 값을 찾아내는 것



cost(loss) 함수를 TensorFlow로 구현하는 방법

  1. TensorFlow의 연산을 사용하여 그래프를 만든다.
  2. Session() 함수로 세션을 만들고, sess.run() 함수에 데이터를 주고 계산 그래프를 실행하여 연산을 한다.
  3. 결과값이 나와 그래프에 있는 변수들이 업데이트되거나 값을 반환한다.


1. TensorFlow의 연산을 이용하여 그래프 만들기

  • 예측값에 대한 함수 \(H(x)=Wx+b\)를 TensorFlow로 작성해보자.
  • TensorFlow에서는 weight \(W\)와 bias \(b\)의 값을 변수(variable) node로 정의
    • 기존 프로그래밍의 변수와는 다른 개념
    • TensorFlow가 사용하는 변수
      • 프로그램을 실행하면 TensorFlow가 자체적으로 변경시키는 값을 의미
      • 학습을 위해 TensorFlow가 변경을 하면서 최적의 값을 찾아낸다.
    • TensorFlow 변수를 만들 때에는 변수의 shape을 정의하고 값을 주어야 한다.
      • 보통 \(W\)와 \(b\)의 값을 모르기 때문에 random한 값을 준다.
      • tf.random_normal(shape)
    • 예측값 함수를 TensorFlow의 한 점(node)으로 정의
      • tensor 또는 node \(W\)와 \(b\)로 표현
import tensorflow as tf

# 학습용 X와 Y 데이터를 준다.
x_train = [1, 2, 3]
y_train = [1, 2, 3]

# TensorFlow 변수를 1차원 배열로 정의
w = tf.Variable(tf.random_normal([1]), name = 'weight')
b = tf.Variable(tf.random_normal([1]), name = 'bias')

# 예측값 함수(hypothesis)
hypothesis = w * x_train + b


  • cost(loss) 함수 \(\textrm{cost(loss)}(W,b)=\frac{1}{m}\sum_{i=1}^{m}(H(x_i)-b_i)^2\)를 TensorFlow 함수를 이용해 표현해보자.
    • tf.reduce_mean() 함수 : tensor가 주어졌을 때 평균을 구하는 함수
    • cost(loss) 함수의 평균을 내는 부분 \(\frac{1}{m}\sum_{i+1}^{m}\)을 구현하는 것
>>> import tensorflow as tf
>>> t = [1., 2., 3., 4.]
>>> r_mean = tf.reduce_mean(t)
>>> sess = tf.Session()
>>> print("sess.run(r_mean) = ", sess.run(r_mean))
sess.run(r_mean) =  2.5
 

    • cost(loss) 함수 \(\textrm{cost(loss)}(W,b)=\frac{1}{m}\sum_{i=1}^{m}(H(x_i)-b_i)^2\)는 다음과 같이 작성할 수 있다.

# cost(loss) 함수
cost = tf.reduce_mean(tf.square(hypothesis - y_train))


    • 이제 cost(loss) 함수를 최소화(minimization)해야 한다.
      • TensorFlow에서는  GradientDescentOptimizer() 함수를 사용한다
      • 학습 최적화를 위해 minimize() 함수를 사용해 cost 함수의 최소값을 찾도록 한다.
      • 이 부분이 magic이 되는 부분이다.
# GradientDescentOptimizer() 함수로 학습에 Gradient Descent 최적화 방법을 사용
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
train = optimizer.minimize(cost)

  • TensoFlow 세션을 만들고 실행해야 한다.
    • tf.session() 함수를 만든다.
    • 그래프에 있는 전역 변수를 초기화한다.
    • weight $W$와 bias $b$는 앞에서 선언했다.
    • 변수를 사용하기 위해서는 반드시 초기화를 해주어야만 한다.
      • tf.global_variables_initializer() 함수로 변수를 초기화할 수 있다.
# 세션을 만든다.
sess = tf.Session()
# 그래프에 있는 모든 전역 변수를 초기화한다.
sess.run(tf.global_variables_initializer())


  • training 점 : cost 함수를 최소화시킬 수 있다.
    • train을 실행시켜야 cost를 최소화시킬 수 있다.
      • cost를 최소화시킨다는 것은 예측값과 실제값의 차이를 최쇠화시킨다는 것이다.
  • 세션을 통해 train 점을 실행시킬 수 있다.
    • sess.run(train) 함수를 통해 학습이 이루어진다.
    • 예제에서는 2만번 학습을 한다.
    • 매번 결과를 출력하지 않고, 2000번째 마다 학습한 값을 출력한다.
for step in range(20001):
    sess.run(train)
    if step % 2000 == 0:
        # sess.run(train) 실행을 통해 그래프 상의 모든 연산이 수행되어
        # 그래프 상의 변수의 값들이 업데이트된다.
        print(f"STEP = {step:>5}, cost = {sess.run(cost):>.10}, "
              f"weight = {sess.run(W)}, bias = {sess.run(b)}")


2.3. 그래프의 변수들이 업데이트 된다.

  • 프로그램의 실행 결과는 다음과 같다.
  • 예제 학습 데이터를 통해 우리가 예측할 수 있는 것은 weight \(W=1\)이고, bias \(b=0\)이다.
    • 실제 학습을 시킨 후의 결과는  \(W\approx 1\), \(b\approx 0\)이다.
STEP =     0, cost = 2.450398445, weight = [ 0.52071428], bias = [-0.55709851]
STEP =  2000, cost = 7.966009434e-07, weight = [ 1.00103676], bias = [-0.00235626]
STEP =  4000, cost = 6.939634284e-11, weight = [ 1.00001001], bias = [ -2.18230052e-05]
STEP =  6000, cost = 1.227817847e-11, weight = [ 1.00000429], bias = [ -8.61254284e-06]
STEP =  8000, cost = 1.227817847e-11, weight = [ 1.00000429], bias = [ -8.61254284e-06]
STEP = 10000, cost = 1.227817847e-11, weight = [ 1.00000429], bias = [ -8.61254284e-06]
STEP = 12000, cost = 1.227817847e-11, weight = [ 1.00000429], bias = [ -8.61254284e-06]
STEP = 14000, cost = 1.227817847e-11, weight = [ 1.00000429], bias = [ -8.61254284e-06]
STEP = 16000, cost = 1.227817847e-11, weight = [ 1.00000429], bias = [ -8.61254284e-06]
STEP = 18000, cost = 1.227817847e-11, weight = [ 1.00000429], bias = [ -8.61254284e-06]
STEP = 20000, cost = 1.227817847e-11, weight = [ 1.00000429], bias = [ -8.61254284e-06]


TensorFlow의 전체적인 구조

  • train() 함수는 cost() 함수와 연결되어 있다.
  • cost() 함수는 hypothesis \(H(x)\)와 연결되어 있다.
  • \(H(x)\)는 weight \(W\)와 bias \(b\)의 형태로 연결되어 있다.
  • train()을 실행시킨다는 것은
    • 아래 그림과 같은 그래프를 만든 다음에 training을 한다.
  • train() 함수 실행 : 학습을 시킨다는 것
    • 그래프를 따라 들어가 \(W\)와 \(b\)에 값을 저장한다는 것을 의미
    • 학습을 통해 cost(loss) 함수의 값과 weight \(W), bias \(b)의 값을 보게된다.

  • 예제의 전체 소스코드

import tensorflow as tf

# 학습용 X와 Y 데이터를 준다.
x_train = [1, 2, 3]
y_train = [1, 2, 3]

# TensorFlow 연산에서는 weight와 bias를 variable로 정
W = tf.Variable(tf.random_normal([1]), name = 'weight')
b = tf.Variable(tf.random_normal([1]), name = 'bias')

# 예측값 함수(hypothesis)
hypothesis = W * x_train + b

# cost(loss) 함수
cost = tf.reduce_mean(tf.square(hypothesis - y_train))

# GradientDescentOptimizer() 함수로 학습에 Gradient Descent 최적화 방법을 사용
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
train = optimizer.minimize(cost)

# 세션을 만든다.
sess = tf.Session()
# 그래프에 있는 모든 전역 변수를 초기화한다.
sess.run(tf.global_variables_initializer())


for step in range(20001):
    sess.run(train)
    if step % 2000 == 0:
        # sess.run(train) 실행을 통해 그래프 상의 모든 연산이 수행되어
        # 그래프 상의 변수의 값들이 업데이트된다.
        print(f"STEP = {step:>5}, cost = {sess.run(cost):>.10}, "
              f"weight = {sess.run(W)}, bias = {sess.run(b)}")


placeholder() 함수로 실행할 때 변수의 값을 줄 수 있다.

  • 그래프를 미리 만들어 놓고, 실행하는 단계에서 값을 주고 싶다.

  • placeholder() 함수로 점을 만들어 놓으면 된다.

    1. placeholder() 함수로 변수형 점을 만든다.
    2. run() 함수로 그래프를 실행할 때, feed_dict 변수로 데이터를 입력한다.
  • placeholde() 함수를 사용해 변수를 선언

# 프로그램을 실행할 때 변수의 값을 넣기위해 placeholde() 함수를 사용
X = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)


  • 실행 단계에서 feed_dict 옵션을 사용하여 데이터를 입력
    • X = [1, 2, 3, 4, 5]
    • Y = [2.1, 3.1, 4.1, 5.1, 6.1]
    • \(W=1\), \(b=1.1\)
for step in range(20001):
    cost_val, W_val, b_val, _ = \
        sess.run([cost, W, b, train],
                 feed_dict = {X: [1, 2, 3, 4, 5], 
                              Y: [2.1, 3.1, 4.1, 5.1, 6.1]})
    if step % 2000 == 0:
        print(f"STEP = {step:>5}, cost = {cost_val:>.15}, "
              f"weight = {W_val}, bias = {b_val}")


  • placeholde() 함수를 사용하는 전체 코드
import tensorflow as tf

# 프로그램을 실행할 때 변수의 값을 넣기위해 placeholde() 함수를 사용
X = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)

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

hypothesis = W * X + b

cost = tf.reduce_mean(tf.square(hypothesis - Y))

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

sess = tf.Session()
sess.run(tf.global_variables_initializer())

for step in range(20001):
    cost_val, W_val, b_val, _ = \
        sess.run([cost, W, b, train],
                 feed_dict = {X: [1, 2, 3, 4, 5],
                              Y: [2.1, 3.1, 4.1, 5.1, 6.1]})
    if step % 2000 == 0:
        print(f"STEP = {step:>5}, cost = {cost_val:>.15}, "
              f"weight = {W_val}, bias = {b_val}")


  • 실행 결과
    • \(W\approx1\), \(b\approx1.1\)
STEP =     0, cost = 121.828224182129, weight = [-1.6607039], bias = [ 1.53716469]
STEP =  2000, cost = 2.85170699498849e-07, weight = [ 0.99965453], bias = [ 1.10124719]
STEP =  4000, cost = 6.18001622099129e-11, weight = [ 0.99999481], bias = [ 1.10001838]
STEP =  6000, cost = 6.18001622099129e-11, weight = [ 0.99999481], bias = [ 1.10001838]
STEP =  8000, cost = 6.18001622099129e-11, weight = [ 0.99999481], bias = [ 1.10001838]
STEP = 10000, cost = 6.18001622099129e-11, weight = [ 0.99999481], bias = [ 1.10001838]
STEP = 12000, cost = 6.18001622099129e-11, weight = [ 0.99999481], bias = [ 1.10001838]
STEP = 14000, cost = 6.18001622099129e-11, weight = [ 0.99999481], bias = [ 1.10001838]
STEP = 16000, cost = 6.18001622099129e-11, weight = [ 0.99999481], bias = [ 1.10001838]
STEP = 18000, cost = 6.18001622099129e-11, weight = [ 0.99999481], bias = [ 1.10001838]
STEP = 20000, cost = 6.18001622099129e-11, weight = [ 0.99999481], bias = [ 1.10001838]


  • 훈련시킨 모델로 값을 예측해보자.
    • 전체 소스 코드 뒤에 모델로 다른 값에 대한 예측값을 계산하는 코드를 추가한다.
print("X = {:4}일 때의 예측값은 {}입니다.".format(5, sess.run(hypothesis, feed_dict={X: [5]})))
print("X = {:4}일 때의 예측값은 {}입니다.".format(2.5, sess.run(hypothesis, feed_dict={X: [2.5]})))
print("X = [ {}, {} ]일 때의 예측값은 {}입니다.".format(1.5, 3.5, sess.run(hypothesis, feed_dict={X: [1.5, 3.5]})))


  • 예측값은 다음과 같이 실제 데이터와 거의 같게 나온다.
    • \(x=5\)일 때, \(H(5)\approx6.1\)
    • \(x=2.5\)일 때, \(H(2.5)\approx3.6\)
    • \(x=[1.5, 3.5]\)일 때, \(H(x)\approx[2.6, 4.6]\)
X =    5일 때의 예측값은 [ 6.09999275]입니다.
X =  2.5일 때의 예측값은 [ 3.60000563]입니다.
X = [ 1.5, 3.5 ]일 때의 예측값은 [ 2.60001063  4.60000038]입니다.


예제 모델에 대한 TensorFlow 역학 구조


cost(loss) 함수의 그래프 그리기

  • matplotlib 모듈을 이용하여 $W$에 대한 cost(loss) 함수의 그래프 그리기

import tensorflow as tf
import matplotlib.pyplot as plt

# 학습용 데이터 X와 Y
X = [1, 2, 3]
Y = [1, 2, 3]

W = tf.placeholder(tf.float32)

# 우리의 가설은 bias b를 생략했다. 즉 H(W) = W * X
hypothesis = W * X

# cost(또는 loss) 함수는 가설과 y 값과의 차의 제곱에 대한 평균
cost = tf.reduce_mean(tf.square(hypothesis - Y))

# 세션에서 그래프 활성화
sess = tf.Session()

# 변수 초기화
sess.run(tf.global_variables_initializer())

# cost(loss) 함수를 그래프로 출력하기 위한 변수설정
W_val = []
cost_val = []

# W 범위 -30부터 50까지에 대하여 cost(loss) 함수의 값을 구하여 저장
for i in range(-30, 50):
    feed_W = i * 0.1
    curr_cost, curr_W = sess.run([cost, W], feed_dict={W: feed_W})
    W_val.append(curr_W)
    cost_val.append(curr_cost)

# matplotlib 모듈을 이용하여 cost(loss) 함수 그리기
plt.plot(W_val, cost_val)
plt.show()


  • 위 코드 실행 결과는 아래 그래프 처럼 볼록 함수의 그래프로 표시된다.
    • 이제 아래 그래프에서 극소값을 찾아야 한다.



cost(loss) 함수의 극소값 찾기

  • 기울기(경사도)는 미분을 이용하여 찾는다.
    • 오른쪽은 기울기가 양(+, positive)이고, 왼쪽은 음(-, negative)
    • 기울기가 양이면 왼쪽으로 움직여야 하기 때문에 기울기를 빼준다.
    • 기울기가 음이면 오른쪽을 움직여야 하기 때문에 기울기를 더해준다.
  • 아래 식 (1)을 코드로 구현
    • \(\alpha\) : learning rate = 0.1
    • \(\nabla=\frac{1}{m}\sum(Wx_i-y_y)x_i\) : gradient
    • 경사 하강법 : descent = W - learning_rate * gradient

\begin{equation}W = W - \alpha\frac{1}{m}\sum_{i=1}^m(W x_i - y_i) x_i\tag{1}\end{equation}


import tensorflow as tf

x_data = [1, 2, 3]
y_data = [1, 2, 3]

W = tf.Variable(tf.random_normal([1]), name='weight')
X = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)

# 가설은 H(W) = W * X
hypothesis = W * X

# cost(loss) 함수
cost = tf.reduce_mean(tf.square(hypothesis - Y))

# 미분계수(기울기=경사도)로 경사 하강법을 사용
# W = W - learning_rate * 미분계수(gradient)
learning_rate = 0.1
gradient = tf.reduce_mean((W * X - Y) * X)
descent = W - learning_rate * gradient
update = W.assign(descent)

# 세션에서 그래프 활성
sess = tf.Session()

# 변수 초기화
sess.run(tf.global_variables_initializer())

for step in range(21):
    sess.run(update, feed_dict={X: x_data, Y: y_data})
    print(f"STEP = {step:02}, cost(loss) 함수값 = {sess.run(cost, feed_dict={X: x_data, Y: y_data}):>.5},"
          f"기울기 = {sess.run(W)} ")


  • 실행 결과

STEP = 00, cost(loss) 함수값 = 0.604494512081146240234375,기울기 = [ 1.35990906] 
STEP = 00, cost(loss) 함수값 = 15.124,기울기 = [-0.80024123] 
STEP = 01, cost(loss) 함수값 = 4.302,기울기 = [ 0.03987139] 
STEP = 02, cost(loss) 함수값 = 1.2237,기울기 = [ 0.4879314] 
STEP = 03, cost(loss) 함수값 = 0.34807,기울기 = [ 0.72689676] 
STEP = 04, cost(loss) 함수값 = 0.099005,기울기 = [ 0.85434496] 
STEP = 05, cost(loss) 함수값 = 0.028161,기울기 = [ 0.92231733] 
STEP = 06, cost(loss) 함수값 = 0.0080104,기울기 = [ 0.95856923] 
STEP = 07, cost(loss) 함수값 = 0.0022785,기울기 = [ 0.9779036] 
STEP = 08, cost(loss) 함수값 = 0.0006481,기울기 = [ 0.98821527] 
STEP = 09, cost(loss) 함수값 = 0.00018435,기울기 = [ 0.99371481] 
STEP = 10, cost(loss) 함수값 = 5.2437e-05,기울기 = [ 0.99664789] 
STEP = 11, cost(loss) 함수값 = 1.4916e-05,기울기 = [ 0.99821222] 
STEP = 12, cost(loss) 함수값 = 4.2428e-06,기울기 = [ 0.9990465] 
STEP = 13, cost(loss) 함수값 = 1.2069e-06,기울기 = [ 0.99949145] 
STEP = 14, cost(loss) 함수값 = 3.4317e-07,기울기 = [ 0.9997288] 
STEP = 15, cost(loss) 함수값 = 9.764e-08,기울기 = [ 0.99985534] 
STEP = 16, cost(loss) 함수값 = 2.7743e-08,기울기 = [ 0.99992287] 
STEP = 17, cost(loss) 함수값 = 7.9032e-09,기울기 = [ 0.99995887] 
STEP = 18, cost(loss) 함수값 = 2.2452e-09,기울기 = [ 0.99997807] 
STEP = 19, cost(loss) 함수값 = 6.3691e-10,기울기 = [ 0.99998832] 
STEP = 20, cost(loss) 함수값 = 1.8353e-10,기울기 = [ 0.99999374] 



TensofFlow를 이용하여 cost(loss) 함수의 극소값 찾기

  • 텐서플로우를 이용하면 cost(loss) 함수를 미분하지 않아도 된다.
  • 다음과 같이 2줄로 코딩할 수 있다.
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
train = optimizer.minimize(cost) 
  • \(W\)의 값을 초기에 5로 설정하고 위의 코드로 실행하는 코드

import tensorflow as tf

X = [1, 2, 3]
Y = [1, 2, 3]

# W의 값을 5로 설정하고 학습 시킨다
W = tf.Variable(5.0)

# 학습 모델의 가설
hypothesis = W * X

# cost(loss) 함수
cost = tf.reduce_mean(tf.square(hypothesis - Y))

# 텐서플로우에서 제공하는 경사 하강법 메서드(이것이 매직이다!!!)
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
train = optimizer.minimize(cost)

# 세션에서 그래프 초기화
sess = tf.Session()

# 변수 초기화
sess.run(tf.global_variables_initializer())

for step in range(20):
    print(f"STEP = {step:03}, 기울기 = {sess.run(W):>.5}")
    sess.run(train)


  • 초기값 5.0으로 실행한 결과

    • 초기값 5.0으로 시작해서 빠르게 1로 수렴한다.
    • 미분해서 구한 결과보다 더 정확하게 나온다.
STEP = 000, 기울기 = 5.0
STEP = 001, 기울기 = 1.2667
STEP = 002, 기울기 = 1.0178
STEP = 003, 기울기 = 1.0012
STEP = 004, 기울기 = 1.0001
STEP = 005, 기울기 = 1.0
STEP = 006, 기울기 = 1.0
STEP = 007, 기울기 = 1.0
STEP = 008, 기울기 = 1.0
STEP = 009, 기울기 = 1.0
STEP = 010, 기울기 = 1.0
STEP = 011, 기울기 = 1.0
STEP = 012, 기울기 = 1.0
STEP = 013, 기울기 = 1.0
STEP = 014, 기울기 = 1.0
STEP = 015, 기울기 = 1.0
STEP = 016, 기울기 = 1.0
STEP = 017, 기울기 = 1.0
STEP = 018, 기울기 = 1.0
STEP = 019, 기울기 = 1.0


  • 초기값 -3.0으로 실행한 결과

STEP = 000, 기울기 = -3.0
STEP = 001, 기울기 = 0.73333
STEP = 002, 기울기 = 0.98222
STEP = 003, 기울기 = 0.99881
STEP = 004, 기울기 = 0.99992
STEP = 005, 기울기 = 0.99999
STEP = 006, 기울기 = 1.0
STEP = 007, 기울기 = 1.0
STEP = 008, 기울기 = 1.0
STEP = 009, 기울기 = 1.0
STEP = 010, 기울기 = 1.0
STEP = 011, 기울기 = 1.0
STEP = 012, 기울기 = 1.0
STEP = 013, 기울기 = 1.0
STEP = 014, 기울기 = 1.0
STEP = 015, 기울기 = 1.0
STEP = 016, 기울기 = 1.0
STEP = 017, 기울기 = 1.0
STEP = 018, 기울기 = 1.0
STEP = 019, 기울기 = 1.0




Linear Regression의 개념

Predicting exam score

  • 아래 표의 데이터를 가지고 supervised learning을 한다고 해보자
    • x : 예측을 하기 위한 기본적인 자료,  training data 또는 learning data 또는 feature
    • y : 예측하려는 값
    • regression : 0~100 사이의 값을 예측하는 것
    • training : 데이터로 학습을 시키는 것
    • 학습이 끝나면 어떤 모델이 만들어진다.
    • regression을 사용한다는 것
      • 시험을 치르기 전에 x라는 값(7시간 공부한 학생)을 주고 y(몇 점을 맞을 수 있을까?)는 얼마인가 인공지능에게 물어본다.
      • 인공지능은 regression을 사용해 약 65점 정도 나올 것으로 예측을 한다.

 

 

Linear Regression 모델을 만들어 어떻게 동작하는지 알아보자.

  • 아래 그림 표의 데이터를 가지고 그래프에 표시하면 다음과 같다.

 

  • Linear Regression 모델을 만들기 위해서는 가설(hypothesis)을 세울 필요가 있다.
    • 가설(Hypothesis) 세우기 : 우리가 가지고 있는 데이터는 linear한 모델이 맞을 것이다.
      • 세상의 많은 데이터나 현상들이 linear한 모델로 설명할 수 있는 것이 많다
    • 학습(learning) 하기 : 아래 그림과 같이 우리가 가지고 있는 데이터에 잘 맞는 직선을 찾는 것

 

  •  1단계 : 아래 그림과 같은 직선을 수학식으로 표현한다.

$$H(x) = Wx+b$$

    • \(H(x)\) : 가설, 예측 값
    • \(W\) : weight
    • \(b\) : bias
    • \(W\)와 \(b\)에 따라 여러 가지 직선이 만들어질 수 있다.

    

    • 다음과 같은 직선의 방정식을 얻었다고 해보자.

 

  • 2단계 : 여러 직선 중에서 우리 데이터에 가장 잘 맞는 직선을 찾는다.
    • 가설로 세운 직선 위의 점과 실제 데이터와의 거리가 짧으면 좋고, 멀면 나쁘다.
    • 그래서 직선과 실제 데이터와의 거리를 구한다.

 

  • 3단계 : 거리를 구한다.
    • cost function 또는 loss function : 거리를 구하는 함수
      • 우리가 세운 가설이 실제 데이터가 얼마나 다른가를 알 수 있다.
      • 가장 쉬운 방법은 \(H(x)-y\)를 구하는 것
        • 그러나 거리가 음이나 양이 될 수 있기에 잘 사용하지 않는다
      • 그래서 차이(거리)를 제곱 \((H(x)-y)^2\)한 후 평균을 구한다.:
        • 항상 양의 값을 가진다.
        • 거리가 멀어지면 값이 커지기 때문에 페널티를 줄 수 있다.
        • 페널티를 줌으로서 거리를 작게 만들 수 있다.
    • 위의 데이터에 대하여 cost(loss) function 값을 구하면 다음과 같다.
$$\frac{(H(x_1)-y_1)^2 + (H(x_2)-y_2)^2 + (H(x_3)-y_3)^2}{3}$$
    • 그래서 cost(loss) function의 식은 다음과 같다.
      • \(m\)은 학습 데이터의 개수
$$\textrm{cost(loss) function} = \frac{1}{m}\sum_{i=1}^{m}(H(x_i)-y_i)^2$$
      • 여기서 \(H(x)=Wx+b\)이고 위 식에 대입하면 cost(loss) function은 \(W\)와 \(b\)의 함수가 된다.
$$\textrm{cost(loss)}(W,b) = \frac{1}{m}\sum_{i=1}^{m}(H(x_i)-y_i)^2$$
 

Linear Regression 학습의 목표: cost(loss) 함수의 값이 최소가 되는 \(W\)와 \(b\)를 찾는 것이다.

$$\textrm{minimize}_{\substack{W,b}}\textrm{cost(loss)}(W,b)$$
  • 이미 만들어져 있는 많은 알고리즘들이 있다.
  • 가장 대표적인 알고리즘은 경사 하강법(Gradient Descent Algorithm)이다.

 

Gradient Descent Algorithm(경사 하강법) 개념 (출처: 위키피디아)

  • 경사 하강법은 1차 근삿값 발견용 최적화 알고리즘이다.
  • 기본 아이디어는 함수의 기울기(경사: gradient)를 구하여 기울기가 낮은 쪽으로 계속 이동시켜서 극값에 이를 때까지 반복하는 것
  • 최적화할 함수 \(f(\mathbf{x})\)에 대하여 먼저 시작점 \(\mathbf{x}_0\)를 정한다.
  • 현재의 점 \(\mathbf{x}_i\)가 주어졌을 때, 그 다음으로 이동할 점인 \(\mathbf{x}_{i+1}\)을 다음과 같이 계산한다.
    • \(\gamma_i\)는 이동할 거리를 조절하는 매개변수이다.

\begin{equation}\mathbf{x}_{i+1}=\mathbf{x}_i - \gamma_i\nabla f(\mathbf{x}_i)\tag{1}\end{equation}

  • 아래 그림은 경사 하강법을 실행하는 모습으로 \(\mathbf{x}_0\)에서 시작하여, 경사가 낮아지는 쪽으로 이동하여 차례대로 \(\mathbf{x}_1,\mathbf{x}_2,\mathbf{x}_3,\mathbf{x}_4\)를 얻게된다.

 

  • 이 알고리즘의 수렴 여부는 \(f\)의 성질과 \(\gamma_i\)의 선택에 따라 달라진다.
  • 이 알고리즘은 극소점(local minimum)으로 수렴한다.
    • 따라서 구한 값이 전역적인 최적해라는 것을 보장하지 않는다. -> 극소값이 아닌 최소값을 찾을 수 있는 방법이 필요
    • 시작점 \(\mathbf{x}_0\)의 선택에 따라 달라진다.
    • 따라서 다양한 시작점에 대해 여러 번 경사 하강법을 적용하여 그 중 가장 좋은 결과를 선택할 수도 있다.

 

 

 

예제를 통한 경사 하강법 설명

  • 설명의 편의를 위해 가설을 다음과 같이 bias \(b\)를 없애 간단하게 만든다.
  • 가설 : \(H(x)=Wx\)
  • cost(loss) 함수는 \(W\)의 함수로 다음과 같이 표현된다.

 

\begin{eqnarray}\textrm{cost(loss)}(W) &=& \frac{1}{m}\sum_{i=1}^{m}(H(x_i)-y_i)^2\\&=&\frac{1}{m}\sum_{i=1}^{m}(W\cdot x_i-y_i)^2\end{eqnarray}

 

  • 아래와 같은 데이터에 대하여 위의 cost(loss) 함수 값을 구해보자
    • \(W=1\)일 때,
    • \begin{eqnarray}\textrm{cost(loss)}(1) &=& \frac{1}{3}\big( (1\times 1 - 1)^2 + (1\times 2 - 2)^2 + (1\times 3 - 3)^2\big)\\&= &\frac{1}{3}(0^2+0^2+0^2)\\&=&0\end{eqnarray}
    • \(W=0\)일 때,

\begin{eqnarray}\textrm{cost(loss)}(0) &=& \frac{1}{3}\big( (0\times 1 - 1)^2 + (0\times 2 - 2)^2 + (0\times 3 - 3)^2\big)\\&=&\frac{1}{3}(1^2+2^2+3^2)\\&=&\frac{14}{3}\\&\fallingdotseq &4.67\end{eqnarray}

    • \(W=2\)일 때,

\begin{eqnarray}\textrm{cost(loss)}(2) &=& \frac{1}{3}\big( (2\times 1 - 1)^2 + (2\times 2 - 2)^2 + (2\times 3 - 3)^2\big)\\&=&\frac{1}{3}(1^2+2^2+3^2)\\&=&\frac{14}{3}\\&\fallingdotseq &4.67\end{eqnarray}

 

  • 위에서 구한 값을 토대로 \(\textrm{cost(loss)}(W)\) 함수를 그래프로 그려보면 다음과 같이 2차 함수의 그래프로 표현된다.

\begin{eqnarray}\textrm{cost(loss)}(W) &=& \frac{1}{m}\sum_{i=1}^{m}(H(x_i)-y_i)^2\\&=&\frac{1}{m}\sum_{i=1}^{m}(W\cdot x_i-y_i)^2\end{eqnarray}

 

  • 여기서 우리의 목표는 cost(loss) 함수가 최소가 되는 점을 찾는 것이다.
    • 우리가 데이터를 가지고 위의 그래프와 같은 형태의 cost(loss) 함수를 만들어 낼 수 있다면 최소값은 어떻게 찾아낼 수 있을까? -> 미분계수가 최소가 되는 점!!!!
    • 기계적으로 최소가 되는 점을 찾아내야 한다!
  • 최소가 되는 점을 찾아내는 알고리즘 -> 경사를 따라 내려가는 알고리즘
    • 실제로는 구간에서의 극소값을 찾는 것이다!!!
  • Gradient Descent Algorithm
    • \(\textrm{cost(loss)}(W,b)\) 함수를 최소화하는데 많이 사용됨
    • 많은 기계 학습 뿐만 아니라 다른 최소화 문제에 사용됨
    • 주어진 \(\textrm{cost(loss)}(W,b)\) 함수에 대하여 최소가 되는 \(W\)와 \(b\)를 찾을 수 있다.
      • 매개변수 \(W\)와 \(b\)를 바꿔가면서 최소가 되는 점을 찾는 방법
    •  보다 일반적인 함수 \(\textrm{cost(loss)}(w_1, w_2, \ldots, b)\)에 대해서도 적용이 가능

어떻게 극소값을 찾을 수 있을까?

  1. 임의의 초기값에서 시작한다.
    1. \((0,0)\)(또는 다른 값)에서 시작한다.
    2. \(W\)와 \(b\)를 조금씩 바꿔가면서 \(\textrm{cost(loss)}(W,b)\)의 값을 줄여나간다.
  2. 매개변수 \(W\)와 \(b\)를 바꿀 때마다 \(\textrm{cost(loss)}(W,b)\)를 줄일 수 있는 경사(gradient)를 선택한다.
  3. 위의 1~2번을 반복한다.
  • 극소값(local minimum)으로 수렴할 때까지 반복한다.
  • 이 알고리즘의 장점
    • 어떤 점에서 시작하더라도 예외가 있기는 하지만 항상 극소점에 도달할 수 있다.
 

경사도(gradient)를 찾는 방법 -> 미분(differential)

  • 미분을 이용하여 경사도(기울기)를 구한다.
  • 계산을 편하게 하기 위하여 cost(loss) 함수를 약간 변형한다.
    • cost(loss) 함수의 최소값을 구할 때 \(\frac{1}{m}\) 대신 \(\frac{1}{2m}\)을 사용하더라도 같은 의미를 지니기에 큰 문제가 없다.

\begin{eqnarray}\textrm{cost(loss)(W)} = \frac{1}{2m}\sum_{i=1}^{m}(W\cdot x_i-y_i)^2\tag{2}\end{eqnarray}

  • 식 (2)를 GDA의 정의(식 (1))를 따라 식을 전개하면 다음과 같다.
    • \(\alpha\)는 learning rate이다.

\begin{eqnarray} W &=& W - \alpha\frac{\partial}{\partial W}\textrm{cost(loss)}(W)\\&=&W - \alpha\frac{\partial}{\partial W}\Bigg(\frac{1}{2m}\sum_{i+1}^m\big(W\cdot x_i-y_i\big)^2\Bigg)\\&=&W - \alpha\frac{1}{2m}\sum_{i+1}^m2\big(W\cdot x_i-y_i\big)\cdot x_i\\&=&W - \alpha\frac{1}{m}\sum_{i=1}^m\big(W\cdot x_i-y_i\big)\cdot x_i\tag{3}\end{eqnarray}

  •  식 (3)이 완성된 Gradient Descent Algorithm이다.
    • 식 (3)을 여러 번 실행하여 \(W\)의 값이 변화하면 그 값이 cost(loss) 함수를 극소화하는 값이 된다.
    • 식 (3)을 기계적으로 실행만 시키면 cost(loss) 값을 최소화하는 \(W\) 값을 구할 수 있다.
    • 이 과정을 linear regression의 핵심인 모델을 학습시킨다고 한다.

 

경사 하강법의 문제점

  • 아래 그림과 같이 2개의 시작점으로 출발을 하면 도착점이 다르다.
  • 각각 서로 다른 극소점에 도달하게 된다.

 

  • 그러나 우리가 가설로 세웠던 cost(loss) 함수는 아래 그림과 같은 볼록 함수(convex function)이다.
    • 따라서 어느 점에서 출발하더라도 최소값에 도달하게 된다.

 

  • linear regression을 적용하기 전에 반드시 cost(loss) 함수가 볼록 함수인지 확인한한다.
    • 확인만 된다면 편안하게 경사 하강법을 사용할 수 있다.

 

TensorFlow의 개념 잡기 연습

TensorFlow의 개념

  • Data flow graph를 이용하여 산술계산을 위한 오픈 소스 소프트웨어 라이브러리로 파이썬을 통해 사용할 수 있다.


Tensor란?

  • 텐서(tensor) : \(n\)차원 행렬(matrix)

    • 2차원 텐서는 일반적인 \(2\times2\) 행렬이다.

Data Flow Graph

  • 점(node) : 그래프에서 수학 연산을 나타내며 선을 통해 입력받은 데이터를 연산하여 결과를 선으로 출력한다.
  • 선(edge) : 점들을 지나다니는 다차원 데이터 배열(multidimensional data array)로 텐서(tensor)라고 함
  • 데이터 흐름 그래프(data flow graph) : 데이터들이 점을 지나면서 연산이 이루어지고 결국에는 내가 원하는 결과를 얻거나 작업이 이루어지는 과정으로 텐서가 그래프 상에서 돌아다닌다., 즉 텐서 플로우(tensor flow)이다.



TensorFlow 실행

  • TensorFlow를 설치하고, 버전을 확인한다.
>>> import tensorflow as tf
>>> tf.__version__
'1.1.0-rc1'
  • Hello, TensorFlow!를 출력해보자.
    • constant() 함수를 사용해서 점만 1개 있는 그래프를 만든다.
    • 선은 없으며, 점에는 "Hello, TensorFlow!"라는 상수만 있는 연산 그래프이다.
    • 계산 그래프를 실행하기 위해서는
      1. 세션을 만든다.
      2. run() 함수를 사용하여 우리가 만들어 놓은 연산(점)을 실행한다.
      • 결과에서 'Hello, TensorFlow!' 문자열 앞에 있는 b는 바이트 문자열(Bytes literals)을 의미한다.
# constant() 함수로 상수만 있는 연산을 하나 만든다.
# 이 연산은 기본 텐서플로우 그래프에 점(node)으로 추가가 된다.
>>> hello = tf.constant("Hello, TensorFlow!")

# 텐서플로우 세션을 시작한다.
>>> sess = tf.Session()

# 연산을 수행하고 결과를 얻는다.
>>> print(sess.run(hello))
b'Hello, TensorFlow!'
  • 2개의 데이터를 받아 더하는 그래프를 만들어보자.
    • 다음과 같이 a와 b의 값을 더하는 그래프를 만드는 것이다.
    • 오른쪽 그림과 같이 텐서 3과 텐서 4가 선을 따라 이동하여 더하기 연산을 통하여 덧셈 결과값 텐서를 만들어 내는 것이다.

    1. 2개의 입력을 위하여 constant() 함수로 데이터 입력용 연산을 위한 점을 만든다.
    2. 더하기 연산을 위하여 add() 함수로 더하기 연산 점을 만든다.
    3. 세션을 만든다.
    4. run() 함수로 그래프 연산을 한다.
>>> node1 = tf.constant(3.0, tf.float32)
>>> node2 = tf.constant(4.0)  # 암묵적으로 tf.float32로 인식한다.
>>> node3 = tf.add(node1, node2) 

>>> print("점1 = ", node1, "점2 = ", node2)
점1 =  Tensor("Const_4:0", shape=(), dtype=float32) 점2 =  Tensor("Const_5:0", shape=(), dtype=float32)
# 점1과 점2는 모두 Tensor이다!!!

>>> print("점3 = ", node3)
점3 =  Tensor("Add:0", shape=(), dtype=float32)
# 점3도 Tensor이다!!!
>>> sess = tf.Session()

>>> print("sess.run(점1, 점2) = ", sess.run([node1, node2]))
sess.run(점1, 점2) =  [3.0, 4.0]

>>> print("sess.run(점3) = ", sess.run(node3))
sess.run(점3) =  7.0

>>> node4 = node1 + node2   # 'node4 = node1 + node2'라고 해도 된다.
>>> print("sess.run(점4) = ", sess.run(node4))
sess.run(점4) =  7.0

 

TensorFlow의 역학구조

  1. TensorFlow의 연산을 사용하여 그래프를 만든다.
  2. Session() 함수로 세션을 만들고, sess.run() 함수에 데이터를 주고 계산 그래프를 실행하여 연산을 한다.
  3. 결과값이 나와 그래프에 있는 변수들이 업데이트 된다.


TensorFlow에서 변수의 값을 바꾸어 보자.

  • 그래프를 미리 만들어 놓고, 실행하는 단계에서 값을 주고 싶다.
  • placeholder() 함수로 점을 만들어 놓으면 된다.
    1. placeholder() 함수로 변수형 점을 만든다.
    2. run() 함수로 그래프를 실행할 때, feed_dict 변수로 데이터를 입력한다.
>>> a = tf.placeholder(tf.float32)
>>> b = tf.placeholder(tf.float32)
>>> adder_node = a + b

>>> print(sess.run(adder_node, feed_dict = {a: 3, b: 4.5}))
7.5

>>> print(sess.run(adder_node, feed_dict = {a: [1, 3], b: [2, 4]}))
[ 3.  7.]



Tensor란 무엇인가?

  • 텐서는 배열(array)로서 어떤 값이든 될 수 있다.

  • 텐서를 얘기할 때에는 랭크(Rank)와 모양(Shape), 종류(Type)를 사용한다.
    • 랭크 : 몇 차원 배열인가?

    • 모양 : 각각의 원소에 몇 개가 들어있는가?
      • 텐서를 설계할 때 매우 중요하기 때문에 몇 개의 원소를 가지고 있는지 잘 살펴봐야 한다.
      • 텐서의 모양은 파이썬 리스트일 수도 있고, 정수들의 정렬된 집합을 포함하는 튜플(tuple)일 수도 있다.
      • 차원의 개수만큼 숫자들이 리스트 안에 있을 수 있는데, 리스트 안의 각 숫자는 각 차원의 숫자를 의미
        • 각 차원의 값을 None으로 지정하면 길이는 변할 수 있다.
        • tf.shape() 연산으로 모양을 확인할 수 있음

    • 종류 : 데이터의 종류
      • 대부분의 경우 float32를 사용


    • 연산(OP; operation) : 텐서 객체에(또는 텐서 객체를 사용하여) 계산을 수행하는 점(node)이다.
      • 0개 이상의 입력을 받아 0개 이상의 텐서를 반환
      • 입력과 출력이 모두 0개인 연산
        • 텐서플로우에서 연산은 단순한 수학적인 계산 이상으로 상태를 초기화하는 등과 같은 일에 사용됨
        • 모든 점들이 다른 점들과 반드시 연결될 필요는 없음
      • 연산의 생성자는 문자열 매개변수인 name을 입력을 받아들임
        • name 매개변수를 사용하여 문자열로 특정 연산을 참조할 수 있음
        • c = tf.add(a, b, name = 'add_c')
          


  • 기계학습(ML; Machine Learning)이란 무엇인가?
    •  일종의 소프트웨어(프로그램)로 명시적인 프로그램(explicit program)이다.
      • 명시적인 프로그래밍(explicit programming)이란
        • 개발자가 이런 환경에서는 이렇게 반응하고, 저런 환경에서는 저렇게 반응하도록 만드는 것
      • 명시적인 프로그래밍의 한계
        • 어떤 부분에서는 명시적으로, 정확하게 프로그래밍하기가 어려운 경우가 있다.
          • 스팸 필터 : 규칙이 너무나 많아 개발자들이 규칙을 적용하는 것이 어렵다.
          • 자율 주행 : 주행하기에 너무나 많은 규칙을 따라야 하는데 이를 구현하는 것이 어렵다
    • Arthur Samuel의 정의(1959)
      • 규칙을 일일이 프로그래밍하지 말고, 어떤 자료에서 혹은 어떤 현상에서 자동적으로 배우면 어떨까?하는 생각을 함
      • "Field of study that gives computers the ability to learn without being explicitly programmed"
      • 기계학습은 프로그램으로서, 개발자가 일일이 어떻게 하는지 정의하지 않고, 이 프로그램 자체가 어떤 데이터를 보고 학습하여, 학습에서 무언가를 배우는 영역을 갖는 프로그램


  • 학습(Learning)이란 무엇인가?
    • 기계학습 프로그램은 학습을 해야하기 때문에 학습에 필요한 데이터를 제공해야 한다.
    • 학습 방벙에 따라 다음 2가지로 분류한다.
    • 지도 학습(Supervised* Learning): *supervised : 감독하에
      • 미리 표시가 되어 정해져 있는 데이터(labeled data)를 가지고 학습하는 것
      • labeled data를 training set이라고 함
      • training set의 예
        • 고양이의 그림을 주면서 고양이라고 학습을 시킴

      • 기계학습의 가장 일반적인 문제
        • image labeling : 표시된 이미지를 통한 학습
        • 이메일 스팸 필터 : 스팸인지 아닌지 표시된 이메일을 통한 학습
        •  시험성적 예측 : 이전에 시험을 본 사람들이 공부하는데 소요된 시간과 점수를 통한 학습
      • Training data set
        • 어떤 기계학습 프로그램에 표시된 데이터로 학습을 시키면 어떤 모델이 만들어진다. 이 때 표시된 데이터를 training data set이라고 한다.   

 

        • Training data set으로 만들어진 기계학습 모델을 통해 모르는 값에 대한 결과값을 알아낼 수 있다.

        • AlphaGo도 기보를 training data set으로 학습한 기계학습 프로그램

      • 지도 학습는 결과에 따라 분류를 할 수 있다.  
        • 회귀(regression) : 공부한 시간에 따른 시험 점수 예측
          • 다음과 같은 데이터로 학습시킨 다음에 7시간 정도 공부했을 때 몇 점이나 받을까?

            x(공부한 시간)

            y(시험 점수)

            10

             90

             9

             80

             3

             50

             2

             30


        • 이진 분류(binary classification) : 공부한 시간에 따른 시험 점수를 통과와 실패 두 종류로 분류
        • 다중 분류(multi-label classification) : 공부한 시간에 따른 시험 점수를 등급(A, B, C, E, F)으로 분류


    • 비지도 학습(Unsupervised Learning)
      • 어떤 데이터의 경우에는 우리가 일일이 표시(labeling)할 수가 없다.
      • 자동적으로 유사한 뉴스를 모으는 Google news grouping
      • 단어들 간에 비슷한 단어를 모는 기계학습 프로그램의 경우에는 데이터를 보고 스스로 학습을 해야 한다


python.org에서 다운받은 python으로 해보려했는데 scipy 패키지를 설치하는데 결국 실패했다. 이거때문에 하루를 소비했다. ㅠㅠ

그래서 결국 Anaconda Python을 설치했다. 향후 TensorFlow를 사용할 것이기 때문에 3.5버전(이 글을 쓰는 시점에서 python의 최신 버전은 3.6이다.)을 설치했다. 에디터는 손에 익은 PyCharm Edu 버전을 사용한다.


'Predictive Analytics' 카테고리의 다른 글

단순선형회귀  (0) 2019.09.19
대표적인 예측 분석 사례  (0) 2018.04.20
Predictive Analytics  (0) 2018.04.16
Linear Regression Analysis with Python #2  (0) 2017.03.31
Linear Regression Analysis with Python #1  (0) 2017.03.31

http://forensics.tistory.com/1에서는 숫자로만 분석을 했었다. 숫자로만 판단하기에는 다소 어려움이 있기 때문에 그래프를 이용하여 시각적인 분석을 해보자.


그래프를 그리기 위해서 matplotlib 모듈을 이용한다.



matplotlib를 이용하면 기본값으로 영어 폰트가 설정되어 있어 한글이 표현되지 않는다.

그래서 matplotlib의 환경변수를 변경하여 한글이 출력되도록 아래와 같이 한글폰트를 지정해야만 한다.




위의 코드를 실행하면 다음과 같은 그래프를 얻을 수 있다. 파란색 점을 다 지나는 곡선을 찾는 것이 우리의 목표가 되는 것이다.





'Predictive Analytics' 카테고리의 다른 글

단순선형회귀  (0) 2019.09.19
대표적인 예측 분석 사례  (0) 2018.04.20
Predictive Analytics  (0) 2018.04.16
Python 준비  (0) 2017.03.31
Linear Regression Analysis with Python #1  (0) 2017.03.31

파이썬을 이용하여 가장 기본적인 선형회귀분석을 해보도록 한다.

  1. 다음의 표는 어떤 공장의 월별 생산 금액과 전기 사용량을 나타낸다.
  2.  

    생산 금액(억 원) 

    전기 사용량(백만 kWh) 

    1월

    3.52 

    2.48

    2월 

    2.58 

    2.27 

    3월 

    3.31 

    2.47 

    4월 

    4.07 

    2.77 

    5월 

    4.62 

    2.98 

    6월 

    3.98 

    3.05 

    7월 

    4.29 

    3.18 

    8월 

    4.83 

    3.46 

    9월 

    3.71 

    3.03 

    10월 

    4.61 

    3.25 

    11월 

    3.90 

    2.67 

    12월 

    3.20 

     2.53

  3. 월별 생산 금액을 변수 \(x\)로 하여 벡터로 표시하면 \(\mathbf{x}=[x_1, x_2, \ldots, x_{12}]\), 이 때의 전기 사용량을 \(y\)로 하여 벡터로 나타내면 \(\mathbf{y}=[y_1, y_2, \ldots, y_{12}]\)가 되며, 위의 데이터는 다음과 같이 \(x\) \(y\)로 구성된 쌍으로 표현할 수 있다. $$(\mathbf{x},\mathbf{y})=\{(3.52,2.48), (2.58,2.27), \ldots, (3.20, 2.53)\}$$
  4. 이 때 두 변수간에 어떤 상관관계가 있는지 알아보자. 이 때 두 변수 사이의 상관관계가 존재한다면 통계적으로 모델을 작성할 수 있으며, 1차원의 선형모델로 표현할 수 있다면 다음과 같은 수식형태로 쓸 수 있다. $$y_i = \beta_0 + \beta_1\cdot x_i + \epsilon_i$$
  5. 위의 식에서 \(y_i\)는 종속변수(dependent variable), \(x_i\)를 독립변수(independent variable)라고한다. \(\beta_0\)와 \(\beta_1\)의 값은 데이터 \(\mathbf{x}\)와 \(\mathbf{y}\)벡터로 부터 구할 수 있는데, 잘 알고 있다시피 \(\beta_0\)는 \(Y\)축 절편(intercept), \(\beta_1\)는 기울기(slope)라고 한다. 여기서 \(\epsilon_i\)는 오차항으로 실제 데이터와 선형회귀분석의 결과로 나온 1차함수 값과의 오차를 의미한다.
  6. 파이썬에서는 scipy 모듈의 linregress() 함수를 사용하면 쉽게 선형회귀분석 결과값을 얻을 수 있다.


위의 소스코드를 실행하면 다음과 같다. 매출이 4억 원에 근접했던 달은 4월(4.07억 원)과 6월(3.90억 원)로 전기 사용량은 각각 2.77kWh와 3.05kWh였다. 선형회귀분석의 결과값은 2.902kWh로 실제 4억 원의 전기 사용량은 2.77~3.05kWh 범위 안에 있다. 회귀분석을 통한 예측값은 실제 데이터와 오차가 발생할 수 밖에 없다. 이 오차를 줄이기 위해서 정확한 회귀모델을 구해야만 하는 것이다. 



'Predictive Analytics' 카테고리의 다른 글

단순선형회귀  (0) 2019.09.19
대표적인 예측 분석 사례  (0) 2018.04.20
Predictive Analytics  (0) 2018.04.16
Python 준비  (0) 2017.03.31
Linear Regression Analysis with Python #2  (0) 2017.03.31

+ Recent posts