인공지능 응용 공학

텐서플로우 다변수 선형회귀법 예제: Antique Grand farther’s clock

coding art 2023. 1. 3. 13:48
728x90

 

할아버지 시계 입찰가 결정

머신 러닝 분야의 regression 예제들은 통계학과 밀접한 관계가 있ek. 시카고에는 밀을 포함한 곡물 중심의 상품 거래소가 오래전부터 있어 귀중한 거래 데이터들이 기록되어 남아 있다. 아래의 인터넷 주소를 참조해 보자.

 

참조: StatSci.orf

http://www.statsci.org/data/multiple.html

 

이번 절에서 다루려는 할아버지 시계는 희귀한 고가의 골동품으로서 입찰 가격 사례데이터가 연식(Age)과 입찰 참가자 수(bidder)를 파라메터로 하여 상세한 자료를 남기고 있다.

아래의 인터넷 주소를 참조하여 data 파일을 다운하여 사용하기로 한다.

참조:

http://www.statsci.org/data/general/auction.html

 

상태가 좋은 골동품 할아버지 시계의 시카고 경매 시장 입찰가는 골동품의 연시과 경쟁하는 경매자 수의 영향을 받아 결정된다.

Age Bidders Price($)
127 13 1235
115 12 1080
127 7 845
150 9 1522

할아버지 시계 경매 입찰가는 학습을 위한 2개의 데이터로 구성되는 입력에 대해 regression 학습을 해야 한다. 즉 1개의 출력에 대해 2개의 입력 데이터가 필요하므로 다변수(Multi Variables) 예제로 볼 수 있다.

 

할아버지 시계의 제작년도가 오래 될수록 골동품의 가치 상승효과가 있으며 아울러 입찰자 수가 많음에 따라 거품이 끼면서 부동산 분양처럼 입찰 가격이 상승하게 된다. 시장에서의 신품 할아버지 시계의 가격은 2018년 기준 300∼400 달러 선임을 참조하자.

 

할아버지 시계 나이(Age)를 x1 입찰자 수를 x2 실제 입찰 가격을 y 라하고 표의 데이터를 분석하자. 인터넷에 기록된 32개의 데이터 중 단지 4개만을 사용하여 regression 문제를 tensorflow를 사용하여 풀어보도록 하자.

1 import tensorflow as tf
import matplotlib.pyplot as plt

 

표의 자료로부터 다음과 같이 학습을 위한 입력 데이터와 출력 데이타를 준비한다.

random.set_seed를 잡아주면 매번 연산 시 결과가 일정함에 유의하자.

2 tf.random.set_seed(777)
x1 = tf.constant([[127], [115], [127], [150]], dtype=tf.float32) # Age
x2 = tf.constant([ [13], [12], [ 7], [9]], dtype=tf.float32) # bidders
y = tf.constant([[1235], [1080], [845], [1522]], dtype=tf.float32)# Price

 

x1, x2 에 대한 가중치 w1, w2 및 편향 b를 다음과 같이 랜덤 수를 사용하여tensorflow 변수로 설정하자.

3 w1 = tf.Variable(tf.random.normal([1, 1]), dtype=tf.float32)
w2 = tf.Variable(tf.random.normal([1, 1]), dtype=tf.float32)
b = tf.Variable(tf.random.normal([1, 1]), dtype=tf.float32)

 

hypothesis y_hat과 Cost 함수 loss 는 다음과 같이 설정한다. Cost 함수 loss 는 (y_hat - y)를 제곱하여 합친 후 평균을 취하도록 한다.

4 y_hat = x1*w1 + x2*w2 + b # Define the hypothesis
# Define the loss function (mean squared error)
loss = tf.reduce_mean(tf.square(y - y_hat))

 

leraning_rate = 0.00001로 두고 학습을 1000 회 학습을 시키도록 하자. leraning_rate 이 너무 크면 nan(Not a Number, 오버플로우)이 출력 될 수 있다.

5 optimizer = tf.optimizers.SGD(learning_rate=0.00001)

아래의for loop에서 tf.GradientTape() 다음에 다시 y_hat 과 loss 가 다시 출현하여 4번 항 내용과 중복되므로 4번항을 제거해도 무방하다.

6 for i in range(1000):
with tf.GradientTape() as tape:
y_hat = x1*w1 + x2*w2 + b
loss = tf.reduce_mean(tf.square(y - y_hat))
gradients = tape.gradient(loss, [w1, w2, b])
optimizer.apply_gradients(zip(gradients, [w1, w2, b]))
print(w1.numpy(), w2.numpy(), b.numpy())

 

