#!/usr/bin/env python # coding: utf-8 # # 2 선형회귀분석 # ## 2.1 변수 간의 관계에 대한 모델 # # * 선형회귀분석 : 주어진 데이터를 가장 잘 나타낼 수 있는 수식(직선)을 찾아내는 방법 # # 변수들 사이의 관계를 분석하는 데 사용하는 통계학적 방법 # # 독립변수 xi, 상수항 b, 종속변수 y 사이의 관계를 모델링하는 방법 # # 단순회귀 : x,y 두 변수 사이의 관계일 경우 # # 다중회귀 : x 여러개의 변수와 y 사이의 관계일 경우 # In[1]: # numpy 패키지 import import numpy as np # In[2]: # 좌표값들을 생성하는 코드 num_points = 1000 vectors_set = [] for i in range(num_points): x1 = np.random.normal(0.0, 0.55) y1 = x1 * 0.1 + 0.3 + np.random.normal(0.0, 0.03) vectors_set.append([x1, y1]) x_data = [v[0] for v in vectors_set] y_data = [v[1] for v in vectors_set] # * 코드 설명 # # y = 0.1 * x + 0.3 관계를 가지는 데이터를 생성 # # 정규분포(normal distribution)을 따르는 약간의 변동값을 더함. # In[3]: get_ipython().run_line_magic('matplotlib', 'inline') # 그래프를 그리는 코드 import matplotlib.pyplot as plt plt.plot(x_data, y_data, 'ro') #plt.legend() plt.show() # ## 2.2 비용함수와 경사 하강법 알고리즘 # # 입력 데이터 x_data로부터 출력 값 y를 추정(estimate)할 수 있는 학습 알고리즘을 훈련시키는 것. # # 입력 데이터 x_data를 이용해 출력 데이터 y_data를 만들 수 있는 최적의 매개변수 W와 b를 찾도록 Tensorflow 코드를 만드는 것이 목적. # # * 비용함수(cost function) = 오차함수(error function) # # 데이터 집합의 값들을 반복하여 적용하면서 매번 더 정확한 결과를 얻기 위해 W와 b 매개변수를 수정하는 것. # # 얼마나 좋은(나쁜) 직선인지 측정하는 함수를 정의. # # * 평균제곱오차(mean square error) # # 실제 값(y)과 알고리즘이 반복마다 추정한 값 사이의 거리를 오차로 하는 값의 평균. # In[4]: import tensorflow as tf W = tf.Variable(tf.random_uniform([1], -1.0, 1.0)) b = tf.Variable(tf.zeros([1])) y = W * x_data + b # * 코드 설명 # # Variable 메서드: 텐서플로우 내부의 그래프 자료구조에 만들어질 하나의 변수를 정의. # In[5]: loss = tf.reduce_mean(tf.square(y - y_data)) # * 코드 설명 # # 우리가 이미 알고 있는 값 y_data와 입력 데이터 x_data에 의해 계산된 y 값 사이의 거리를 제곱한 것의 평균을 계산. # In[6]: optimizer = tf.train.GradientDescentOptimizer(0.5) train = optimizer.minimize(loss) # * 경사하강법(gradient descent) # # 초기 시작점에서 함수의 값이 최소화되는 방향으로 매개변수를 변경하는 것을 반복적으로 수행하는 알고리즘. # # 기울기(gradient)를 음의 방향 쪽으로 진행하면서 반복적으로 최적화를 수행. # # 오차함수는 미분 가능해야 함. # ## 2.3 알고리즘 실행 # In[7]: init = tf.global_variables_initializer() sess = tf.Session() sess.run(init) # 앞에서 변수들을 선언했으므로 다음과 같이 이들을 먼저 초기화해야 함. # In[8]: for step in range(8): sess.run(train) print(sess.run(W), sess.run(b)) # * 코드설명 # # 데이터에 최적화된 직선의 W와 b를 찾기 위해 반복적인 프로세스를 실행. # # 우리가 알고 있는 값과 가까운 W(=0.1), b(=0.3)을 보여줄 것임. # In[9]: plt.plot(x_data, y_data, 'ro') plt.plot(x_data, sess.run(W) * x_data + sess.run(b)) plt.xlabel('x') plt.ylabel('y') plt.show() sess.close() # In[10]: init = tf.global_variables_initializer() sess = tf.Session() sess.run(init) fig, axes = plt.subplots(nrows=4, ncols=2, sharex=True, sharey=True, figsize=(9,12)) for step in range(8): sess.run(train) print(step, sess.run(W), sess.run(b), sess.run(loss)) axes[step//2, step%2].plot(x_data, y_data, 'ro') axes[step//2, step%2].plot(x_data, sess.run(W) * x_data + sess.run(b)) axes[step//2, step%2].set_title("step" + str(step)) plt.show() sess.close() # * 코드설명 # # W = -0.4077, -b = 0.2913으로 시작해서 비용함수를 최소화하도록 매개변수를 조정해 감을 확인. # # cost(비용)가 0.07757 => 0.00146으로 줄어듬을 확인할 수 있음. # * 학습 속도(learning rate) # # 각 반복때마다 W, b를 얼마나 크게 이동할 것인가를 제어. # # 학습 속도를 너무 크게 하면 최소값을 지나쳐 버릴 수 있음. 너무 작게하면 최소값에 다다르는 데 많은 반복이 필요. # # 알고리즘이 제대로 동작하는지 확인하는 좋은 방법: 매 반복마다 오차(cost)가 줄어드는 지 확인. # ## regression.py # In[11]: import numpy as np num_points = 1000 vectors_set = [] for i in range(num_points): x1 = np.random.normal(0.0, 0.55) y1 = x1 * 0.1 + 0.3 + np.random.normal(0.0, 0.03) vectors_set.append([x1, y1]) x_data = [v[0] for v in vectors_set] y_data = [v[1] for v in vectors_set] import matplotlib.pyplot as plt #그래픽 표시 plt.plot(x_data, y_data, 'ro') plt.show() import tensorflow as tf W = tf.Variable(tf.random_uniform([1], -1.0, 1.0)) b = tf.Variable(tf.zeros([1])) y = W * x_data + b loss = tf.reduce_mean(tf.square(y - y_data)) optimizer = tf.train.GradientDescentOptimizer(0.5) train = optimizer.minimize(loss) init = tf.global_variables_initializer() sess = tf.Session() sess.run(init) for step in range(8): sess.run(train) print(step, sess.run(W), sess.run(b)) print(step, sess.run(loss)) #그래픽 표시 plt.plot(x_data, y_data, 'ro') plt.plot(x_data, sess.run(W) * x_data + sess.run(b)) plt.xlabel('x') plt.xlim(-2, 2) plt.ylim(0.1, 0.6) plt.ylabel('y') plt.show()