ML

머신러닝 회귀모델

recordmastd 2024. 11. 14. 17:17

단순선형회귀

 

회귀 분석의 절차

  1. X라는 값이 입력되면 Y=β0+β1X라는 계산식을 통해 값을 산출하는 예측 함수를 정의합니다.
  2. 실제 값 y와 예측 함수를 통해 도출된 예측값 pred_y간의 차이를 계산합니다.
  3. 계산한 차이에 기반하여 β0 β1를 업데이트하는 규칙을 정의하고 이를 바탕으로 β0 β1의 값을 조정합니다.
  4. 위의 과정을 특정 반복 횟수(iteration) 만큼 반복합니다.
  5. 반복적으로 수정된 β0 β1를 바탕으로 Y=β0+β1X라는 회귀식을 정의합니다.

 

실습

  1. beta_0, beta_1, X 를 받아 회귀식을 통해 예측값 y_pred를 계산하여 반환하는 prediction() 함수를 구현합니다.
  2. 반복 횟수만큼 오차(loss)를 계산하고 beta_0,beta_1의 값을 변경하는 함수인 gradient_descent() 를 구현합니다. (앞서 구현한 prediction(), update_beta()를 활용하세요)
  3. 실행 버튼을 눌러 회귀 분석 과정의 시각화를 확인합니다.
  4. 제출 버튼을 눌러 올바른 회귀 알고리즘 구현 여부를 확인합니다.

 

 

beta_0와 beta_1 값을 업데이트 하는 규칙을 정의하는 함수

delta_0 = -(lr * (2 / len(X))) * (np.dot(X.T, loss))
delta_1 = -(lr * (2 / len(X)) * np.sum(loss))
delta_0 = -(lr * (2 / len(X))) * np.sum(y - y_pred)
delta_1 = -(lr * (2 / len(X))) * np.dot(X.T, (y - y_pred))

- 두 함수는 동일하다

- lr: learning late

- np.dot 함수는 벡터나 행렬의 곱셈을 수행하는 NumPy의 함수

 

Gradient Descent

def gradient_descent(X, y, iters, lr):
    
    beta_0 = np.zeros((1,1))
    beta_1 = np.zeros((1,1))
np.zeros(shape, dtype=float)

 

- np.zeros 함수는 모든 요소가 0으로 채워진 배열을 생성하는 NumPy 함수

- np.zeros((1,1))는 numpy에서 (1,1) 형태의 배열을 생성하고, 그 안에 0을 채워넣는 함수

 

 

전체코드

더보기
더보기
import numpy as np
import matplotlib.pyplot as plt

from elice_utils import EliceUtils
elice_utils = EliceUtils()

# 데이터를 생성하고 반환하는 함수입니다.
def load_data():
   
    X = np.array([[8.70153760], [3.90825773], [1.89362433], [3.28730045], [7.39333004], [2.98984649], [2.25757240], [9.84450732], [9.94589513], [5.48321616]])
    y = np.array([[5.64413093], [3.75876583], [3.87233310], [4.40990425], [6.43845020], [4.02827829], [2.26105955], [7.15768995], [6.29097441], [5.19692852]])
   
    return X, y

"""
1.  입력값(X)과 beta_0,beta_1를 바탕으로
    예측값(pre_y)을 계산하여 반환하는 함수를 구현합니다.
   
    회귀 함수 식을 참고하여
    예측값을 계산합니다.
"""
def prediction(beta_0, beta_1, X):
   
    y_pred = beta_0 + beta_1 * X
   
    return y_pred
   

# beta_0와 beta_1 값을 업데이트 하는 규칙을 정의하는 함수입니다.
def update_beta(X, y, y_pred, lr):
   
    delta_0 = -(lr * (2 / len(X)) * np.sum(y - y_pred))
   
    delta_1 = -(lr * (2 / len(X)) * (np.dot(X.T, (y - y_pred))))
   
    return delta_0, delta_1
   

