본문 바로가기

멀티캠퍼스 프로젝트형 AI 서비스 개발 5회차/ML

3/29 화

728x90

화요일!

 

오늘은 어제 배운 Simple Linear Regression(단순 선형 회귀)을 코드로 구현한다.

 

< 순서 >

1. Training Data Set 준비 : Data pre-processing(데이터 전처리). 사용할 수 있는 형태로 준비

2. Linear Regression Model을 정의 : y = Wx+b(예측 모델). hypothesis(가설)

3. 최적의 W(weight, 가중치), b(bias, 편차)를 구하려면 loss function(손실함수)/cost function(비용함수) → MSE

4. Gradient Descent Algorithm(경사하강법) : loss function을 편미분(W, b) × learning rate

5. 반복학습 진행

 

1. Training Data Set의 matrix를 행렬곱 연산으로 한 번에 계산하고 예측치 수식을 2차원으로 바꿔준다. y = XW+b

Python으로 단순 선형 회귀를 구현해보자

import numpy as np

# Training Data Set 준비. x_data -> 독립변수(공부시간)
x_data = np.array([1, 2, 3, 4, 5], dtype=np.float64).reshape(5,1) # (5,-1) 앞의 행이 정해지면 열을 알아서 계산하라 (-1,5)


# t_data -> 정답데이터(시험점수)
t_data = np.array([3, 5, 7, 9, 11], dtype=np.float64).reshape(5,1)


# Weight & Bias 정의
W = np.random.rand(1,1) # 1행 1열짜리(값은 1개) ndarray를 만들고 0과 1 사이의 균등분포에서 실수 난수를 추출
b = np.random.rand(1)


# predict function(예측 함수, 모델, hypothesis)
def predict(x):
    y = np.dot(x,W) + b
    return y


# loss function
def loss_func(input_data): # loss 함수는 W와 b의 함수
    
    input_W = input_data[0].reshape(1,1) # input_data -> [W b]
    input_b = input_data[1]
    
    y = np.dot(x_data, input_W) + input_b # 예측값. dot 메서드는 행렬곱연산. y = XW+b
    
    return np.mean(np.power(t_data - y, 2)) # MSE(평균제곱오차)를 구하자(v). t_data - y -> 오차. power 제곱


# 다변수 함수의 수치미분 코드. input_value = [x y] ndarray로 값이 2개 넘어온다
def numerical_derivative(f,x):

    delta_x = 1e-4
    derivative_x = np.zeros_like(x) # derivative_x : [0.0 0.0]. x의 shape과 같도록 ndarray 만듦

# iterator를 이용해서 입력변수 x에 대한 편미분을 수행
    it = np.nditer(x, flags=['multi_index']) # iterator 객체를 얻어 변수 넣고 flags라는 속성으로 차원 정해주고 반복~

    while not it.finished:
        
        idx = it.multi_index
        tmp = x[idx]

        x[idx] = tmp + delta_x
        fx_plus_delta = f(x)

        x[idx] = tmp - delta_x
        fx_minus_delta = f(x)

        derivative_x[idx] = (fx_plus_delta - fx_minus_delta) / (2 * delta_x)

        x[idx] = tmp
        it.iternext()
        
    return derivative_x


# learning rate의 값을 설정. 초기에는 1e-4 or 1e-3 정도로 설정
learning_rate = 1e-4


# 학습과정을 진행
for step in range(300000):
    
    input_param = np.concatenate((W.ravel(), b.ravel()), axis=0) # [W b] Numpy array. 1차원을 열 방향으로 붙여라
    derivative_result = learning_rate * numerical_derivative(loss_func, input_param) # 편미분한 값에 learning_rate를 곱함
    
    W = W - derivative_result[0].reshape(1,1) # 새로운 W'
    b = b - derivative_result[1] # 새로운 b'
    
    if step % 30000 == 0: # loss 값이 실제로 줄어드는지 10번만 출력해서 확인하자
        input_param = np.concatenate((W.ravel(), b.ravel()), axis=0) # loss 값 구하기 위해
        print('W : {}, b:{}, loss:{}'.format(W, b, loss_func(input_param)))
# 6시간 공부하면 몇 점일지를 예측해보자

predict_date = predict(np.array([[6]])) # 인자를 2차원으로 줘야 행렬곱연산이 일어남
print('6시간 공부했을 때 점수 : ', predict_date)

 

2. 사이킷런(Scikit-Learn) 라이브러리로 단순 선형 회귀를 구현해보자

Anaconda Prompt

conda activate machine
pip install scikit-learn
from sklearn import linear_model

x_data = np.array([1, 2, 3, 4, 5], dtype=np.float64).reshape(5,1) # Training Data Set
t_data = np.array([3, 5, 7, 9, 11], dtype=np.float64).reshape(5,1)

model = linear_model.LinearRegression() # model 생성

model.fit(x_data, t_data) # model 학습

print('W : {}, b:{}'.format(model.coef_, model.intercept_)) # W : [[2.]], b:[1.]. W, b 구해보자

print(model.predict(np.array([[6]]))) # [[13.]]. model을 이용한 예측

 

3. 만약 독립변수가 많아 loss 함수가 2차원 포물선으로 그려지지 않을 경우, W를 어떻게 구할까?

 

경사하강법(Gradient Descent Alogrithm)을 이용하면, Global Minima를 구하는 것이 아닌 Local Minima에 갇힐 수 있음 → loss 함수는 특정한 형태(볼록 함수, convex function)를 가져야 함!

 

4. Ozone량 예측하는 모델

Python으로 단순 선형 회귀를 구현해보자

