본문 바로가기
Python/머신러닝+딥러닝 Ⅰ

Multiple Regression(다중회귀)

by Mr.DonyStark 2024. 3. 15.

https://dandora-90.tistory.com/295

 

KNN_Regression&LinearRegression

□ K 최근접 이웃 회귀(K-NN Regression) ○ K-최근접 이웃 회귀모델은 분류와 동일하게 가장먼저가까운 k개의 이웃을 찾음. ○ 그다음 이웃샘플의 타깃값을 평균하여 샘플의 예측값으로 사용. ○ 사

dandora-90.tistory.com

위 글에서 농어의 길이로 무게 예측을 위해 Linear Regression(선형회귀)를 사용하여 트레이닝/테스트 점수가 올랐으나 약간의 과소적합 경향이 보였음.

이를 해결하기위해 Multiple Regression(다중회귀)를 사용하여 트레이닝/테스트 점수관련 과대/과소적합을 방지하고자함.

우선 다항회귀와 다중회귀의 차이를 알아보자.

다항회귀와 다중회귀는 서로다르며 특성이 1개면 선형회귀 모델은 직선 기울기를 학습하는 반면, 특성이 2개 이상인 선형회귀는 평면 기울기를 학습함.(다중회귀의 평면기울기 ▶ 타겟 = a*특성1 + b*특성2 + c*특성3 + 절편)

 


1) 다항회귀 : 독립변수의 차수를 높이는 형태임

https://dandora-90.tistory.com/294

 

K-Nearest Neighbor : K-NN 알고리즘

□ K-NN(K-Nearest Neighbor) 알고리즘 : k-최근접 이웃 알고리즘(또는 줄여서 k-NN)은 분류나 회귀에 사용되는 비모수 방식으로 두 경우 모두 입력이 특징 공간 내 k개의 가장 가까운 훈련 데이터로 구성

dandora-90.tistory.com

2) 다중회귀 : 다중의 독립변수가 있는 형태로 여러개의 변수, 특성을 사용하는 것이 다중회귀임



□ 농어의 길이, 높이, 두께 데이터가 담긴 트레이닝 데이터와 무게 데이터가 저장된 타겟 데이터로 다중회귀분석을 시행하고자함

○ 데이터 호출

#라이브러리 및 학습 데이터 호출
import pandas as pd

df = pd.read_csv("https://bit.ly/perch_csv_data")
print(f"불러온 로우데이터\n{df.head(3)}")
print("\n")
#불러온 데이터프레임을 넘파이로 변환
perch_full = df.to_numpy()
print(f"로우데이터 배열로 변환\n{perch_full[:3]}")
print(f"로우데이터 배열 타입 :{perch_full.ndim}")
print(f"로우데이터 배열 형태 :{perch_full.shape}")

#라이브러리 및 타겟 데이터 호출
import numpy as np
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]
     )
print(f"로우데이터 배열로 변환\n{perch_weight[:3]}")
print(f"로우데이터 배열 타입 :{perch_weight.ndim}")
print(f"로우데이터 배열 형태 :{perch_weight.shape}")

 

트레이닝/테스트 데이터 분리

#트레이닝, 테스트 세트 분리
from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(perch_full, perch_weight)

print(f"트레이닝 데이터\n{train_input[:5]}")
print("\n")
print(f"트레이닝 데이터 길이\n{len(train_input)}")
print("\n")
print(f"트레이닝 타겟데이터\n{train_target[:5]}")
print("\n")
print(f"트레이닝 타겟데이터 길이\n{len(train_target)}")
print("\n")
print(f"테스트데이터\n{test_input[:5]}")
print("\n")
print(f"테스트데이터 길이\n{len(test_input)}")
print(f"테스트 타겟데이터\n{test_target[:5]}")
print(f"테스트 타겟데이터 길이\n{len(test_target)}")

 

○ 다중회귀 모델 생성 및 학습, 학습점수확인

from sklearn.linear_model import LinearRegression
#선형회귀 알고리즘 객체 생성
lr = LinearRegression()
#학습
lr.fit(train_input,train_target)
#점수확인
print(f"트레이닝 데이터 학습점수 : {lr.score(train_input,train_target)}")
print(f"테스트 데이터 학습점수 : {lr.score(test_input,test_target)}")

 

※ 특성을 2개에서 3개로 늘려 학습 후 점수를 확인해보니 적당히 학습이된것같아 보였음.

