본문 바로가기

인공지능/머신러닝

[머신러닝ML] 머신러닝 실습 - 다중회귀모델(Multiple Regression)

~ 목차 ~

다중회귀모델

- 여러 개의 특성을 사용한 회귀모델
- 특성이 많을 수록 복잡도가 증가됨(훈련 시간이 오래걸림, 시스템 성능에 따라 빠를 수도 있음)
- 다중회귀모델 공식
  y = a*x1 + b*x2 + c*x3 + ... + y절편

 


### 데이터 불러들이기
# 사용할 데이터프레임 변수 : df
import pandas as pd

df= pd.read_csv("./data/03_농어의_길이_높이_두께_데이터.csv")
df.info()
df.head()
df.describe()

df 정보

 

 

농어 데이터에 다중회귀모델 적용하기

<농어의 길이, 두께, 높이 값을 이용해서 → 무게 예측하기>
- 독립변수 : 길이, 두께, 높이
- 종속변수 : 무게

- 독립변수 생성하기 : 데이터프레임의 특성 중에 독립변수로 사용할 특성들을 2차원의 리스트 또는 배열 형태로 만들어야 합니다.

 


# 독립변수 생성
perch_full=df.to_numpy()
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]
     )
perch_weight.shape

 ==> 출력 : (56, 3)
                    (56,)

 

<훈련 및 테스트 데이터로 분류하기>
- 분류 기준 : 테스트 데이터를 30%로, 랜덤규칙은 42번

 


from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(perch_full, perch_weight,
                                                                      test_size=0.3,
                                                                      random_state=42)
print(f"{train_input.shape} , {train_target.shape}")
print(f"{test_input.shape} , {test_target.shape}")

 ==> 출력 : (39, 3) , (39,)
                     (17, 3) , (17,)


""" 모델 생성하기 """
from sklearn.linear_model import LinearRegression

lr = LinearRegression()
lr

""" 모델 훈련 시키기 """
lr.fit(train_input, train_target)

""" 훈련정확도 및 검증(테스트) 정확도 확인하기 """
train_r2=lr.score(train_input, train_target)
test_r2=lr.score(test_input, test_target)
print(f"{train_r2}, {test_r2}")

 ==> 출력 : 0.9537065271284176, 0.8863420836347778

 

<과적합 여부 판단하기>

- 훈련과 검증(테스트) 결정계수의 결과로 볼때 과소적합은 발생하지 않았으며, 
  또한 0.07~0.08 정도로 과대적합 또한 일어나지 않은 일반화된 모델로 볼 수 있음
- 다만, 검증(테스트) 정확도가 0.8대에서 0.9대로 올릴 수 없을지 고민해 봅니다.
- 특성공학을 적용하여 특성 늘리는 방법으로 집중도를 강화하는 방식을 사용해서 성능 향상이 되는지 확인

 

<특성을 생성하는 라이브러리>

- 사용 패키지 : sklearn.preprocessing
- 사용 클래스 : PloynomialFeatures(변환기라고 보통 칭합니다.)
- 사용 함수 : fit(훈련 독립변수에서 생성할 특성의 패턴 찾기),
              transform(찾은 패턴으로 특성 생성하기)
- 종속변수는 사용되지 않습니다.

 


""" 테스트 데이터로 예측하기"""
test_pred=lr.predict(test_input)
test_pred

""" 평균절대오차(MAE) 확인하기"""
from sklearn.metrics import mean_absolute_error
mean_absolute_error(test_target, test_pred)


 ==> 출력 : 68.56651514640546

○ 특성 샘플로 확인하기


### 패키지 정의하기
from sklearn.preprocessing import PolynomialFeatures

### 클래스 생성하기
# 특성을 생성 시킬때 y절편값도 생성을 함께 시킵니다.
# 특성만 있으면 되기 때문에 y절편은 생성에서 제외시키기 위해서 include_bias = False로 설정합니다.
poly = PolynomialFeatures(include_bias=False)
poly

### sample 데이터로 어떤 특성들이 만들어지는지 확인 먼저
temp_data = [[2, 3, 4]]
temp_data

### 특성을 만들 패턴 찾기
poly.fit(temp_data)