"""
2.  반복 횟수만큼 오차(loss)를 계산하고
    beta_0,beta_1의 값을 변경하는 함수를 구현합니다.
   
    Step01. 실제 값 y와 prediction 함수를 통해 예측한
    예측 값 pred_y 간의 차이(loss)를 계산합니다.
   
    loss는 실제값(y) - 예측값(pred_y)으로 정의하겠습니다.
   
    Step02. 구현된 함수를 이용하여
    beta_0와 beta_1 의 변화값을 각각 beta0_delta, beta1_delta에 저장합니다.
"""
def gradient_descent(X, y, iters, lr):
   
    beta_0 = np.zeros((1,1))
    beta_1 = np.zeros((1,1))
   
    for i in range(iters):
       
        y_pred = prediction(beta_0, beta_1, X)
        loss = np.mean(np.square(y - y_pred))
       
        beta0_delta, beta1_delta = update_beta(X, y, y_pred, lr)
       
        beta_0 -= beta0_delta
        beta_1 -= beta1_delta
       
        # 100번의 학습마다 그래프 출력하기
        if i%100==0:
            print("학습 횟수 :",i)
            plotting_graph(X,y,beta_0,beta_1)
       
    return beta_0, beta_1


# 그래프를 시각화하는 함수입니다.
def plotting_graph(X,y,beta_0,beta_1):
   
    y_pred = beta_0 + beta_1[0,0] * X
   
    fig = plt.figure()
   
    plt.scatter(X, y)
    plt.plot(X, y_pred,c='r')
   
    plt.savefig("test.png")
    elice_utils.send_image("test.png")


# 회귀 알고리즘 구현 진행을 위한 main() 함수입니다.  
def main():
   
    # 학습을 위해 필요한 파라미터입니다.
    lr = 1e-4
    iteration = 1000
   
    X, y = load_data()
   
    beta_0, beta_1 = gradient_descent(X, y, iteration, lr)
   
    print("{}번의 학습 이후의 회귀 알고리즘 결과".format(iteration))
    print("beta_0:",beta_0[0], "beta_1:",beta_1[0])
   
    plotting_graph(X,y,beta_0,beta_1)
   
    return beta_0, beta_1

if __name__=="__main__":
    main()

 

더보기
더보기
import matplotlib.pyplot as plt
import numpy as np

from elice_utils import EliceUtils
elice_utils = EliceUtils()

# 데이터를 분리하는 모듈을 불러옵니다.
from sklearn.model_selection import train_test_split

# 사이킷런에 구현되어 있는 회귀 모델을 불러옵니다.
from sklearn.linear_model import LinearRegression

"""
1. 데이터를 생성하고,
   생성한 데이터를
   학습용 데이터와 테스트용 데이터로 분리하여
   반환하는 함수를 구현합니다.
   
   학습용 데이터로 전체 데이터의 70%를 사용하고,
   테스트용 데이터로 나머지 30%를 사용합니다.
   
   동일한 결과 확인을 위하여 random_state를 0으로 설정합니다.
"""
def load_data():
   
    np.random.seed(0)
   
    X = 5*np.random.rand(100,1)
    y = 3*X + 5*np.random.rand(100,1)
   
    train_X, test_X, train_y, test_y = train_test_split(X, y, test_size=0.3, random_state=0)
   
    return train_X, test_X, train_y, test_y

"""
2. 단순 선형회귀 모델을 불러오고,
   불러온 모델을 학습용 데이터에
   맞추어 학습시킨 후
   테스트 데이터에 대한
   예측값을 반환하는 함수를 구현합니다.

   Step01. 사이킷런에 구현되어 있는
           단순 선형회귀 모델을 불러옵니다.

   Step02. 불러온 모델을
           학습용 데이터에 맞춰 학습시킵니다.
"""
def regression_model(train_X, train_y):
   
    simplelinear = LinearRegression()
   
    simplelinear.fit(train_X, train_y)
   
    return simplelinear
   
# 그래프를 시각화하는 함수입니다.
def plotting_graph(train_X, test_X, train_y, test_y, predicted):
    fig, ax = plt.subplots(1,2, figsize=(16, 7))
   
    ax[0].scatter(train_X,train_y)
    ax[1].scatter(test_X,test_y)
    ax[1].plot(test_X, predicted, color='b')
   
    ax[0].set_xlabel('train_X')
    ax[0].set_ylabel('train_y')
    ax[1].set_xlabel('test_X')
    ax[1].set_ylabel('test_y')
   
    fig.savefig("result.png")
    elice_utils.send_image("result.png")
   