여기서 의문이 들었음. 속성을 많이 만들어 전처리 및 학습을 하면 학습점수가 더 오르지 않을까? 말해뭐해 바로 실행해봄

※ 우선 알아야 할 것이 사이킷런은 특성을 만들거나 전처리하기 위한 다양한 클래스를 제공하는 데 이러한 클래스들을 활용하여  제공속성을 늘리는 작업을 진행함. 다중특성을 만들기위해 우리는 변환기라는 것을 사용할 수 있음

 

○ 변환기를 활용해 속성늘리기

from sklearn.preprocessing import PolynomialFeatures

#변환기 생성
poly = PolynomialFeatures(include_bias=False)  #y절편을 빼기 위해 include_bias=False 기재
#변환 시행
poly.fit(train_input)

train_poly = poly.transform(train_input) #기존 트레이닝 데이터 변환
test_poly = poly.transform(test_input) #기존 테스트 데이터 변환

print(f"기존 트레이닝 데이터\n{train_input[:3]}")
print(f"기존 트레이닝 데이터 형태{train_input.shape}")
print("\n")
print(f"변환후 트레이닝 데이터\n{train_poly[:3]}")
print(f"변환후 트레이닝 데이터 형태{train_poly.shape}")
print("\n")
print(f"기존 테스트 데이터\n{test_input[:3]}")
print(f"기존 테스트 데이터 형태{test_input.shape}")
print("\n")
print(f"변환후 테스트 데이터\n{test_poly[:3]}")
print(f"변환후 테스트 데이터 형태{test_poly.shape}")
print("\n")
#변환기를 통해 새로 생성된 특성
poly.get_feature_names_out()

 

※ 변환기를 통해 새로 생성된 특성은 6개이며, x0은 첫번째 특성을 의미하고 x0^2는 첫번 째 특성의 제곱, x0 x1은 첫번째 특성과 두번째 특성의 곱을 나타냄.

 

○ 학습진행

from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(train_poly,train_target)
print(lr.score(train_poly,train_target))
print(lr.score(test_poly,test_target))

트레닝/테스트 데이터에대한 학습점수가 더올랐음.

 

여기서 멈추지않고 특성 즉, 속성을 더만들어서 하면 모두다 99%를 달성하지 않을까 하는 마음에 또다시 변환기를 사용함.

poly = PolynomialFeatures(degree=5,include_bias=False)
poly.fit(train_input)
train_poly = poly.transform(train_input)
test_poly = poly.transform(test_input)

print(f"기존 트레이닝 데이터\n{train_input[:3]}")
print(f"기존 트레이닝 데이터 형태{train_input.shape}")
print("\n")
print(f"변환후 트레이닝 데이터\n{train_poly[:3]}")
print(f"변환후 트레이닝 데이터 형태{train_poly.shape}")
print("\n")
print(f"기존 테스트 데이터\n{test_input[:3]}")
print(f"기존 테스트 데이터 형태{test_input.shape}")
print("\n")
print(f"변환후 테스트 데이터\n{test_poly[:3]}")
print(f"변환후 테스트 데이터 형태{test_poly.shape}")
print("\n")
#변환기를 통해 새로 생성된 특성
poly.get_feature_names_out()

52개의 신규 속성을 만들었음

 

○ 학습 재진행

from sklearn.linear_model import LinearRegression
#모델생성
lr = LinearRegression()
#학습
lr.fit(train_poly,train_target)
#학습점수 확인
print(lr.score(train_poly,train_target))
print(lr.score(test_poly,test_target))

 

※ 테스트 데이터 학습점수는 99%인 반면, 테스트 데이터 학습점수는 엄청나게 떨어졌음.
행 수 보다 속성 수가 많아, 과대적합이 발생된 것으로 예상되어, 조치가 필요하다고 생각됨.
과대적합을 해결하기위해 규제가 필요하다고 판단했고 규제를 위해 Ridge, Lasso 모델을 적용하기로함.

 

(다음 글에서~)

'Python > 머신러닝+딥러닝 Ⅰ' 카테고리의 다른 글

확률적경사하강법  (1) 2024.03.22
Logistic_KNN  (0) 2024.03.22
규제(L1, L2)와 Ridge, Lasso  (0) 2024.03.15
KNN_Regression&LinearRegression  (1) 2024.03.13
K-Nearest Neighbor : K-NN 알고리즘  (3) 2024.03.12