### 찾은 패턴으로 특성 생성하기
poly.transform(temp_data)

=> 출력 : array([[ 2.,  3.,  4.,  4.,  6.,  8.,  9., 12., 16.]])

○ 실제 독립변수를 이용해서 특성 생성하기


### 클래스 생성하기
# degree = 2 : 차원을 의미하며 2는 제곱승을 의미함
#            : 3을 넣으면 2의 제곱, 3의 제곱을 수행
#            : 4를 넣으면 2의 제곱, 3의 제곱, 4의 제곱승을 수행함
#            : 기본값은 2 (생략하면 2의 제곱승이 적용됨)
poly = PolynomialFeatures(degree=2, include_bias=False)
poly

### 패턴 찾기
# 훈련 독립변수 사용
poly.fit(train_input)

### 특성 생성하기
### 훈련 독립변수에 특성 추가하기
train_poly = poly.transform(train_input)

### 테스트 독립변수에 특성 추가하기
test_poly = poly.transform(test_input)

train_poly.shape, test_poly.shape

### 사용된 패턴 확인하기
poly.get_feature_names_out()

=> 출력 : 

((39, 19), (17, 19))
array(['x0', 'x1', 'x2', 'x0^2', 'x0 x1', 'x0 x2', 'x1^2', 'x1 x2',
       'x2^2', 'x0^3', 'x0^2 x1', 'x0^2 x2', 'x0 x1^2', 'x0 x1 x2',
       'x0 x2^2', 'x1^3', 'x1^2 x2', 'x1 x2^2', 'x2^3'], dtype=object)

○ 모델 생성, 훈련, 검증


### 모델 생성
lr = LinearRegression()
lr

### 모델 훈련시키기
lr.fit(train_poly, train_target)

### 훈련 정확도 및 테스트(검증) 정확도 확인
train_r2 = lr.score(train_poly, train_target)
test_r2 = lr.score(test_poly, test_target)

### 예측하기
test_pred = lr.predict(test_poly)

### 모델 평가하기(MAE)
mae = mean_absolute_error(test_target, test_pred)

train_r2, test_r2, mae

=> 출력 : (0.9961910731490471, 0.9454275516668981, 36.61538574646403)

해석🪄
- 특성공학을 적용하지 않은 모델은 검증(테스트) 정확도가 다소 낮았으며, 오차가 50g 정도 였으나, 
- 특성공학을 적용하여 특성을 추가하여 훈련 집중도를 높였을 때는
  → 훈련 및 검증(테스트) 정확도 모두 높아졌으며, 과적합이 발생하지 않은 일반화 모델로 오차는 30g 정도의 매우 우수한 모델로 판단됨
- 이 모델을 사용하려면, 독립변수의 특성 길이, 높이, 두께 3개의 특성을 사용해야 하며, 특성 생성 시 degree 2를 적용한 특성을 사용해야 함

 


 

<규제>
- 과대 또는 과소 적합 중에 주로 과대적합이 발생 했을 때 사용됩니다.
- 훈련의 정확도가 다소 낮아지는 경향이 있으나, 검증(테스트) 정확도를 높이는 효과가 있음
- 훈련모델을 일반화하는데 주로 사용되는 방법임
- 규제 개념을 적용한 향상된 모델 : 릿지(Ridge)와 라쏘(Lasso)가 있습니다.


<규제 순서>
1. 정규화 : 단위(스케일)을 표준화 시키는 방식
2. 규제가 적용된 모델 훈련/검증

 

훈련 및 테스트 독립변수 정규화하기

<정규화 순서>
1. 정규화 클래스 생성
2. fit() : 정규화 패턴 찾기 (훈련 독립변수 사용)
3. transform() : 찾은 패턴으로 정규화 데이터로 변환 (훈련 및 테스트 독립변수 변환)


### 현재 사용되는 독립변수
train_poly.shape, test_poly.shape

""" 정규화를 위한 라이브러리 """
from sklearn.preprocessing import StandardScaler

"""정규화 클래스 생성하기"""
ss = StandardScaler()
ss

"""정규화 패턴 찾기"""
ss.fit(train_poly)

