donut

'다중선형회귀'에 해당되는 글 1건

  1. Python Tensorflow 다중선형회귀

Python Tensorflow 다중선형회귀

Tensorflow/ML

 

 

 

Tenserflow

Multi_Valriable_linear_regression_study

다변량 선형 회귀

안녕하세요. 이번 포스팅은 지난번 단순선형회귀에 이은 다변량 선형회귀 입니다,
단순 선형회귀는, 주어지는 변수의 값이 하나 일때, 활용하는 수학적 해 도출방법 이라면,
다변량 선형회귀는, 주어지는 변수의 값이 여러개일경우, 활용하는 수학적 해 도출방법 입니다.

두 가지의 차이점 중에는 기울기의 갯수가 차이가 나는데요,
단순은 W의 값이 하나라면, 다변량은 변수의 갯수만큼 W도 동일하게 필요합니다.

필요한 모듈 세팅

In [244]:
#필요한 모듈 세팅
import tensorflow as tf
import numpy as np
#텐서플로우 버전 확인
print(tf.__version__)
 
2.1.0
 

tf.random.set.seed()

tf.random.set.seed()에 대해 잠시 알아보겠습니다. 초기값을 지정해주는 역활을 합니다.

아래 예 2가지를 보면, tf.random.set.seed()를 지정하지 않았을땐 난수가 계속 생성되는데, tf.random.set.seed()를 지정하면, 난수가 고정되어 나오는 걸 확인 할 수있습니다.

In [245]:
for i in range(10):
    a = tf.Variable(tf.random.uniform((1,), -1.0, 1.0))
    b = tf.Variable(tf.random.uniform((1,), -1.0, 1.0))
    print(a.numpy(),b.numpy())
 
[-0.9770107] [0.591779]
[0.30865002] [-0.05309939]
[-0.1618216] [-0.49061823]
[0.17057109] [0.10782146]
[0.43805528] [0.7680428]
[0.12983441] [-0.6269345]
[0.24475026] [0.36410904]
[-0.95035076] [-0.19002509]
[-0.8641336] [-0.9135275]
[0.48756957] [0.6700702]
In [246]:
for i in range(10):
    tf.random.set_seed(0)
    a = tf.Variable(tf.random.uniform((1,), -1.0, 1.0))
    b = tf.Variable(tf.random.uniform((1,), -1.0, 1.0))
    print(a.numpy(),b.numpy())
 
[-0.41604972] [0.11082816]
[-0.41604972] [0.11082816]
[-0.41604972] [0.11082816]
[-0.41604972] [0.11082816]
[-0.41604972] [0.11082816]
[-0.41604972] [0.11082816]
[-0.41604972] [0.11082816]
[-0.41604972] [0.11082816]
[-0.41604972] [0.11082816]
[-0.41604972] [0.11082816]
 

2변량 선형회귀 -1.변수 선언

In [247]:
# tf.random.set.seed()는 변수, 여기선 W1,W2값을 고정해 주는 역활을 합니다.
# 해당 코드를 몇번을 반복해도 같은 값을 돌려주게 됩니다.
tf.random.set_seed(0)

#변수 x1, x3 선언
x1_data = [5.,0.,3.,4.,5.]
x2_data = [4.,3.,1.,2.,0.]
#정답인 y값 선언
y_data  = [1.,2.,3.,4.,5.]
 

2변량 선형회귀 -2.W초기값, learning_rate할당

In [248]:
#변수가 2개이기 때문에 W(가중치, 기울기)도 2개를 선언해 줍니다.
#tf.random.uniform 균등분포를 따르는 난수를 생성해줍니다, -10~10사이의수
W1 = tf.Variable(tf.random.uniform((1,), -10.0, 10.0))
W2 = tf.Variable(tf.random.uniform((1,), -10.0, 10.0))
b = tf.Variable(tf.random.uniform((1,), -10, 10.0))

learning_rate=tf.Variable(0.001)
 

2변량 선형회귀 -3.경사하강법으로 cost, W1,W2,b도출

