저번 포스트까지 Numpy 모듈에 대해 정리를 마쳤다.
이번 포스트에서는 Linear regression에 필요한 정보를 정리 해보고
해당 정보들을 이용해 Linear regression을 구현해보겠다.
Linear regression
머신러닝에서 Linear regression은 종속 변수 y와 한개 이상의 독립 변수 X와의 선형 관계를 모델링하는 방법론이다.
독립 변수는 입력 값이나 원인을 나타내고,
종속 변수는 독립 변수에 의해 영향을 받는 변수다.
종속 변수는 보통 출력값을 나타낸다.
선형 관계를 모델링한다는 것은 1차로 이루어진 직선을 구하는 것이다.
데이터를 가장 잘 설명하는 최적의 직선을 찾아냄으로써 독립 변수와 종속 변수의 관계를 알아내는 과정이다.
독립 변수가 1개인 직선을 정의해보자.
데이터를 가장 잘 설명하는 직선은 실제 데이터 값들(빨간 원)과 최대한 비슷해야한다.
위 그림에서 빨간점과 직선사이의 차이를 줄이는 것이 목적이다.
그 직선과 점의 거리를 cost function이라고 하고 아래의 식으로 정의해보자
여기서 cost function을 최소로 하는 w와 b를 찾아야 한다.
위 이차함수의 최솟값을 구하면 된다.
머신러닝에서는 일반적으로 최솟값을 구할 때 아래 그림처럼 Gradient Descent 방법을 사용한다.
이 방법을 코드를 통해 구현해보자
일단 필요한 함수들을 먼저 import 하고 시작해보겠다.
import sympy #symbol 식을 표현하고 풀기 위해 사용
import numpy #numpy 연산들에 사용
from matplotlib import pyplot #plotting에 사용
w = sympy.Symbol('w', real=True)
f = w**2 + 3*w - 5
처음으로는 기울기 값을 구하는 함수를 먼저 만들어야 한다.
fprime = f.diff(w) #1차 미분
fpnum = sympy.lambdify(w, fprime) #lambda표현식으로 변환
이 다음 w값을 설정하고 반복적으로 최솟값으로 접근하도록 해야 한다.
w = 10.0 # 시작 값
for i in range(1000):
w = w - fpnum(w)*0.01 # 0.01의 step size를 가지고 최솟값을 향해 감
print(w)
#-1.499999....
답은 -1.5인데 거의 같은 값까지 접근한 것을 볼 수 있다.
이제 구현을 위해 linear한 관계의 dataset을 만들어 보겠다.
normal distribution을 추가해서 약간의 noise도 추가해서 생성해보겠다.
x_data = numpy.linspace(-5, 5, 100) #x는 -5에서 5까지 범위의 100개 elements
w_true = 2
b_true = 20
y_data = w_true*x_data + b_true + numpy.random.normal(size=len(x_data))
#y=2x+20 노이즈 추가
pyplot.scatter(x_data,y_data);
총 100개의 data를 만들었다.
이제 코드로 접근해보겠다.
먼저 cost function을 정의하고
w, b, x, y = sympy.symbols('w b x y')
cost_function = (w*x + b - y)**2
cost_function
$$(b+wx−y)2$$
위의 gradent descent예제 처럼 기울기 함수를 구현한다.
grad_b = sympy.lambdify([w,b,x,y], cost_function.diff(b), 'numpy')
grad_w = sympy.lambdify([w,b,x,y], cost_function.diff(w), 'numpy')
이제 준비가 다 되었으니 w와 b를 초기화 하고 각각의 최솟값을 찾아보겠다.
w = 0
b = 0
for i in range(1000):
descent_b = numpy.sum(grad_b(w,b,x_data,y_data))/len(x_data)
descent_w = numpy.sum(grad_w(w,b,x_data,y_data))/len(x_data)
w = w - descent_w*0.01 # with 0.01 the step size
b = b - descent_b*0.01
print(w) # 1.9606494761058575
print(b) # 20.016909755198796
처음 생성했던 값 w=2, b=20과 매우 유사하게 나오는 것을 확인할 수 있다.
이번 포스팅에서는 직접 gradient descent를 구현해서 각 파라미터의 최솟값을 찾는 task를 해보았다.
다음 포스팅에서는 이를 응용하여 실제 데이터로 확인해보겠다.
'Studying > Machine Learning' 카테고리의 다른 글
[머신러닝] Multiple Linear Regression - 연비(MPG) 예측 (0) | 2022.07.07 |
---|---|
[머신러닝] Linear Regression - 지구 온도 변화 분석 (0) | 2022.07.05 |
[머신러닝] 파이썬 Numpy 연산 - Numpy dot, matmul, transpose (1) | 2022.06.25 |
[머신러닝] 파이썬 Numpy - Numpy의 유용한 기능들 (0) | 2022.06.23 |
[머신러닝] 파이썬 Numpy - Numpy indexing과 slicing (0) | 2022.06.21 |
댓글