-
TensorFlow 기초 18 - 다항회귀(Polynomial Regression)TensorFlow 2022. 12. 2. 15:32
최소제곱법으로 회귀선 구하기 방법과 tf로 회귀선 구하기 방법2로 나눠서 작성했다.
# 다항회귀 : Polynomial Regression - 비선형 데이터인 경우 다항식을 이용하여 다항회귀 처리 가능 # tesnorflow를 이용하여 2차함수 회귀선 그리기 import tensorflow as tf import numpy as np import matplotlib.pyplot as plt plt.rc('font', family='malgun gothic') plt.rcParams['axes.unicode_minus'] = False import random """ # 다항 회귀 연습용 데이터 : 지역별 인구증가율과 고령인구비율(통계청 시각화 자료에서 발췌) x = [0.3, -0.78, 1.26, 0.03, 1.11, 0.24, -0.24, -0.47, -0.77, -0.37, -0.85, -0.41, -0.27, 0.02, -0.76, 2.66] y = [12.27, 14.44, 11.87, 18.75, 17.52, 16.37, 19.78, 19.51, 12.65, 14.74, 10.72, 21.94, 12.83, 15.51, 17.14, 14.42] # a, b, c 세 개의 변수 선언 a = tf.Variable(random.random()) b = tf.Variable(random.random()) c = tf.Variable(random.random()) # 잔차 제곱 평균 반환 함수 def compute_loss(): y_pred = a * x * x + b * x + c # yhat = ax² + bx + c loss = tf.reduce_mean((y - y_pred) ** 2) return loss optimizer = tf.keras.optimizers.Adam(learning_rate=0.05) for i in range(1000): optimizer.minimize(compute_loss, var_list=[a,b,c]) if i % 100 == 99: print(i, 'a :', a.numpy(), ', b :', b.numpy(), ', loss :', compute_loss().numpy()) line_x = np.arange(min(x), max(x), 0.01) line_y = a * line_x *line_x + b * line_x + c plt.plot(line_x, line_y, 'r-') plt.plot(x, y, 'bo') # 실제값 plt.show() """ # 다항 회귀 연습용 데이터 : 지역별 인구증가율과 고령인구비율(통계청 시각화 자료에서 발췌) plo_inc = [0.3, -0.78, 1.26, 0.03, 1.11, 0.24, -0.24, -0.47, -0.77, -0.37, -0.85, -0.41, -0.27, 0.02, -0.76, 2.66] pop_old = [12.27, 14.44, 11.87, 18.75, 17.52, 16.37, 19.78, 19.51, 12.65, 14.74, 10.72, 21.94, 12.83, 15.51, 17.14, 14.42] # plt.plot(plo_inc, pop_old, 'ro') # plt.xlabel('지역별 인구증가율') # plt.ylabel('고령인구비율') # plt.show() print('최소제곱법으로 회귀선 구하기') x_mean = sum(plo_inc) / len(plo_inc) y_mean = sum(pop_old) / len(pop_old) # 기울기, 절편 계산 a = sum(x - mean(x)) * (y - mean(y)) / sum(x - mean(x))², b = mean(y) - mean(x) * a a = sum([(y - y_mean) * (x - x_mean) for y, x in list(zip(pop_old, plo_inc))]) a /= sum([(x - x_mean)**2 for x in plo_inc]) b = y_mean - x_mean * a print('a :', a, ', b :', b) line_x = np.arange(min(plo_inc), max(plo_inc), 0.01) line_y = a * line_x + b plt.plot(plo_inc, pop_old, 'ro') plt.plot(line_x, line_y, 'b-') plt.xlabel('지역별 인구증가율') plt.ylabel('고령인구비율') plt.show() print('최소제곱법 말고 tf로 회귀선 구하기') a = tf.Variable(random.random()) # 기울기 b = tf.Variable(random.random()) # 절편 # y = ax + b def compute_loss(): ypred = a * plo_inc + b loss = tf.reduce_mean((pop_old - ypred)**2) return loss optimizer = tf.keras.optimizers.Adam(learning_rate=0.05) for i in range(1, 1001): optimizer.minimize(compute_loss, var_list=[a,b]) if i % 100 == 0: print(i, 'a :', a.numpy(), ', b :', b.numpy(), ', loss :', compute_loss().numpy()) line_x = np.arange(min(plo_inc), max(plo_inc), 0.01) line_y = a * line_x + b plt.plot(plo_inc, pop_old, 'ro') plt.plot(line_x, line_y, 'b-') plt.xlabel('지역별 인구증가율') plt.ylabel('고령인구비율') plt.show() <console> 최소제곱법으로 회귀선 구하기 a : -0.355834147915461 , b : 15.669317743971302 최소제곱법 말고 tf로 회귀선 구하기 100 a : 0.20552501 , b : 5.124719 , loss : 120.71144 200 a : 0.004973734 , b : 8.891983 , loss : 55.60652 300 a : -0.14282945 , b : 11.667388 , loss : 25.759094 400 a : -0.24142435 , b : 13.519631 , loss : 14.391236 500 a : -0.30027393 , b : 14.625358 , loss : 10.868128 600 a : -0.33152348 , b : 15.212525 , loss : 9.988979 700 a : -0.34627187 , b : 15.48965 , loss : 9.81301 800 a : -0.3524623 , b : 15.605964 , loss : 9.784808 900 a : -0.35477188 , b : 15.64936 , loss : 9.781202 1000 a : -0.35553664 , b : 15.663731 , loss : 9.780835잔차 제곱 평균 반환 수식 : ax² + bx + c
기울기, 절편 계산 a = sum(x - mean(x)) * (y - mean(y)) / sum(x - mean(x))², b = mean(y) - mean(x) * a

