ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [3월 4주차-3/28]경사하강법을 사용한 선형 회귀 학습 및 예측 평가
    Why Not SW CAMP 5기/수업 기록 2025. 3. 31. 17:01

    📌 경사하강법 (Gradient Descent)


    경사하강법이란?

    경사하강법은 함수의 최솟값을 찾기 위해 사용하는 최적화 알고리즘

    보통 손실 함수(Loss Function) 의 값을 최소화하는 파라미터(값)

    현재 위치에서 기울기를 계산하여 반대 방향으로 이동하는 방식


    💡 경사하강법의 작동 원리

    1. 초기값 설정: 무작위로 파라미터 값을 설정
    2. 기울기 계산 (Gradient Calculation): 현재 위치에서의 기울기를 계산
    3. 업데이트 (Update): 기울기의 값을 조정
    4. 반복 (Iterate): 원하는 최소값에 도달할 때까지 위의 과정을 반복

    📊 경사하강법 종류

    1. 배치 경사하강법 (Batch Gradient Descent):
      • 모든 데이터를 사용하여 기울기를 계산
      • 정확하지만 데이터가 많을 경우 계산 비용이 큼.
    2. 확률적 경사하강법 (Stochastic Gradient Descent, SGD):
      • 데이터 하나씩 사용하여 기울기를 계산
      • 계산 속도가 빠르지만 경로가 불안정할 수 있음
    3. 미니 배치 경사하강법 (Mini-Batch Gradient Descent):
      • 일부 데이터를 묶어 기울기를 계산
      • 속도와 정확도 간의 균형이 좋음.
      • 적절한 미니 배치 크기를 알아내기 위한 튜닝 작업 필요

    ❌ 문제점:

    • 지역 최솟값 (Local Minimum): 전체 최솟값이 아닌 부분적으로 낮은 값에 갇힐 수 있음
    • 학습률 설정 (Learning Rate): 너무 크면 목표를 넘겨버리고, 너무 작으면 학습 속도가 느려짐.

    ✅ 해결책:

    • 학습률 조정 (Learning Rate Adjustment): 점점 작게 줄여가며 최적값을 찾는 방식 (Learning Rate Decay).
    • 모멘텀 (Momentum): 이전 업데이트의 방향을 유지하여 빠르고 안정적으로 학습.
    • Adam (Adaptive Moment Estimation): 학습률을 자동으로 조정하며 학습하는 방법.

     

     

    📌 경사하강법을 사용한 선형 회귀 학습 및 예측 평가

    경사하강법(Stochastic Gradient Descent, SGD) 를 사용하여 학습 데이터를 기반으로 선형 회귀 모델을 학습하고 예측값을 평가하는 코드 입니다.


    1. 데이터 준비 (train, test)

    dataset = [
        [25, 100], [52, 256], [38, 152], [32, 140], [25, 150], 
        [45, 183], [40, 175], [55, 203], [28, 152], [42, 198]
    ]
    
    train = dataset[:5]  # 학습 데이터 (앞의 5개)
    test = dataset[5:]    # 테스트 데이터 (뒤의 5개)
    

    2. 회귀계수 초기화 (coef)

    coef = [0.0 for i in range(len(train[0]))]
    
    • coef = [0.0, 0.0] 로 초기화.
      • coef[0]: 절편 (Intercept)
      • coef[1]: 기울기 (Slope)

    3. 예측 함수 (predict())

    def predict(row, coef):
        yhat = coef[0]  # 절편 (Intercept)
        for i in range(len(row) - 1): 
            yhat += coef[i+1] * row[i]
        return yhat
    • 입력값 row 와 학습된 회귀계수 coef 를 이용하여 예측값 (yhat) 을 계산합니다.

    4. 학습 함수 (coefficients_sgd())

    def coefficients_sgd(train, l_rate, n_epoch):
        coef = [0.0 for i in range(len(train[0]))]
        for epoch in range(n_epoch):
            sum_error = 0
            for row in train:
                yhat = predict(row, coef)
                error = row[-1] - yhat
                sum_error += error ** 2
                
                # 회귀계수 업데이트
                coef[0] = coef[0] + l_rate * error  # 절편 업데이트
                for i in range(len(row) - 1):
                    coef[i+1] = coef[i+1] + l_rate * error * row[i]  # 기울기 업데이트
                    
        return coef, math.sqrt(sum_error / len(train))  # 학습 후 회귀계수와 RMSE 반환

    🔍 코드 설명: coefficients_sgd() 함수

    함수 정의

    def coefficients_sgd(train, l_rate, n_epoch):
    
    • train: 학습 데이터. (X 값, Y 값) 쌍으로 구성된 리스트.
      예) [[X1, Y1], [X2, Y2], ...]
    • l_rate: 학습률 (Learning Rate).
      • 값이 크면 학습이 빠르지만 정확도가 떨어질 수 있음.
      • 값이 작으면 학습이 느리지만 정확하게 수렴할 가능성이 높음.
    • n_epoch: 학습 반복 횟수 (Epoch).
      • 학습 데이터를 몇 번 반복하여 학습할 것인지 설정.

    회귀계수 초기화

    coef = [0.0 for i in range(len(train[0]))]
    
    • coef: 학습할 회귀계수 리스트.
    • train[0]: 학습 데이터의 첫 번째 샘플. 예) [25, 100]
    • len(train[0]): 입력값(X) 과 출력값(Y) 를 포함한 데이터의 길이.
      (이 예제에서는 2개)
    • 예를 들어, coef = [0.0, 0.0] 은 초기값으로 모두 0.0으로 설정합니다.
      • coef[0]: 절편 (Intercept)
      • coef[1]: 기울기 (Slope)

    학습 반복 (에포크 반복)

    for epoch in range(n_epoch):
        sum_error = 0  # 오차 제곱합 초기화
    
    • 전체 학습 데이터를 반복해서 학습하는 과정.
    • sum_error: 한 에포크 당 모든 학습 데이터의 오차 제곱합 (SSE, Sum of Squared Errors)

    학습 데이터 사용 (SGD 방식)

    for row in train:
        yhat = predict(row, coef)
        error = row[-1] - yhat
        sum_error += error ** 2
    
    • yhat: 예측값 (현재 모델의 회귀계수로 예측된 값)
    • error: 실제값과 예측값의 차이
    • sum_error: 오차를 제곱해서 계속 더함.

    회귀계수 업데이트 (경사하강법)

    🔍 절편 업데이트 (Intercept)

    coef[0] = coef[0] + l_rate * error
    
    • 절편은 입력값 X 의 영향을 받지 않고, 오차의 크기만을 고려하여 업데이트.
    • error 값이 크면 더 큰 변화량이 적용됩니다.

    🔍 기울기 업데이트 (Slope)

    for i in range(len(row) - 1):
        coef[i+1] = coef[i+1] + l_rate * error * row[i]
    
    • 각 입력값(X) 에 대한 기울기를 업데이트합니다.
    • 입력값(row[i]) 과 오차(error) 의 곱을 학습률(l_rate) 로 조정하여 기존 기울기에 더합니다.
    • 여러 입력값이 있는 경우에도 동일하게 적용됩니다.

    학습 결과 반환 (에포크 종료 후)

    return coef, math.sqrt(sum_error / len(train))
    
    • coef: 학습된 최종 회귀계수 (coef[0]: 절편, coef[1]: 기울기)
    • math.sqrt(sum_error / len(train)): 평균 오차의 제곱근 (RMSE, Root Mean Squared Error)
      • RMSE 는 모델의 예측 정확도를 나타내는 지표.
      • 값이 낮을수록 모델의 예측 성능이 좋음을 의미합니다.

     


    5. 학습된 모델로 예측 (predicted())

    def predicted(train, test, alpha, beta):
        predictions = []
        for i in test:
            yhat = alpha + beta * i[0]  # 단순 선형 회귀식 적용
            predictions.append(yhat)
        return predictions
    

    🔍 코드 설명:

    • 학습된 모델(alpha, beta) 을 사용하여 테스트 데이터의 예측값을 계산합니다.
    • 예측 값(yhat) 은 선형 회귀 공식에 의해 계산됩니다.

    6. 예측값 평가 (RMSE())

    def RMSE(actual, predicted):
        sum_error = 0.0
        for i in range(len(actual)):
            prediction_error = predicted[i] - actual[i]
            sum_error += (prediction_error ** 2)
        mean_error = sum_error / float(len(actual))
        return math.sqrt(mean_error)
    

    🔍 코드 설명:

    • 실제값(actual) 과 예측값(predicted) 사이의 오차를 계산합니다.
    • RMSE 값이 작을수록 모델의 예측 정확도가 높은 것을 의미합니다.

    7. 결과 확인

    l_rate = 0.0001
    n_epoch = 10
    
    # 학습
    alpha, beta = coefficients_sgd(train, l_rate, n_epoch)[0][0], \
                  coefficients_sgd(train, l_rate, n_epoch)[0][1]
    
    # 예측
    pred = predicted(train, test, alpha, beta)
    
    # 실제값
    actual = [j[1] for j in test]
    
    # 예측 정확도 평가
    rmse_value = RMSE(actual, pred)
    print("예측값:", pred)
    print("RMSE:", rmse_value)
    

    📊 코드 출력 결과 (예시)

    예측값: [210.00907613781257, 186.68812120780515, 256.6509859978274, 130.71782937578732, 196.0165031798081]
    RMSE: 28.987568769523886
    
    • 예측값은 실제값과 비교했을 때 일부 차이가 존재합니다.
    • RMSE 값이 약 28.99 이므로 모델의 예측 정확도를 개선할 필요가 있습니다.

    🔑 코드가 하는 일 요약

    1. 학습 데이터(train) 를 사용하여 경사하강법으로 모델 학습.
    2. 학습된 모델로 테스트 데이터(test) 에 대한 예측 수행.
    3. 예측값과 실제값을 비교하여 RMSE 계산.

    코드를 더 개선하고 싶다면 알려주세요! 또는 코드의 동작 방식에 대해 더 궁금한 게 있나요? 😊

Designed by Tistory.