21.12.18 머신러닝 회귀(Regression)

2021. 12. 19. 19:17작업/머신러닝

01 회귀 개념

머신러닝 분야 구조

 

회귀 분석이란 Loss function을 최소로 만드는 Gradient Descent(최적의 B0, B1를 찾는 알고리즘)를 통해 데이터를 가장 잘 선명하는 선을 찾아 입력값에 따른 미래 결과값을 예측하는 알고리즘

 

각 데이터의 실제 값과 모델이 예측하는 값의 차이를 최소한으로 해야 한다.

|pred - 실제값|의 (제곱) 오차를 최소로
-> Loss function을 최소로 만드는 B0, B1을 구하자

-> Gradient Descent(최적의 B0, B1를 찾는 알고리즘)

실습 1 선형 회귀분석

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_1와 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)) # MSE 사용 
        
        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()

실습2 단순선형회귀모델 구현

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()

다항 회귀(선형이 아닌 약간 곡선) .. 그러나 너무 높은 차수의 모델일 경우 과적합 현상 발생할 수도 있음

실습3 다중선형회귀모델

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()

실습4 다항회귀모델

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):
    
    multilinear = LinearRegression()
    
    multilinear.fit(poly_x,y)
    
    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()

과적합과 정규화

과적합 overfitting : 모델이 주어진 훈련 데이터에 과도하게 맞춰져 새로운 데이터가 입력되었을 때 잘 예측하지 못하는 현상, 즉 모델이 과도하게 복잡해져 일반성이 떨어진 경우를 의미한다.

 

-> sol1 교차 검증, sol2 정규화 진행

 

k-fold 교차 검증 : 데이터를 k등분으로 나누고 k번 훈련시킨다.

K-Fold 교차 검증은 K를 어떤 값으로 설정 후, 데이터를 K등분으로 나누고 K번 훈련시키는 방법입니다. 이때 K개로 나뉜 데이터 셋 중 1개는 검증용, 나머지 K-1개는 학습용으로 사용합니다.

 

(데이터셋을 k개로 나누고, 한 개는 valid, 나머지를 훈련용으로 사용.)

k개 모델의 평균 성능이 최종 모델 성능이다.

 

정규화 : 모델의 복잡성을 줄여 일반화된 모델을 구현하기 위한 방법 : 모델 Bi에 패널티를 부여함.

(B0x제곱 B1x세제곱 B2x네제곱 등..에서)

 

L1 정규화 :

+ 중요하지 않은 특정 B값을 정확히 0으로 만든다. 모델의 복잡성을 줄일 수 있다.

- 몇 개의 중요변수만 선택하기 때문에 정보 손실의 가능성이 있다.

L2 정규화 :

+ 중요하지 않은 특정 B값을 0에 가깝게 만든다. 모델 복잡성 줄일 수 O

- 완전한 0은 아니기 때문에 모델이 여전히 복잡할 수 있다.

엘라스틱 넷 (Elastic Net)

L1, L2 섞어서

 

정규화 방법을 적용한 회귀 알고리즘 -> 적용한 정규화 방법에 따라 라쏘L1, 릿지L2, 엘라스틱넷

 

실습5 과적합 방지 교차검증

import numpy as np

from sklearn.model_selection import train_test_split

from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression

# sklearn의 KFold 모듈 불러오기
from sklearn.model_selection import KFold

"""
1. 사이킷런에 존재하는 데이터를 불러오고, 
   불러온 데이터를 학습용 데이터와 테스트용 데이터로 
   분리하여 반환하는 함수를 구현합니다.
   
   Step01. 사이킷런에 존재하는 boston 데이터를 
           (X, y)의 형태로 불러옵니다. 
   
   Step02. 불러온 데이터를 
           학습용 데이터와 테스트용 데이터로
           분리합니다.
           
           학습용 데이터로 전체 데이터의 80%를,
           테스트용 데이터로 나머지 20%를 사용합니다.
           
           동일한 결과 확인을 위하여 random_state를
           100으로 설정합니다.
"""
def load_data():
    
    X, y = load_boston(return_X_y = True)
    
    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. K-fold 교차 검증을 통한 
   모델 학습 및 예측 수행을 진행할 함수를 구현합니다.
   
   Step01. 전체 데이터를 5개로 분리할 수 있도록 
           KFold 객체를 정의합니다.
           
   Step02. 정의한 kFold 객체와 .split() 함수를 이용하여 
           학습용 데이터 내에서 다시 
           학습용(Train) 데이터와 검증용(Validation)
           데이터를 나누고 
           각각 X_train, X_val, y_train, y_val에
           저장합니다.
           
           train_idx 와 val_idx는 분리된 데이터들의
           인덱스입니다.
            
   Step03. 분리한 학습용 데이터로 모델을 학습시키고,
           검증용 데이터로 모델을 평가하여 
           각 데이터에 대한 모델 평가 점수를 score
           변수에 저장합니다.