골동품 할아버지의 연식이 120세 인데 경매 참가자가 10명이라면 예상 가격은 얼마인가? 이 문제를 풀어보면 1090 $ 로 계산이 되며 학습 데이터를 늘리고 학습 횟수를 늘리면 10$ 가량 변동되는 가격이 나올 수 있다. 이 기법은 변수가 여럿인 부동산 예측에도 적용이 가능하다.

7 age = 120
bidder = 10
predicted_price = w1.numpy()*age + w2.numpy()*bidder + b.numpy()
print('predicted price= ', predicted_price)
------------------------------------------------------------
[[8.820588]] [[3.2104995]] [[0.28024074]]
predicted price= [[1090.8558]]

regression 작업을 위해 사용된 3차원 점 데이터를 numpy() 수치로 변환하여 출력해 보고 이어서 3차원 공간에 빨간색의 크기가 50으로 scatter 작도해 보자.

 x축(연식), y축(입찰자 수) 눈금을 적절히 결정하여 meshgrid 명령으로 처리하자.

regression 처리된 함수 predicted_price 는 X 와 Y 의 함수로 규정된다.

wireframe  명령으로 predicted_price 면을 녹색으로 작도한다.

아울러 이 면에 상대적인 학습 데이터 점들을 scatter plot  한다.

8 xx = x1.numpy(); yy = x2.numpy(); zz = y.numpy()
print('xx= ', xx); print('yy= ', yy); print('zz= ', zz)


fig = plt.figure(figsize = (10, 7))
plt.title("simple 3D scatter & wireframe plot")
x = np.linspace(100, 160, 10)
y = np.linspace(5, 20, 10)
X, Y = np.meshgrid(x, y)
predicted_price = w1.numpy()*X + w2.numpy()*Y + b.numpy()
ax = plt.axes(projection ='3d')
ax.plot_wireframe(X, Y, predicted_price, color ='green')
ax.scatter3D(xx, yy, zz, color = "red", s=50)
plt.show()

첨부된 grandfartherclock.py 코드를 복사하여 Jupyter에서 셀별로 또는 스크립트 처리 Spyder 로 실행해보자.

 

#grandfartherclock.py

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

tf.random.set_seed(777)
# Define the input and output data
x1 = tf.constant([[127], [115], [127], [150]], dtype=tf.float32)
x2 = tf.constant([ [13],  [12],  [ 7],   [9]], dtype=tf.float32)
y = tf.constant([[1235], [1080], [845], [1522]], dtype=tf.float32)
xx = x1.numpy()
yy = x2.numpy()
zz = y.numpy()

# Define the model variables
w1 = tf.Variable(tf.random.normal([1, 1]), dtype=tf.float32)
w2 = tf.Variable(tf.random.normal([1, 1]), dtype=tf.float32)
b = tf.Variable(tf.random.normal([1, 1]), dtype=tf.float32)

# Define the hypothesis
y_hat = x1*w1 + x2*w2 + b
# Define the loss function (mean squared error)
loss = tf.reduce_mean(tf.square(y - y_hat))

# Define the optimizer
optimizer = tf.optimizers.SGD(learning_rate=0.00001)

# Training loop
for i in range(1000):
  with tf.GradientTape() as tape:
    y_hat = x1*w1 + x2*w2 + b
    loss = tf.reduce_mean(tf.square(y - y_hat))
  gradients = tape.gradient(loss, [w1, w2, b])
  optimizer.apply_gradients(zip(gradients, [w1, w2, b]))

# Print the final values of the model parameters
print(w1.numpy(), w2.numpy(), b.numpy())

age = 120
bidder = 10
predicted_price = w1.numpy()*age + w2.numpy()*bidder + b.numpy()
print('predicted price= ', predicted_price)

print('xx= ', xx)
print('yy= ', yy)
print('zz= ', zz)

# 3D scatter plot & regression surface plot50

fig = plt.figure(figsize = (10, 7))
plt.title("simple 3D scatter & wireframe plot")
x = np.linspace(100, 160, 10)
y = np.linspace(5, 20, 10)
X, Y = np.meshgrid(x, y)
predicted_price = w1.numpy()*X + w2.numpy()*Y + b.numpy()
ax = plt.axes(projection ='3d')
ax.plot_wireframe(X, Y, predicted_price, color ='green')
ax.scatter3D(xx, yy, zz, color = "red", s=50)

plt.show()