선형일 경우 시각화 다항회귀 방법(비선형)
print('다항회귀 : 비선형일 경우 사용') a = tf.Variable(random.random()) b = tf.Variable(random.random()) c = tf.Variable(random.random()) # 잔차 제곱 평균 반환 함수 def compute_loss2(): y_pred = a * plo_inc * plo_inc + b * plo_inc + c # yhat = ax² + bx + c loss = tf.reduce_mean((pop_old - y_pred) ** 2) return loss optimizer = tf.keras.optimizers.Adam(learning_rate=0.05) for i in range(1000): optimizer.minimize(compute_loss2, var_list=[a,b,c]) if i % 100 == 99: print(i, 'a :', a.numpy(), ', b :', b.numpy(), ', loss :', compute_loss().numpy()) line_x = np.arange(min(plo_inc), max(plo_inc), 0.01) line_y = a * line_x *line_x + b * line_x + c plt.plot(plo_inc, pop_old, 'ro') plt.plot(line_x, line_y, 'b-') plt.xlabel('지역별 인구증가율') plt.ylabel('고령인구비율') plt.show() <console> 다항회귀 : 비선형일 경우 사용 99 a : 3.6720428 , b : -4.853299 , loss : 437.1123 199 a : 3.665368 , b : -5.6806293 , loss : 471.43127 299 a : 2.498158 , b : -4.0594373 , loss : 400.7987 399 a : 1.418247 , b : -2.4626667 , loss : 338.33197 499 a : 0.63158935 , b : -1.296304 , loss : 296.9518 599 a : 0.10912019 , b : -0.52199644 , loss : 271.4591 699 a : -0.21093011 , b : -0.04776672 , loss : 256.6256 799 a : -0.39185336 , b : 0.22029804 , loss : 248.50278 899 a : -0.4862474 , b : 0.36015433 , loss : 244.34001 999 a : -0.531682 , b : 0.42747155 , loss : 242.35472다항회귀 : Polynomial Regression - 비선형 데이터인 경우 다항식을 이용하여 다항회귀 처리 가능

비선형일 경우 시각화 다항회귀 : 딥러닝 네트워크 사용(좋은 방법(간단))
print('다항회귀 : 딥러닝 네트워크 사용') model = tf.keras.Sequential([ tf.keras.layers.Dense(units=64, activation='relu', input_shape=(1,)), tf.keras.layers.Dense(units=32, activation='relu'), tf.keras.layers.Dense(units=1) ]) model.compile(optimizer='adam', loss='mse', metrics=['mse']) model.summary() model.fit(plo_inc, pop_old, epochs=100) print(model.predict(plo_inc).flatten()) line_x = np.arange(min(plo_inc), max(plo_inc), 0.01) line_y = model.predict(line_x) plt.plot(plo_inc, pop_old, 'ro') plt.plot(line_x, line_y, 'b--') plt.xlabel('지역별 인구증가율(%)') plt.ylabel('고령인구비율(%)') plt.show()딥러닝의 경우 알아서 비선형이면 비선형으로 계산되어 나오기 때문에 간단하고 편하다
'TensorFlow' 카테고리의 다른 글
TensorFlow 기초 20 - classification(이항분류 wine dataset), 학습 조기 종료, 모델 학습 시 모니터링 결과를 파일로 저장 (0) 2022.12.02 TensorFlow 기초 19 - classification (0) 2022.12.02 TensorFlow 기초 17 - 현대차 가격예측 모델(function api 사용 방법, GradientTape 객체 사용 방법) (0) 2022.12.02 TensorFlow 기초 16 - AutoMPG dataset으로 자동차 연비 예측 모델(표준화) (0) 2022.12.02 TensorFlow 기초 15 - 활성화 함수, 학습 조기 종료 (0) 2022.12.02