"""
def kfold_regression(train_X, train_y):
    
    # 반복문 내에서 횟수를 표시하기 위한 변수 설정하기
    n_iter = 0
    
    # 각 fold 마다 모델 검증 점수를 저장하기 위한 빈 리스트 생성하기
    model_scores = []
    
    kfold = KFold(n_splits=5)
    
    for train_idx, val_idx in kfold.split(train_X):
        
        X_train, X_val =  train_X[train_idx], train_X[val_idx]
        y_train, y_val =  train_y[train_idx], train_y[val_idx]
        
        # 동일한 가중치 사용을 위해 각 fold 마다 모델 초기화 하기
        model = LinearRegression()
        
        model.fit(X_train, y_train)
        
        # 각 Iter 별 모델 평가 점수 측정
        score = model.score(X_val, y_val)
        
        # 학습용 데이터의 크기를 저장합니다.
        train_size = X_train.shape[0]
        val_size = X_val.shape[0]
    
        print("Iter : {0} Cross-Validation Accuracy : {1}, Train Data 크기 : {2}, Validation Data 크기 : {3}"
              .format(n_iter, score, train_size, val_size))
    
        n_iter += 1
        
        # 전체 모델 점수를 저장하는 리스트에 추가하기
        model_scores.append(score)
        
    return kfold, model, model_scores
        
        
def main():
    
    # 학습용 데이터와 테스트 데이터 불러오기
    train_X, test_X, train_y, test_y = load_data()
    
    # KFold 교차 검증을 통한 학습 결과와 회귀 모델을 반환하는 함수 호출하기
    kfold, model, model_scores = kfold_regression(train_X, train_y)
    
    # 전체 성능 점수의 평균 점수 출력
    print("\n> 평균 검증 모델 점수 : ", np.mean(model_scores))
    

    
if __name__ == "__main__":
    main()

실습  6 릿지, 라쏘 회귀

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

from elice_utils import EliceUtils
elice_utils = EliceUtils()

from sklearn.linear_model import Ridge
from sklearn.linear_model import Lasso

from sklearn.datasets import load_boston

"""
1. 사이킷런에 존재하는 데이터를 불러오고, 
   불러온 데이터를 학습용 데이터와 테스트용 데이터로 
   분리하여 반환하는 함수를 구현합니다.
   
   Step01. 사이킷런에 존재하는 boston 데이터를 
           (X, y)의 형태로 불러옵니다. 
   
   Step02. 데이터의 변수 이름을 feature_names 에
           저장합니다.
"""
def load_data():
    
    X, y = load_boston(return_X_y = True)
    
    feature_names = load_boston().feature_names
    
    return X,y,feature_names
    
"""
2. 릿지(Ridge) 회귀를 구현하고, 
   전체 데이터를 바탕으로 학습시킨 모델을 
   반환하는 함수를 완성합니다.
   
   Step01. 사이킷런에 구현되어 있는 
           릿지(Ridge) 회귀 모델을 불러옵니다.
           
           파라미터 alpha를 10으로 설정합니다.
   
   Step02. 불러온 모델을 전체 데이터에 맞춰
           학습시킵니다.
"""
def Ridge_regression(X, y):
    
    ridge_reg = Ridge(alpha=10) # alpha의 기본값은1, alpha가 클수록 강한 정규화 적용
    
    ridge_reg.fit(X,y)
    
    return ridge_reg

"""
2. 라쏘(Lasso) 회귀를 구현하고, 
   전체 데이터를 바탕으로 학습시킨 모델을 
   반환하는 함수를 완성합니다.
   
   Step01. 사이킷런에 구현되어 있는 
           라쏘(Lasso) 회귀 모델을 불러옵니다.
           
           파라미터 alpha를 10으로 설정합니다.
   
   Step02. 불러온 모델을 전체 데이터에 맞춰
           학습시킵니다.