"""찾은 패턴으로 훈련 및 테스트 독립변수 변환 생성하기"""
train_scaled = ss.transform(train_poly)
test_scaled = ss.transform(test_poly)

print(f"{train_scaled.shape} / {test_scaled.shape}")

#train_scaled

 ==> 출력 : (39, 9) / (17, 9)

 

릿지(Ridge) 모델

<정규화 순서>
1. 정규화 클래스 생성
2. fit() : 정규화 패턴 찾기 (훈련 독립변수 사용)
3. transform() : 찾은 패턴으로 정규화 데이터로 변환 (훈련 및 테스트 독립변수 변환)


### 모델 생성하기
from sklearn.linear_model import Ridge
ridge = Ridge()
ridge

"""모델 훈련 시키기"""
ridge.fit(train_scaled, train_target)

"""훈련 및 검증(테스트) 정확도 확인하기"""
train_r2 = ridge.score(train_scaled, train_target)
test_r2 = ridge.score(test_scaled,test_target)

train_r2, test_r2

"""예측하기"""
test_pred = ridge.predict(test_scaled)

"""평가하기(MAE)"""
mae = mean_absolute_error(test_target, test_pred)

train_r2, test_r2, mae


 ==> 출력 : (0.9849041294689239, 0.9845173591615219, 29.253911474018174)

 

해석🪄
- 과적합 여부를 확인한 결과, 과소적합은 발생하지 않았으며,
- 기존 특성공학을 적용한 우수한 모델보다는 훈련정확도는 0.005 정도 낮아 졌지만,
  검증(테스트) 정확도는 0.013 정도 높아졌음
- 또한, 평균절대오차(MAE)도 1g 낮아졌음
- 따라서, 일반화되고 오차가 작은 Ridge(릿지) 모델은 매우 우수한 모델로 판단됨

 


 

라쏘(Rasso) 모델


### 사용할 패키지
from sklearn.linear_model import Lasso

### 모델 생성하기
lasso = Lasso()
lasso

"""모델 훈련시키기"""
lasso.fit(train_scaled, train_target)

"""훈련 및 검증(테스트) 정확도 확인하기"""
train_r2 = lasso.score(train_scaled, train_target)
test_r2 = lasso.score(test_scaled, test_target)
train_r2, test_r2

"""예측하기"""
test_pred = lasso.predict(test_scaled)

"""평가하기"""
mae = mean_absolute_error(test_target, test_pred)

train_r2, test_r2, mae



 ==> 출력 : (0.9861305259897015, 0.98632202810554, 26.878384450173357)

해석🪄
- 0.0002정도의 과소적합이 있는 것으로 보임
- 오차값도 3g정도 작아 졌음
- 과소적합이 미세한 차이이기 때문에 릿지 모델과 비교 했을 때 나쁜 모델은 아니지만, 사용하기에는 미흡한 부분으로 판단됨

 


하이퍼파라메터 튜닝하기(규제 적용)


"""
릿지(Ridge) 모델 규제 튜닝하기
- alpha : 규제강도 값
- 값의 범위 0.001 ~ 100 사이의 값
- 값이 작을 수록 훈련 정확도는 낮아지면서, 과적합에 도움을 주게됨
- 값이 커질 수록 훈련 정확도는 높아짐, 과적합에는 도움이 되지 않을 수도 있음

- 기본 값은 = 1
"""

ridge = Ridge(alpha = 0.011)
ridge.fit(train_scaled, train_target)
ridge.score(train_scaled, train_target), ridge.score(test_scaled, test_target)
# alpha = 1 (0.9849041294689239, 0.9845173591615219)
# alpha = 0.1 (0.9882780161390031, 0.9868237771849514)
# alpha = 0.01 (0.9887392788057467, 0.9851828913418638)
# alpha = 0.011 (0.9887239787296944, 0.9852151542405199)
### 0.1일때가 가장 좋은 상태
--------------------------------------------
lasso = Lasso(alpha = 0.1)
lasso.fit(train_scaled, train_target)
lasso.score(train_scaled, train_target), lasso.score(test_scaled, test_target)

 ==> 출력

                    릿지 : (0.9887239787296944, 0.9852151542405199)
                    라쏘 : (0.9883448062768178, 0.9857016019582314)

 

 

 

728x90