In [249]:
#단순 선형회귀에서 사용한 경사하강법과 동일합니다.
for i in range(1000+1):
    #tape에 모든 with연산기록 저장
    with tf.GradientTape() as tape:
        #hypothesis(추론,공식)을 전해줍니다.
        hypothesis = W1 * x1_data + W2* x2_data+b
        cost = tf.reduce_mean(tf.square(hypothesis - y_data))
    W1_grad, W2_grad, b_grad = tape.gradient(cost, [W1,W2, b])
    W1.assign_sub(learning_rate * W1_grad)
    W2.assign_sub(learning_rate * W2_grad)
    b.assign_sub(learning_rate * b_grad)
    
    if i % 50 ==0:
        print("{:5} | {:10.6f} | {:10.4f} | {:10.4f} | {:10.6f}".format(
          i, cost.numpy(), W1.numpy()[0], W2.numpy()[0], b.numpy()[0]))
 
    0 | 522.226257 |    -3.9860 |     1.1794 |  -6.053674
   50 |  35.391602 |    -0.0499 |     2.3939 |  -5.107175
  100 |  19.473316 |     0.7045 |     2.1722 |  -4.908693
  150 |  15.734917 |     0.9508 |     1.8387 |  -4.810085
  200 |  13.626745 |     1.0862 |     1.5601 |  -4.720336
  250 |  12.331724 |     1.1771 |     1.3430 |  -4.628006
  300 |  11.495358 |     1.2404 |     1.1748 |  -4.532677
  350 |  10.919973 |     1.2838 |     1.0439 |  -4.435214
  400 |  10.494151 |     1.3123 |     0.9411 |  -4.336432
  450 |  10.155027 |     1.3298 |     0.8595 |  -4.236956
  500 |   9.867114 |     1.3391 |     0.7937 |  -4.137262
  550 |   9.610357 |     1.3423 |     0.7400 |  -4.037704
  600 |   9.373407 |     1.3409 |     0.6954 |  -3.938541
  650 |   9.149802 |     1.3361 |     0.6576 |  -3.839968
  700 |   8.935852 |     1.3288 |     0.6250 |  -3.742122
  750 |   8.729431 |     1.3197 |     0.5963 |  -3.645109
  800 |   8.529282 |     1.3092 |     0.5707 |  -3.549000
  850 |   8.334658 |     1.2978 |     0.5474 |  -3.453849
  900 |   8.145084 |     1.2857 |     0.5259 |  -3.359690
  950 |   7.960254 |     1.2732 |     0.5058 |  -3.266548
 1000 |   7.779940 |     1.2603 |     0.4867 |  -3.174435
 

2변량 선형회귀(메트릭스)

In [250]:
#이번엔 같은 예제를 메트릭스를 활용하여 도출하겠습니다.
#메트릭스를 사용하지 않았을때(위예시)와 비교하면서 확인해야합니다.

#x와, y데이터를 따로따로 주었습니다.
x_data = [
    [5.,0.,3.,4.,5.],
    [4.,3.,1.,2.,0.]
]

y_data = [1.,2.,3.,4.,5.]
tf.random.set_seed(0)


W = tf.Variable(tf.random.uniform((1,2), -10.0, 10.0))
b = tf.Variable(tf.random.uniform((1,), -10.0, 10.0))

learning_rate = tf.Variable(0.001)

for i in range(1000+1):
    with tf.GradientTape() as tape:
        hypothesis = tf.matmul(W, x_data) + b 
        cost = tf.reduce_mean(tf.square(hypothesis - y_data))

        W_grad, b_grad = tape.gradient(cost, [W, b])
        W.assign_sub(learning_rate * W_grad)
        b.assign_sub(learning_rate * b_grad)
    if i % 50 ==0:
        print("{:5} | {:10.6f} | {:10.4f} | {:10.4f} | {:10.6f}".format(
            i, cost.numpy(), W.numpy()[0][0], W.numpy()[0][1], b.numpy()[0]))
        
 
    0 | 858.094421 |    -3.9484 |    -5.7427 |   1.163832
   50 |  29.465967 |     0.4849 |    -2.7273 |   2.405365
  100 |   7.518828 |     0.9309 |    -1.9451 |   2.634386
  150 |   4.350302 |     0.8506 |    -1.5717 |   2.709365
  200 |   2.751280 |     0.7300 |    -1.3228 |   2.755810
  250 |   1.850505 |     0.6302 |    -1.1412 |   2.793313
  300 |   1.339502 |     0.5533 |    -1.0063 |   2.825848
  350 |   1.048183 |     0.4946 |    -0.9060 |   2.854856
  400 |   0.880757 |     0.4499 |    -0.8315 |   2.881201
  450 |   0.783236 |     0.4156 |    -0.7763 |   2.905494
  500 |   0.725190 |     0.3891 |    -0.7357 |   2.928197
  550 |   0.689464 |     0.3686 |    -0.7060 |   2.949652
  600 |   0.666392 |     0.3525 |    -0.6845 |   2.970117
  650 |   0.650519 |     0.3398 |    -0.6691 |   2.989786
  700 |   0.638773 |     0.3295 |    -0.6583 |   3.008808
  750 |   0.629419 |     0.3212 |    -0.6509 |   3.027293
  800 |   0.621478 |     0.3143 |    -0.6461 |   3.045323
  850 |   0.614397 |     0.3085 |    -0.6432 |   3.062964
  900 |   0.607862 |     0.3035 |    -0.6418 |   3.080263
  950 |   0.601695 |     0.2991 |    -0.6414 |   3.097257
 1000 |   0.595795 |     0.2953 |    -0.6418 |   3.113975
 