"""
def Lasso_regression(X, y):
    
    lasso_reg = Lasso(alpha = 10)
    
    lasso_reg.fit(X,y)
    
    return lasso_reg
    
# 각 변수의 beta_i 크기를 시각화하는 함수입니다.
def plot_graph(coef, title):
    fig = plt.figure()
    
    plt.ylim(-1,1)
    plt.title(title)
    coef.plot(kind='bar')

    plt.savefig("result.png")
    elice_utils.send_image("result.png")


def main():
    
    X,y,feature_names = load_data()
    
    ridge_reg = Ridge_regression(X, y)
    lasso_reg = Lasso_regression(X, y)
    
    ## Ridge 회귀의 beta_i의 크기를 저장합니다.
    ridge_coef = pd.Series(ridge_reg.coef_, feature_names).sort_values()
    print("Ridge 회귀의 beta_i\n", ridge_coef)
    
    ## Lasso 회귀의 beta_i의 크기를 저장합니다.
    lasso_coef = pd.Series(lasso_reg.coef_, feature_names).sort_values()
    print("Lasso 회귀의 beta_i\n", lasso_coef)
    
    plot_graph(ridge_coef, 'Ridge')
    plot_graph(lasso_coef, 'Lasso')

if __name__=="__main__":
    main()

실습 7 엘라스틱넷 회귀

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

from elice_utils import EliceUtils
elice_utils = EliceUtils()

from sklearn.linear_model import ElasticNet
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_boston

"""
1. 사이킷런에 존재하는 데이터를 불러오고, 
   데이터와 변수 이름을 반환하는 함수를 구현합니다.
   
   Step01. 사이킷런에 존재하는 boston 데이터를 
           (X, y)의 형태로 불러옵니다. 
   
   Step02. 데이터의 변수 이름을 feature_names 에 저장합니다.
   
   [실습6]에서 구현한 함수를 그대로 이용할 수 있습니다.
"""
def load_data():
    
    X, y = load_boston(return_X_y = True)
    
    feature_names = load_boston().feature_names
    
    return X,y,feature_names
    
"""
2. 엘라스틱 넷(ElasticNet) 회귀를 구현하고, 
   학습용 데이터를 바탕으로 학습시킨 모델을 
   반환하는 함수를 완성합니다.
   
   Step01. 사이킷런에 구현되어 있는 
           엘라스틱 넷(ElasticNet) 회귀 모델을 불러옵니다.
           
           파라미터 alpha와 l1_ratio를 자유롭게 설정합니다.
   
   Step02. 불러온 모델을 학습용 데이터에 맞춰 학습시킵니다.
"""

def ElasticNet_regression(train_X, train_y):
    
    ElasticNet_reg = ElasticNet()
    
    ElasticNet_reg.fit(train_X,train_y)
    
    return ElasticNet_reg
    
    
# 각 변수의 beta_i 크기를 시각화하는 함수입니다.
def plot_graph(coef):
    coef.plot(kind='bar')
    
    plt.savefig("result.png")
    elice_utils.send_image("result.png")
    
    
def main():
    
    X,y,feature_names = load_data()
    
    train_X, test_X, train_y, test_y = train_test_split(X,y,test_size=0.2, random_state=100)
    
    elasticnet_reg = ElasticNet_regression(train_X, train_y)
    
    # 엘라스틱넷 회귀 모델 평가 점수 출력하기
    score = elasticnet_reg.score(test_X,test_y)
    print("ElasticNet 회귀의 평가 점수:", score)
    
    # 엘라스틱넷 회귀의 beta_i의 크기를 저장합니다.
    ElasticNet_coef = pd.Series(elasticnet_reg.coef_, feature_names).sort_values()
    print("\nElasticNet 회귀의 beta_i\n", ElasticNet_coef)
    
    plot_graph(ElasticNet_coef)
    
    return elasticnet_reg

if __name__=="__main__":
    main()

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

from elice_utils import EliceUtils
elice_utils = EliceUtils()

from sklearn.linear_model import ElasticNet
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_boston

"""
1. 사이킷런에 존재하는 데이터를 불러오고, 
   데이터와 변수 이름을 반환하는 함수를 구현합니다.
   
   Step01. 사이킷런에 존재하는 boston 데이터를 
           (X, y)의 형태로 불러옵니다. 
   
   Step02. 데이터의 변수 이름을 feature_names 에 저장합니다.
   
   [실습6]에서 구현한 함수를 그대로 이용할 수 있습니다.