"""
3. 모델 학습 및 예측 결과 확인을 위한
   main() 함수를 완성합니다.
   
   Step01. 학습이 완료된 모델을 활용하여
           테스트 데이터에 대한 예측을 수행합니다.
       
   Step02. 사이킷런 회귀 모델 내에 구현되어 있는
           score 함수를 사용하여
           모델 학습 평가 점수를 model_score 변수에
           저장합니다.
   
   Step03. 학습된 모델의 beta_0와 beta_1을
           각각 변수 beta_0와 beta_1에
           저장합니다.
"""
def main():
   
    train_X, test_X, train_y, test_y = load_data()
   
    simplelinear = regression_model(train_X, train_y)
   
    predicted = simplelinear.predict(test_X)
   
    model_score = simplelinear.score(test_X, test_y)
   
    beta_0 = simplelinear.intercept_
    beta_1 = simplelinear.coef_
   
    print("> beta_0 : ",beta_0)
    print("> beta_1 : ",beta_1)
   
    print("> 모델 평가 점수 :", model_score)
   
    # 시각화 함수 호출하기
    plotting_graph(train_X, test_X, train_y, test_y, predicted)
   
    return predicted, beta_0, beta_1, model_score
   
   
if __name__=="__main__":
    main()
더보기
더보기

데이터 준비를 위한 사이킷런 함수/라이브러리

 

from sklearn.model_selection import train_test_split : 학습용 데이터와 테스트용 데이터를 나누어주는 함수(train_test_split())를 불러옵니다.

train_test_split(X, y, test_size=0.3, random_state=0): 데이터 X와 y에 대해 70%를 학습용, 나머지 30%의 데이터를 테스트용 데이터로 나눈 결과 데이터를 반환합니다.

단순 선형 회귀를 위한 사이킷런 함수/라이브러리

 

from sklearn.linear_model import LinearRegression: 단순 선형 회귀 모델을 불러옵니다.

model=LinearRegression() : 선형회귀 모델 model을 정의합니다.

model.fit(X, y): 인공지능 모델 model을 X, y 데이터셋에 대해서 학습시킵니다.

model.predict(X): 모델 model의 X 데이터에 대한 예측값을 반환합니다.

model.score(X, y) : 테스트 데이터를 인자로 받아 학습이 완료된 모델 model의 평가 점수를 출력합니다.

model.intercept_ : 학습이 완료된 모델 model의 β0β0​ 를 반환합니다.

model.coef_ : 학습이 완료된 모델 model의 β1β1​ 를 반환합니다.


다중선형회귀

 

tensor = tf.constant([[1, 2], [3, 4], [5, 6]])
print(tensor.shape)  # Output: (3, 2)

- shape returns a tuple representing the dimensions of an array

더보기
더보기
import matplotlib.pyplot as plt

import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression

# boston 데이터를 위한 모듈을 불러옵니다.
from sklearn.datasets import load_boston

"""
1. 사이킷런에 존재하는 데이터를 불러오고,
   불러온 데이터를 학습용 데이터와 테스트용 데이터로
   분리하여 반환하는 함수를 구현합니다.
   
   Step01. 사이킷런에 존재하는 boston 데이터를
           (X, y)의 형태로 불러옵니다.
   
   Step02. 불러온 데이터를
           학습용 데이터와 테스트용 데이터로 분리합니다.
           
           학습용 데이터로 전체 데이터의 80%를 사용하고,
           테스트용 데이터로 나머지 20%를 사용합니다.
           
           동일한 결과 확인을 위하여 random_state를
           100으로 설정합니다.
"""
def load_data():
   
    X, y  = load_boston(return_X_y = True)
     
    print("데이터의 입력값(X)의 개수 :", X.shape[1])
   
    train_X, test_X, train_y, test_y = train_test_split(X, y, test_size = 0.2, random_state = 100)
   
    return train_X, test_X, train_y, test_y
   
"""
2. 다중 선형회귀 모델을 불러오고,
   불러온 모델을 학습용 데이터에 맞추어 학습시킨 후
   해당 모델을 반환하는 함수를 구현합니다.

   Step01. 사이킷런에 구현되어 있는
           다중 선형회귀 모델을 불러옵니다.

   Step02. 불러온 모델을 학습용 데이터에 맞춰
           학습시킵니다.
"""
def Multi_Regression(train_X,train_y):
   
    multilinear = LinearRegression()
   
    multilinear.fit(train_X, train_y)
   
    return multilinear
   
