ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [혼공머] 3-1. K-최근접 이웃 회귀
    Data Science/딥러닝 & 머신러닝 2025. 1. 10. 23:35

     

    1. 개념

    • 지도 학습 알고리즘
      • 분류
      • 회귀 : 숫자 예측
    • K-최근접 이웃 분류 알고리즘
      1. 가까운 이웃 k개 선택
      2. 이웃의 클래스 확인
      3. 다수 클래스를 새로운 샘플의 클래스로 예측
    • k-최근접 이웃 회귀
      1. 가까운 이웃 k개 선택
      2. 이웃의 ‘수치’ 확인
      3. 이웃들의 수치의 평균을 새로운 샘플의 예측값으로!
    • 결정계수 R^2
      • R^2 = 1 - ((타겟- 예측)^2의 합) / (타겟-평균)^2의 합)
      • 예측과 타겟이 가까울수록 1 = 클수록 좋은 모델
    • 과대적합 : 훈련 세트에만 잘 맞는 모델
    • 과소적합 : 훈련 세트에서도 적절하게 훈련되지 않은 경우

     

    2. 데이터 준비

    • 전체 데이터 : 농어의 길이, 높이, 두께, 무게
    • 이번에는 길이와 무게만 사용해서, 무게를 예측하자.

    1. 데이터 불러오기

    • 파이썬 리스트 만들고 arry 하지 말고 한 번에 np.array로 만들기
    import numpy as np
    perch_length = np.array([8.4, 13.7, 15.0, 16.2, 17.4, 18.0, 18.7, 19.0, 19.6, 20.0, 21.0,
           21.0, 21.0, 21.3, 22.0, 22.0, 22.0, 22.0, 22.0, 22.5, 22.5, 22.7,
           23.0, 23.5, 24.0, 24.0, 24.6, 25.0, 25.6, 26.5, 27.3, 27.5, 27.5,
           27.5, 28.0, 28.7, 30.0, 32.8, 34.5, 35.0, 36.5, 36.0, 37.0, 37.0,
           39.0, 39.0, 39.0, 40.0, 40.0, 40.0, 40.0, 42.0, 43.0, 43.0, 43.5,
           44.0])
    perch_weight = np.array([5.9, 32.0, 40.0, 51.5, 70.0, 100.0, 78.0, 80.0, 85.0, 85.0, 110.0,
           115.0, 125.0, 130.0, 120.0, 120.0, 130.0, 135.0, 110.0, 130.0,
           150.0, 145.0, 150.0, 170.0, 225.0, 145.0, 188.0, 180.0, 197.0,
           218.0, 300.0, 260.0, 265.0, 250.0, 250.0, 300.0, 320.0, 514.0,
           556.0, 840.0, 685.0, 700.0, 700.0, 690.0, 900.0, 650.0, 820.0,
           850.0, 900.0, 1015.0, 820.0, 1100.0, 1000.0, 1100.0, 1000.0,
           1000.0])
    

    2. 산점도 그려보기

    • 데이터 형태 파악
    import matplotlib.pyplot as plt
    plt.scatter(perch_length, perch_weight)
    plt.xlabel('length')
    plt.ylabel('weight')
    

    3. 훈련 세트와 테스트 세트 나누기

    from sklearn.model_selection import train_test_split
    train_input, test_input, train_target, test_target = train_test_split(perch_length, perch_weight, random_state=42)
    • 배열 reshape 가 필요 : 사이킷런에서 사용하는 훈련 세트는 2차원 배열
      • perch_length 가 1차원 → train_input, test_input도 1개의 열이 있는 2차원 배열로 변경
      • 해결 방안 : reshape() 메서드
        • -1 지정 : 나머지 원소 개수로 모두 채우기
        • resahpe(-1, 1) : 첫 번째 크기를 나머지 원소 개수로 채우고 두번째 크기를 1로 변경
      #원소 개수 영향 없이 차원 늘리기
      train_input = train_input.reshape(-1,1) 
      test_input = test_input.reshape(-1,1)
      

    4. 모델 훈련

    • KNeighborsRegressor 이용
    from sklearn.neighbors import KNeighborsRegressor
    knr = KNeighborsRegressor()
    
    knr.fit(train_input, train_target))
    

    5. 모델의 정확도

    • 결정계수 점수
      • 회귀에서는 ‘결정계수’로 모델을 평가한다.
      • score 메서드의 출력 결과가 결정계수를 의미
      knr.score(test_input, test_target) # R^2 = 0.992809406101064
      
    • 타겟과 예측의 절댓값 오차from sklearn.metrics import mean_absolute_error
      from sklearn.metrics import mean_absolute_error
      
      test_prediction = knr.predict(test_input) # 예측값
      mae = mean_absolute_error(test_target, test_prediction)
      print(mae) # 어느 정도의 오차가 발생하는가 = 19.1571
      

     

    3. K-Neighbors Regressor

    1. 모델 훈련

    • KNeighborsRegressor 이용
    from sklearn.neighbors import KNeighborsRegressor
    knr = KNeighborsRegressor()
    
    knr.fit(train_input, train_target))
    

    2. 모델의 정확도

    • 결정계수 점수
      • 회귀에서는 ‘결정계수’로 모델을 평가한다.
      • score 메서드의 출력 결과가 결정계수를 의미
      knr.score(test_input, test_target) # R^2 = 0.992809406101064
      
    • 타겟과 예측의 절댓값 오차from sklearn.metrics import mean_absolute_error
      from sklearn.metrics import mean_absolute_error
      
      test_prediction = knr.predict(test_input) # 예측값
      mae = mean_absolute_error(test_target, test_prediction)
      print(mae) # 어느 정도의 오차가 발생하는가 = 19.1571
      

     

    4. 과대적합과 과소적합

    knr.score(train_input, train_target) # 0.96
    knr.score(test_input, test_target) # 0.99
    
    • 훈련 세트의 score < 테스트 세트의 score → 과소적합

    1. 과소적합의 해결 방안

    • 모델을 조금 더 복잡하게 만든다 : 이웃 개수 감소 → 국지적 패턴에 민감
      • n_neighbors 속성값 변경
      knr.n_neighbors = 3
      knr.fit(train_input, train_target)
      knr.score(train_input, train_target) # 0.98
      knr.score(test_input, test_target) # 0.97
      
      훈련 세트 score 상승, 테스트 세트 score 감소 → 과소적합 문제 해결

     

    5. 회귀문제 다루기 소스코드

    # 데이터 불러오기
    import numpy as np
    perch_length = np.array([8.4, 13.7, 15.0, 16.2, 17.4, 18.0, 18.7, 19.0, 19.6, 20.0, 21.0,
           21.0, 21.0, 21.3, 22.0, 22.0, 22.0, 22.0, 22.0, 22.5, 22.5, 22.7,
           23.0, 23.5, 24.0, 24.0, 24.6, 25.0, 25.6, 26.5, 27.3, 27.5, 27.5,
           27.5, 28.0, 28.7, 30.0, 32.8, 34.5, 35.0, 36.5, 36.0, 37.0, 37.0,
           39.0, 39.0, 39.0, 40.0, 40.0, 40.0, 40.0, 42.0, 43.0, 43.0, 43.5,
           44.0])
    perch_weight = np.array([5.9, 32.0, 40.0, 51.5, 70.0, 100.0, 78.0, 80.0, 85.0, 85.0, 110.0,
           115.0, 125.0, 130.0, 120.0, 120.0, 130.0, 135.0, 110.0, 130.0,
           150.0, 145.0, 150.0, 170.0, 225.0, 145.0, 188.0, 180.0, 197.0,
           218.0, 300.0, 260.0, 265.0, 250.0, 250.0, 300.0, 320.0, 514.0,
           556.0, 840.0, 685.0, 700.0, 700.0, 690.0, 900.0, 650.0, 820.0,
           850.0, 900.0, 1015.0, 820.0, 1100.0, 1000.0, 1100.0, 1000.0,
           1000.0])
    
    # 데이터 분포 확인
    import matplotlib.pyplot as plt
    plt.scatter(perch_length, perch_weight)
    plt.xlabel('length')
    plt.ylabel('weight')
    
    # 세트 분리와 차원 증가
    from sklearn.model_selection import train_test_split
    train_input, test_input, train_target, test_target = train_test_split(perch_length, perch_weight, random_state=42)
    train_input = train_input.reshape(-1,1)
    test_input = test_input.reshape(-1,1)   
    
    # k-최근접 이웃 모델 훈련
    from sklearn.neighbors import KNeighborsRegressor
    knr = KNeighborsRegressor()
    knr.fit(train_input, train_target)    
    
    # k-최근접 이웃 모델 예측
    test_prediction = knr.predict(test_input)
    
    # 결정계수
    knr.score(test_input, test_target)
    
    # MAE
    from sklearn.metrics import mean_absolute_error
    test_prediction = knr.predict(test_input) 
    mae = mean_absolute_error(test_target, test_prediction)
    print(mae)
    
    # 과소적합 확인
    knr.score(train_input, train_target)
    knr.score(test_input, test_target)
    
    # 과소적합 없애기
    knr.n_neighbors = 3
    knr.fit(train_input, train_target)
    knr.score(train_input, train_target)
    knr.score(test_input, test_target)
    
Designed by Tistory.