"""
def load_data():
    
    X, y = load_boston(return_X_y = True)
    
    feature_names = load_boston().feature_names
    
    return X,y,feature_names
    
"""
2. 엘라스틱 넷(ElasticNet) 회귀를 구현하고, 
   학습용 데이터를 바탕으로 학습시킨 모델을 
   반환하는 함수를 완성합니다.
   
   Step01. 사이킷런에 구현되어 있는 
           엘라스틱 넷(ElasticNet) 회귀 모델을 불러옵니다.
           
           파라미터 alpha와 l1_ratio를 자유롭게 설정합니다.
   
   Step02. 불러온 모델을 학습용 데이터에 맞춰 학습시킵니다.
"""

def ElasticNet_regression(train_X, train_y):
    
    ElasticNet_reg = ElasticNet(alpha=0.001, l1_ratio=0.001)
    
    ElasticNet_reg.fit(train_X,train_y)
    
    return ElasticNet_reg
    
    
# 각 변수의 beta_i 크기를 시각화하는 함수입니다.
def plot_graph(coef):
    coef.plot(kind='bar')
    
    plt.savefig("result.png")
    elice_utils.send_image("result.png")
    
    
def main():
    
    X,y,feature_names = load_data()
    
    train_X, test_X, train_y, test_y = train_test_split(X,y,test_size=0.2, random_state=100)
    
    elasticnet_reg = ElasticNet_regression(train_X, train_y)
    
    # 엘라스틱넷 회귀 모델 평가 점수 출력하기
    score = elasticnet_reg.score(test_X,test_y)
    print("ElasticNet 회귀의 평가 점수:", score)
    
    # 엘라스틱넷 회귀의 beta_i의 크기를 저장합니다.
    ElasticNet_coef = pd.Series(elasticnet_reg.coef_, feature_names).sort_values()
    print("\nElasticNet 회귀의 beta_i\n", ElasticNet_coef)
    
    plot_graph(ElasticNet_coef)
    
    return elasticnet_reg

if __name__=="__main__":
    main()

회귀 알고리즘 평가 지표 

RSS - 단순 오차, 실제값과 예측값의 단순 오차 제곱 합

+ 간단한 평가 방법, 직관적

- 오차를 그대로 이용하여 입력값의 크기에 의존적임

MSE - 평균 제곱 오차

RSS에서 데이터수만큼 나눈 값, 작을 수록 모델의 성능 높

 

MAE - 평균 절대값 오차

실제값과 예측값의 오차의 절대값의 평균, 작을 수록 성능높

 

 

MSE와 MAE 특징

 

R2 결정 계수 회귀 모델의 설명력을 표현하는 지표, 1에 가까울 수록 높은 성능

(0<= <=1)

R2 특징

절대적인 평가 지표는 없다! R2만 보진 않는다~

 

실습 8 회귀 알고리즘 평가 지표 RSS 

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

# 데이터 X와 y를 생성하고, 학습용 데이터와 테스트용 데이터로 분리하여 반환하는 함수입니다.
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, train_y, test_X, test_y

# 회귀 모델을 불러오고, 불러온 모델을 학습용 데이터에 맞춰 학습시켜 반환하는 함수입니다.
def Linear_Regression(train_X, train_y):
    
    lr = LinearRegression()
    
    lr.fit(train_X,train_y)
    
    return lr
    
"""
1. RSS(Residual Sum of Squares)를 계산하여
   반환하는 함수를 완성합니다.
"""
def return_RSS(test_y, predicted):
    
    RSS = 0
    
    for i in range(len(test_y)):
        RSS += (test_y[i] - predicted[i]) **2
    
    return RSS
    
    
# 그래프로 시각화합니다.
def plotting_graph(test_X, test_y, predicted):
    plt.scatter(test_X,test_y)
    plt.plot(test_X, predicted, color='r')
    
    plt.savefig("result.png")
    elice_utils.send_image("result.png")

"""
3. 정의한 함수들을 이용하여 main() 함수를 완성합니다.
   
   Step01. 생성한 데이터를 
           학습용 데이터와 테스트 데이터로
           분리하여 반환하는 함수를 호출합니다.
           
   Step02. 학습용 데이터를 바탕으로 학습한 선형 회귀 
           모델을 반환하는 함수를 호출합니다.
          
   Step03. 학습된 모델을 바탕으로 계산된 
           테스트 데이터의 예측값을 predicted에
           저장합니다.
           
   Step04. 회귀 알고리즘을 평가하기 위한 RSS 값을 RSS에
           저장합니다.