3변량 단순 선형회귀

In [251]:
#값 고정 역활
tf.random.set_seed(0)


# 데이터 세팅
x1 = [ 60.,  91.,  78.,  64.,  74.]
x2 = [ 70.,  87.,  60.,  80.,  67.]
x3 = [ 73.,  92.,  93., 99.,  71.]
Y  = [130., 170., 160., 170., 150.]

# 변수만큼 w갯수 세팅
w1 = tf.Variable(tf.random.normal((1,)))
w2 = tf.Variable(tf.random.normal((1,)))
w3 = tf.Variable(tf.random.normal((1,)))
b  = tf.Variable(tf.random.normal((1,)))


learning_rate = 0.000001
print("epoch | cost")
#경사하강법
for i in range(1000+1):
    with tf.GradientTape() as tape:
        hypothesis = w1* x1 + w2*x2 + w3*x3 + b
        cost =tf.reduce_mean(tf.square(hypothesis -Y))
        
    w1_grad, w2_grad, w3_grad, b_grad = tape.gradient(cost, [w1,w2,w3,b])
    
    w1.assign_sub(learning_rate * w1_grad)
    w2.assign_sub(learning_rate * w2_grad)
    w3.assign_sub(learning_rate * w3_grad)
    b.assign_sub(learning_rate * b_grad)
    
    if i % 500 == 0:
        print("{:5} | {:12.4f}".format(i, cost.numpy()))
 
epoch | cost
    0 |   15281.1172
  500 |     625.5705
 1000 |     538.3800
 

3변량 단순 선형회귀(메트릭스)

In [252]:
#np배열로 x와 y 선언
data = np.array([
    # X1,   X2,    X3,   y
    [ 60.,  70.,  73., 130. ],
    [ 91.,  87.,  92., 170. ],
    [ 78.,  60.,  93., 160. ],
    [ 64.,  80., 99., 170. ],
    [ 74.,  67.,  71., 150. ]
], dtype=np.float32)

# 슬라이스로, 엑스와, y를 명확히 선언및 대입
X = data[:, :-1]
y = data[:, [-1]]

#x의 변수가 3개인것을 주의
W = tf.Variable(tf.random.normal((3, 1)))
b = tf.Variable(tf.random.normal((1,)))

learning_rate = 0.000001

# hypothesis, prediction function
def predict(X):
    return tf.matmul(X, W) + b

print("epoch | cost")

n_epochs = 1000
for i in range(n_epochs+1):
    # tf.GradientTape() to record the gradient of the cost function
    with tf.GradientTape() as tape:
        cost = tf.reduce_mean((tf.square(predict(X) - y)))

    # calculates the gradients of the loss
    W_grad, b_grad = tape.gradient(cost, [W, b])

    # updates parameters (W and b)
    W.assign_sub(learning_rate * W_grad)
    b.assign_sub(learning_rate * b_grad)

    if i % 50 ==0:
        print("{:5} | {:10.6f} | {:10.4f} | {:10.4f} | {:10.6f}".format(
            i, cost.numpy(), W.numpy()[0][0], W.numpy()[1][0], b.numpy()[0]))
        
 