# Ozone량 예측하는 모델을 만들어 보자
import numpy as np
import pandas as pd

# 다변수 함수의 수치미분 코드
def numerical_derivative(f,x):

    delta_x = 1e-4
    derivative_x = np.zeros_like(x)

# iterator를 이용해서 입력변수 x에 대한 편미분을 수행
    it = np.nditer(x, flags=['multi_index'])

    while not it.finished:
        
        idx = it.multi_index
        tmp = x[idx]

        x[idx] = tmp + delta_x
        fx_plus_delta = f(x)

        x[idx] = tmp - delta_x
        fx_minus_delta = f(x)

        derivative_x[idx] = (fx_plus_delta - fx_minus_delta) / (2 * delta_x)

        x[idx] = tmp
        it.iternext()
        
    return derivative_x

# Raw Data Set Loading
df = pd.read_csv('./data/ozone.csv')
# display(df.head())

# Ozone(오존량) : 종속변수
# Solar.R(태양광세기), Wind, Temp : 독립변수. Linear Regression으로 하나의 독립변수만 사용함
training_data = df[['Ozone', 'Temp']]
# display(training_data)
# print(training_data.shape) # (153, 2)
# training_data.info() # 결치값이 존재함. 데이터가 충분히 많다면 삭제 or 대체

training_data.dropna(how='any', inplace=True) # 결치가 존재하는 행을 삭제
# training_data.info()

x_data = training_data['Temp'].values.reshape(-1,1) # Training Data Set
t_data = training_data['Ozone'].values.reshape(-1,1)

# Weight, bias
W = np.random.rand(1,1)
b = np.random.rand(1)

# loss function
def loss_function(input_data):
    W = input_data[0].reshape(1,1)
    b = input_data[1]
    
    y = np.dot(x_data, W) + b
    return np.mean(np.power(t_data-y,2))

# predict
def predict(x):
    y = np.dot(x, W) + b
    return y

# learning_rate
learning_rate = 1e-4

# 반복 학습
for step in range(300000):
    
    input_param = np.concatenate((W.ravel(), b.ravel()), axis=0)
    derivative_result = learning_rate * numerical_derivative(loss_func, input_param)
    
    W = W - derivative_result[0].reshape(1,1)
    b = b - derivative_result[1]
    
    if step % 30000 == 0:
        input_param = np.concatenate((W.ravel(), b.ravel()), axis=0)
        print('W : {}, b : {}, loss : {}'.format(W, b, loss_func(input_param)))

# 학습종료 후 예측
predict_data = predict(np.array([[62]]))
print('온도가 62일 때 오존량 : {}'.format(predict_data)) # [[16.90439304]]
# 그래프로 표현해보자
import matplotlib.pyplot as plt

plt.scatter(x_data.ravel(), t_data.ravel())
plt.plot(x_data.ravel(), x_data.ravel()*W.ravel() + b, color='r')
plt.show()

 

 

5. 사이킷런 라이브러리로 단순 선형 회귀를 구현해보자

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import linear_model
import warnings
warnings.filterwarnings('ignore')

# Raw Data Set Loading
df = pd.read_csv('./data/ozone.csv')

# Linear Regression으로 하나의 독립변수만 사용함
training_data = df[['Ozone', 'Temp']]

training_data.dropna(how='any', inplace=True) # 결치가 존재하는 행을 삭제

x_data = training_data['Temp'].values.reshape(-1,1) # Training Data Set
t_data = training_data['Ozone'].values.reshape(-1,1)

# model 생성
model = linear_model.LinearRegression()

# model 학습
model.fit(x_data, t_data)

# 예측
result = model.predict(np.array([[62]]))
print('sklearn으로 구한 온도가 62도 일 때의 오존량 : {}'.format(result)) # [[3.58411393]]

# 그래프 표현
plt.scatter(x_data.ravel(), t_data.ravel())
plt.plot(x_data.ravel(), 
         x_data.ravel()*model.coef_.ravel() + model.intercept_, color='g')
plt.show()

6. 왜 Python으로 구현한 것과 사이킷런 라이브러리로 구현한 것의 모양이 다를까? Data 처리가 잘 되지 않았기 때문에!

 

1. 3/15 화 2. 3/16 수 3. 3/17 목 4. 3/18 금 5. 3/21 월
ML
환경 설정

(아나콘다, 주피터 노트북),
Pandas,

Numpy,
ndarray
ML
Numpy,

행렬곱연산,
전치행렬,
iterator,
axis,
Pandas,
Series,
DataFrame
ML
Pandas,
DataFrame,

함수들
ML
Pandas,
데이터 분석,
데이터 전처리
ML
Pandas,
데이터 전처리,
수행평가
6. 3/22 화 7. 3/23 수 8. 3/24 목 9. 3/25 금 10. 3/28 월
ML
데이터 시각화,
Matplotlib,
기술통계
ML
기술통계
ML
기술통계,
머신러닝
ML
미분,
Regression
ML
머신러닝 기법들,
Regression
11. 3/29 화 12. 3/30 수 13. 3/31 목 14. 4/1 금 15. 4/4 월
ML
Regression 구현
(Python, Scikit-Learn)
ML
Outlier,
Tensorflow,
Zscore
     

* Python 코드로 모델을 구현할 줄 알아야, 라이브러리를 개선하고 응용할 수 있다!

728x90

'멀티캠퍼스 프로젝트형 AI 서비스 개발 5회차 > ML' 카테고리의 다른 글

3/31 목  (0) 2022.03.31
3/30 수  (0) 2022.03.30
3/28 월  (0) 2022.03.28
3/25 금  (0) 2022.03.27
3/24 목  (0) 2022.03.24