"""
3. 모델 학습 및 예측 결과 확인을 위한 main 함수를 완성합니다.
   
   Step01. 학습이 완료된 모델을 활용하여
           테스트 데이터에 대한 예측을 수행합니다.
       
   Step02. 사이킷런 회귀 모델 내에 구현되어 있는
           score 함수를 사용하여
           모델 학습 평가 점수를 model_score 변수에
           저장합니다.
   
   Step03. 학습된 모델의 beta_0와 beta_i들을
           각각 변수 beta_0와 beta_i_list에 저장합니다.
"""
def main():
   
    train_X, test_X, train_y, test_y = load_data()
   
    multilinear = Multi_Regression(train_X,train_y)
   
    predicted = multilinear.predict(test_X)
   
    model_score = multilinear.score(test_X, test_y)
   
    print("\n> 모델 평가 점수 :", model_score)
     
    beta_0 = multilinear.intercept_
    beta_i_list = multilinear.coef_
   
    print("\n> beta_0 : ",beta_0)
    print("> beta_i_list : ",beta_i_list)
   
    return predicted, beta_0, beta_i_list, model_score
   
if __name__ == "__main__":
    main()

 

다항회귀모델

 

더보기
더보기

다항 회귀를 위한 사이킷런 함수/라이브러리

 

 # 다항회귀모델 polynominal Regression Model

  • poly=PolynomialFeatures(degree, include_bias): Polynomial 객체 poly를 생성합니다.
    • degree: 만들어줄 다항식의 차수를 의미합니다.
    • include_bias : 편향 변수의 추가 여부를 설정합니다.(True/False) True로 설정하게 되면, 해당 다항식의 모든 거듭제곱이 0일 경우 편향 변수를 추가합니다. 이는 회귀식에서 β0 와 같은 역할을 합니다.
  • poly.fit_transform(X): 데이터 X와 X의 degree제곱을 추가한 데이터를 반환합니다.
    • fit(X)와 transform(X) 을 각각 분리해서 진행하는 것도 가능합니다.
  • from sklearn.linear_model import LinearRegression: 다중 선형 회귀 모델을 불러옵니다.
  • model=LinearRegression() : 다중선형회귀 모델 model을 정의합니다.
  • model.fit(X, y): 인공지능 모델 model을 X, y 데이터셋에 대해서 학습시킵니다.

-

더보기
더보기
from elice_utils import EliceUtils
elice_utils = EliceUtils()

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

# 다항 회귀의 입력값을 변환하기 위한 모듈을 불러옵니다.
from sklearn.preprocessing import PolynomialFeatures

def load_data():
   
    np.random.seed(0)
   
    X = 3*np.random.rand(50, 1) + 1
    y = X**2 + X + 2 +5*np.random.rand(50,1)
   
    return X, y
   
"""
1. PolynomialFeature 객체를 활용하여
   각 변수 값을 제곱하고,
   데이터에 추가하는 함수를 구현합니다.
   
   Step01. Polynomial 객체를
           생성합니다.
           
           degree를 2로 설정하고,
           include_bias 파라미터를
           True로 설정합니다.
   
   Step02. 변수 값을 제곱하고
           이를 X에 추가시킨 후
           poly_X에 저장합니다.
"""
def Polynomial_transform(X):
   
    poly_feat = PolynomialFeatures(degree=2, include_bias = True)
   
    poly_X = poly_feat.fit_transform(X)
   
    print("변환 이후 X 데이터\n",poly_X[:3])
   
    return poly_X
   
"""
2. 다중 선형회귀 모델을 불러오고,
   불러온 모델을 학습용 데이터에 맞추어
   학습시킨 후 해당 모델을 반환하는
   함수를 구현합니다.

   Step01. 사이킷런에 구현되어 있는
           다중 선형회귀 모델을 불러옵니다.

   Step02. 불러온 모델을 제곱값이 추가된
           데이터에 맞춰 학습시킵니다.
"""
def Multi_Regression(poly_x, y):
   
    # LinearRegression은
    # 단순선형회귀, 다중선형회귀 모두 적용 가능
    multilinear = LinearRegression()
   
    multilinear.fit(poly_x)
   
    return multilinear
   
   
# 그래프를 시각화하는 함수입니다.
def plotting_graph(x,y,predicted):
    fig = plt.figure()
    plt.scatter(x, y)
   
    plt.scatter(x, predicted,c='r')
    plt.savefig("test.png")
    elice_utils.send_image("test.png")
   
   
"""
3. 모델 학습 및 예측 결과 확인을 위한
   main 함수를 완성합니다.
   
   학습이 완료된 모델을 활용하여
   테스트 데이터에 대한 예측을 수행합니다.
"""
def main():
   
    X,y = load_data()
   
    poly_x = Polynomial_transform(X)
   
    linear_model = Multi_Regression(poly_x,y)
   
    predicted = linear_model.predict(poly_x)
   
    plotting_graph(X,y,predicted)
   
    return predicted
   
if __name__=="__main__":
    main()