"""
def main():
    
    train_X, train_y, test_X, test_y = load_data()
     
    lr = Linear_Regression(train_X, train_y)
    
    predicted = lr.predict(test_X)
    
    RSS = return_RSS(test_y, predicted)
    print("> RSS :",RSS)
    
    plotting_graph(test_X, test_y, predicted)

if __name__=="__main__":
    main()

실습 9 회귀 알고리즘 평가지표 MSE, MAE

from elice_utils import EliceUtils
elice_utils = EliceUtils()

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression

from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_squared_error

# 데이터 X와 y를 생성하고, 학습용 데이터와 테스트용 데이터로 분리하여 반환하는 함수입니다.
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, train_y, test_X, test_y

# 회귀 모델을 불러오고, 불러온 모델을 학습용 데이터에 맞춰 학습시켜 반환하는 함수입니다.
def Linear_Regression(train_X, train_y):
    
    lr = LinearRegression()
    
    lr.fit(train_X,train_y)
    
    return lr
    
# 그래프로 시각화합니다.
def plotting_graph(test_X, test_y, predicted):
    plt.scatter(test_X,test_y)
    plt.plot(test_X, predicted, color='r')
    
    plt.savefig("result.png")
    elice_utils.send_image("result.png")

"""
1. 정의한 함수들을 이용하여 main() 함수를 완성합니다.
   
   Step01. 생성한 데이터를 
           학습용 데이터와 테스트 데이터로 
           분리하여 반환하는 함수를 호출합니다.
           
   Step02. 학습용 데이터를 바탕으로 학습한 선형 회귀
           모델을 반환하는 함수를 호출합니다.
          
   Step03. 학습된 모델을 바탕으로 계산된 
           테스트 데이터의 예측값을 predicted에
           저장합니다.
           
   Step04. 회귀 알고리즘을 평가하기 위한 MSE, MAE 값을 
           각각 MSE,MAE 에 저장합니다.
"""
def main():
    
    train_X, train_y, test_X, test_y = load_data()
    
    lr = Linear_Regression(train_X, train_y)
    
    predicted = lr.predict(test_X)
    
    MAE = mean_absolute_error(test_y, predicted)
    MSE = mean_squared_error(test_y, predicted)
    
    print("> MSE :",MSE)
    print("> MAE :",MAE)
    
    plotting_graph(test_X, test_y, predicted)
    
    return MSE, MAE

if __name__=="__main__":
    main()

실습10 회귀 알고리즘 평가 지표 R2 R squared 1에 가까울 수록 좋다

from elice_utils import EliceUtils
elice_utils = EliceUtils()

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression

from sklearn.metrics import r2_score

# 데이터 X와 y를 생성하고, 학습용 데이터와 테스트용 데이터로 분리하여 반환하는 함수입니다.
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, train_y, test_X, test_y

# 회귀 모델을 불러오고, 불러온 모델을 학습용 데이터에 맞춰 학습시켜 반환하는 함수입니다.
def Linear_Regression(train_X, train_y):
    
    lr = LinearRegression()
    
    lr.fit(train_X,train_y)
    
    return lr
    
# 그래프로 시각화합니다.
def plotting_graph(test_X, test_y, predicted):
    plt.scatter(test_X,test_y)
    plt.plot(test_X, predicted, color='r')
    
    plt.savefig("result.png")
    elice_utils.send_image("result.png")

"""
1. 정의한 함수들을 이용하여 main() 함수를 완성합니다.
   
   Step01. 생성한 데이터를 
           학습용 데이터와 테스트 데이터로 
           분리하여 반환하는 함수를 호출합니다.
           
   Step02. 학습용 데이터를 바탕으로 학습한 선형 회귀
           모델을 반환하는 함수를 호출합니다.
          
   Step03. 학습된 모델을 바탕으로 계산된
           테스트 데이터의 예측값을 predicted에
           저장합니다.
           
   Step04. 회귀 알고리즘을 평가하기 위한 r2_score값을 
           R_squared에 저장합니다.
"""
def main():
    
    train_X, train_y, test_X, test_y = load_data()
    
    lr = Linear_Regression(train_X, train_y)
    
    predicted = lr.predict(test_X)
    
    R_squared  = r2_score(test_y, predicted)
    
    print("> R_squared :",R_squared)
    
    plotting_graph(test_X, test_y, predicted)
    
    return R_squared

if __name__=="__main__":
    main()

 

'작업 > 머신러닝' 카테고리의 다른 글

21.12.19 모의테스트  (0) 2021.12.19
21.12.18 나이브베이즈 분류  (0) 2021.12.19
21.12.18 회귀분석  (0) 2021.12.19
21.12.18 선형대수 / Numpy  (0) 2021.12.19
21.12.18 머신러닝 분류(Classification)  (0) 2021.12.19