epoch | cost
    0 | 2483.050293 |     1.6077 |     2.4433 |  -1.174632
   50 | 812.191284 |     1.4626 |     2.2968 |  -1.176452
  100 | 760.821167 |     1.4322 |     2.2640 |  -1.176727
  150 | 749.294678 |     1.4199 |     2.2491 |  -1.176760
  200 | 738.898804 |     1.4105 |     2.2370 |  -1.176755
  250 | 728.683472 |     1.4015 |     2.2254 |  -1.176743
  300 | 718.622498 |     1.3928 |     2.2140 |  -1.176731
  350 | 708.713074 |     1.3841 |     2.2026 |  -1.176719
  400 | 698.951843 |     1.3756 |     2.1914 |  -1.176707
  450 | 689.338745 |     1.3671 |     2.1801 |  -1.176695
  500 | 679.869019 |     1.3587 |     2.1690 |  -1.176683
  550 | 670.542236 |     1.3504 |     2.1579 |  -1.176671
  600 | 661.355774 |     1.3421 |     2.1468 |  -1.176659
  650 | 652.306458 |     1.3340 |     2.1359 |  -1.176647
  700 | 643.393311 |     1.3259 |     2.1250 |  -1.176635
  750 | 634.614380 |     1.3179 |     2.1141 |  -1.176623
  800 | 625.966370 |     1.3100 |     2.1034 |  -1.176612
  850 | 617.448181 |     1.3022 |     2.0927 |  -1.176600
  900 | 609.058105 |     1.2944 |     2.0820 |  -1.176588
  950 | 600.792847 |     1.2867 |     2.0715 |  -1.176576
 1000 | 592.652344 |     1.2791 |     2.0609 |  -1.176564
 

다변량 선형회귀 요약

다변량 선형회귀는 변수를 직접 선언하는것과, 메트릭스를 통해 선언 하는 두가지 방법이 있다.

전자는 변수가 많을 경우 하나하나 모두 세팅을 해줘야하는 반면,
후자는 변수가 많아도 메트릭스를 사용해 한번만 세팅이 가능하다.

더 빠른 결과, 정확도가 높은 결과를 도출 할 수있다.

 

다변량 선형회귀 확인 및 예측(바로 위 예제를 통한)

In [253]:
#y값 확인
y
Out[253]:
array([[130.],
       [170.],
       [160.],
       [170.],
       [150.]], dtype=float32)
In [254]:
#X값 확인
X
Out[254]:
array([[60., 70., 73.],
       [91., 87., 92.],
       [78., 60., 93.],
       [64., 80., 99.],
       [74., 67., 71.]], dtype=float32)
In [255]:
#b값 확인
b
Out[255]:
<tf.Variable 'Variable:0' shape=(1,) dtype=float32, numpy=array([-1.1765639], dtype=float32)>
 

def predict(X): return tf.matmul(X, W) + b

In [256]:
#predict공식을 통한 해 도출
predict(X).numpy()
Out[256]:
array([[145.7387 ],
       [201.1421 ],
       [127.85293],
       [145.07324],
       [159.49405]], dtype=float32)
In [257]:
#x1,x2,x3값 할당한 후 예측값
predict([[ 1.,  1.,  4.]]).numpy()
Out[257]:
array([[-1.8966974]], dtype=float32)
In [258]:
#2개의 해 동시 도출
predict([[ 1.,  1.,  4.],[ 145.,  50.,  50.]]).numpy()
Out[258]:
array([[ -1.8966974],
       [236.59372  ]], dtype=float32)
In [259]:
#3개의 해 동시 도출
#특히 마지막 배열은 최초 선언시 주었던 x값임
predict([[ 1.,  1.,  4.],[ 145.,  50.,  50.],[ 74.,  67.,  71.]]).numpy()
Out[259]:
array([[ -1.8966974],
       [236.59372  ],
       [159.49405  ]], dtype=float32)
 

해당 포스팅은 부스트코스 강의와, 텐서플로우공식 홈페이지를 참고하여 작성하였습니다.

In [ ]:
 

'Tensorflow > ML' 카테고리의 다른 글

Tensorflow 다중선형회귀 공부  (0) 2020.08.07
Python Logistic Regression  (0) 2020.07.28
Python Tensorflow 단순선형회귀  (0) 2020.07.20