🍡 선형회귀모델 (LR; Liner Regression Model)
### 모델 라이브러리 불러들이기
from sklearn.linear_model import LinearRegression
### 사용할 데이터
train_input, train_target, test_input, test_target
### 모델(클래스 생성하기)
lr = LinearRegression()
### 모델 훈련 시키기
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.12로 과대적합이 의심됨
🍡임의 데이터로 예측하기
- KNN에서는 1033g을 예측했었음
lr.predict([[50]])
🍡추세선 그리기
- 추세선(예측선 이라고도 함)를 그리기 위한 계수값 추출하기
- 직선의 방정식 y = a * x + b
- coef_ : 기울기(계수) → a
- intercept_ : y절편 → b
lr.coef_, lr.intercept_
### 훈련데이터 산점도
plt.scatter(train_input, train_target)
### 예측값 산점도
plt.scatter(50, 1241.839, marker='^')
### 추세선
plt.plot([15, 50], [lr.coef_ * 15 + lr.intercept_,
lr.coef_ * 50 + lr.intercept_])
plt.grid()
plt.show()
# 선으로부터 떨어진 거리 = 오차 값(MAE)
- 추세선 시작값을 0으로 설정
### 훈련데이터 산점도
plt.scatter(train_input, train_target)
### 예측값 산점도
plt.scatter(50, 1241.839, marker='^')
### 추세선
plt.plot([0, 50], [lr.coef_ * 0 + lr.intercept_,
lr.coef_ * 50 + lr.intercept_])
plt.grid()
plt.show()
해석
- 임의 값 예측 시 KNN보다는 성능이 좋은 예측이 가능하며, 과적합이 발생하지 않는 일반화된 모델로 보여지나, y절편의 값이 음수로 예측시 음수의 데이터가 예측 될 가능성이 있는 모델로 보여짐
- 종속변수 무게의 값은 0이하로 나올 수 없기에 이상치를 예측할 수 있는 모델로 현재 사용하는 데이터를 예측하기에는 부적합한 모델로 여겨짐
🧁 다항회귀모델
- 데이터의 분포가 선형이면서 곡선을 띄는 경우에 사용됨
- 곡선(포물선)의 방정식이 적용되어 있음
- y = (a * x^2) + (b * x) +c
- 독립변수는 2개가 사용됨 : x^2값과 x값
🧁 훈련 및 테스트데이터의 독립변수에 x^2값 추가하기
# - 훈련 독립변수
train_poly = np.column_stack((train_input**2, train_input))
# - 테스트 독립변수
test_poly = np.column_stack((test_input**2, test_input))
train_poly.shape, test_poly.shape
🧁 모델 훈련 및 예측
### 모델 생성하기
# - 선형, 다형, 다중 회귀모델은 하나의 모델(클래스) 사용
# - 직선, 곡선에 대한 구분은 독립변수의 갯수로 모델이 알아서 구분해준다.
lr = LinearRegression()
### 모델 훈련 시키기
lr.fit(train_poly, train_target)
### 훈련 정확도 확인하기
train_r2 = lr.score(train_poly, train_target)
### 테스트 정확도 확인하기
test_r2 = lr.score(test_poly, test_target)
### 과적합 여부 확인(해석)
# - 0.007 정도의 과소적합(훈련 < 검증)이 발생
print(f"훈련 결정계수 = {train_r2} / 테스트 결정계수 = {test_r2}")
### 임의 값 길이 50으로 예측하기
pred = lr.predict([[50**2, 50]])
print(f"길이 50 예측 결과 : {pred}")
🧁 추세선 그리기
- 추세선을 그리기 위해서는 곡선의 방정식에 사용할 계수 a,b와 절편 c를 알아야 함
print(f"계수 = {lr.coef_} / 절편 = {lr.intercept_}")
a = lr.coef_[0]
b = lr.coef_[1]
c = lr.intercept_
print(f"a = {a} / b = {b} / c = {c}")
plt.scatter(train_input, train_target)
plt.scatter(50, pred[0], marker='^')
# 추세선
# - 추세선이 사용할 x축값 지정(0~50까지의 순차적인 값 사용)
point = np.arange(0, 51)
plt.plot(point, a*point**2 + b*point + c)
plt.grid()
plt.show()
해석
- 선형회귀모델의 경우에는 음의 절편값이 나타나는 모델이었으나, 다항회귀모델의 경우에는 이를 해소할 수 있었음
- 단, 길이(x)가 10이하의 독립변수는 사용하면 안됨
- 다항회귀모델의 훈련 및 테스트 결정계수의 결과 미세한 과소적합을 보이고 있으나, 사용가능한 모델로 판단됨
- 선형회귀모델에 비하여 독립변수들이 전체적으로 추세선에 가깝게 위치하고 있기에 오차가 적은 모델이라고 분석 됨
🧁 과소 / 과대 적합을 해소하기 위한 방법
- 데이터 양(row 데이터, 행)을 늘릴 수 있는지 확인
- 분석 모델이 좀 더 집중해서 훈련할 수 있도록 특성(독립변수)을 추가하는 방법 확인
→ 특성을 추가(늘리는)하는 방법은 "특성공학" 개념을 적용
→ 특성을 늘려서 사용하는 모델로 다중회귀모델이 있음
→ 특성을 늘린다는 의미는 훈련의 복잡도를 증가시킨다고 표현하며, 복잡도가 증가되면, 훈련의 집중력이 강해지게 됨 - 복잡도를 늘리는 방법으로는 "규제" 방법이 있음
→ "규제"를 하는 하이퍼파라미터 속성을 이용하는 방식으로 릿지와 라쏘 회귀모델 방식이 있음 - 이외 다른 회귀모델을 사용하여 비교
- 특성 → 컬럼, 필드, 퓨처 모두 같은 의미
- 데이터 처리 분야에서는 컬럼 또는 필드라고 칭하며, 머신러닝에서는 특성이라고 칭하며, 딥러닝에서는 퓨처라고 칭함
💎 다중회귀모델(Multiple Regression)
- 여러개의 특성을 사용한 회귀모델
- 특성이 많을수록 복잡도가 증가됨(훈련 시간이 오래걸림, 시스템 성능에 따라 빠를 수도 있음)
- 다중회귀모델 공식
y = a*x1 + b*x2 + c*x3 + ... + y절편 (x의 값은 3개 이상)
💎 데이터 불러들이기
- 사용할 데이터프레임 변수
import pandas as pd
df = pd.read_csv("./data/03_농어의_길이_높이_두께_데이터.csv")
💎 농어의 길이, 두께 높이 값을 이용해서 무게 예측하기
- 독립변수 : 길이, 두께, 높이
- 종속변수 : 무게
- 독립변수 생성하기
→ 데이터프레임의 특성 중에 독립변수로 사용할 특성들을 2차원의 리스트 또는 배열 형태로 만들어아야 한다.
→ to_numpy() : 행렬 데이터 형태를 리스트 배열 형태로 바꿈
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
💎 훈련 및 테스트 데이터로 분류하기
- 분류 기준 : 테스트 데이터를 30%로
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}")
💎 모델 훈련 및 평가
from sklearn.linear_model import LinearRegression
### 모델 생성하기
lr = LinearRegression()
### 모델 훈련시키기
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.07 ~ 0.08 정도로 과대적합 또한 일어나지 않은 일반화 된 모델로 볼 수 있음
- 다만, 검증(테스트) 정확도가 0.8대에서 0.9대로 올릴 수 없을지 고민해 본다.
- 특성공학을 적용하여 특성 늘리는 방법으로 집중도를 강화하는 방식을 사용해서 성능 향상이 되는지 확인한다. - 특성을 생성하는 라이브러리
- 사용 패키지 : sklearn.preprocessing
- 사용 클래스 : PolynomialFeatures(변환기라고 보통 칭한다)
- 사용 함수 : fit(훈련 독립변수에서 생성할 특성의 패턴 찾기), transform(찾은 패턴으로 특성 생성하기)
- 종속변수는 사용되지 않는다.
💎 테스트 데이터로 예측하기
test_pred = lr.predict(test_input)
test_pred
💎 평균절대오차(MAE) 확인하기
from sklearn.metrics import mean_absolute_error
mae = mean_absolute_error(test_target, test_pred)
mae
💎 특성공학
💎 특성공학 적용하기
- 패키지 정의하기
from sklearn.preprocessing import PolynomialFeatures
- 클래스 생성하기
- 특성을 생성 시킬 때 y절편값도 생성을 함께 시킨다.
- 특성만 있으면 되기 때문에 y절편은 생성에서 제외시키기 위해서 include_bias(y절편) = False로 설정한다.
poly = PolynomialFeatures(include_bias = False)
- sample 데이터로 어떤 특성들이 만들어지는지 확인하기
temp_data = [[2, 3, 4]]
temp_data
- 특성을 만들 패턴 찾기
poly.fit(temp_data)
- 찾은 패턴으로 특성 생성하기
poly.transform(temp_data)
💎 실제 독립변수를 이용해서 특성 생성하기
- 클래스 생성하기
- degree = 2
- 차원을 의미하며 2는 제곱승을 의미함
- 3을 넣으면 2의 제곱, 3의 제곱을 수행
- 4를 넣으면 2의 제곱, 3의제곱, 4의 제곱승을 수행함
- 기본값은 2 (생략하면 2의 제곱승이 적용됨)
poly = PolynomialFeatures(degree=2, include_bias=False)
- 패턴 찾기
- 훈련 독립변수 사용
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()
💎 모델 생성 / 훈련 / 예측 / 평가
### 모델 생성하기
lr = LinearRegression()
### 모델 훈련시키기
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)
print(f"훈련 = {train_r2} / 테스트 = {test_r2} / 오차 = {mae}")
해석
- 특성공학을 적용하지 않은 모델은 검증(테스트) 정확도가 다소 낮았으며, 오차가 50g 정도 있으나- 특성공학을 적용하여 특성을 추가하여 훈련 집중도를 높였을 때는 훈련 및 검증(테스트) 정확도 모두 높아졌으며, 과적합이 발생하지 않은 일반화 모델로 오차는 30g정도의 매우 우수한 모델로 판단 됨
- 이 모델을 사용하려면, 독립변수의 특성 길이, 높이, 두께 3개의 특성을 사용해야 하고 특성 생성 시 degree 2를 적용한 특성을 사용해야 함
💎규제
💎 규제
- 과대 또는 과소 적합 중에 주로 과대적합이 발생 했을 때 사용된다.
- 훈련의 정확도가 다소 낮아지는 경향이 있으나. 검증(테스트) 정확도를 높이는 효과가 있음
- 훈련모델을 일반화하는데 주로 사용되는 방법임
- 규제 개념을 적용한 향상된 모델 : 릿지(Ridge)와 라쏘(Lasso)가 있다.
💎 규제 순서
- 정규화(단위(스케일)을 표준화 시키는 방식)
- 규제가 적용된 모델 훈련 / 검증
💎 훈련 및 테스트 독립변수 정규화 하기
- 정규화를 위한 라이브러리
from sklearn.preprocessing import StandardScaler
- 정규화 순서
1. 정규화 클래스 생성
2. fit() : 정규화 패턴 찾기(훈련 독립변수 사용)
3. transform() : 찾은 패턴으로 정규화 데이터로 변환(훈련 및 테스트 독립변수 변환)
''' 1. 정규화 클래스 생성 '''
ss = StandardScaler()
''' 2. 정규화 패턴 찾기 '''
ss.fit(train_poly)
''' 3. 찾은 패턴으로 훈련 및 테스트 독립변수 변환 생성하기 '''
train_scaled = ss.transform(train_poly)
test_scaled = ss.transform(test_poly)
print(f"{train_scaled.shape} / {test_scaled.shape}")
릿지(Ridge) 모델
from sklearn.linear_model import 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)
print(f"훈련 = {train_r2} / 테스트 = {test_r2} / 오차 = {mae}")
해석
- 과적합 여부를 확인한 결과, 과소적합은 발생하지 않았으며- 기존 특성공학을 적용한 우수한 모델보다는 훈련 정확도는 0.005정도 낮아 졌지만 검증(테스트) 정확도는 0.013 정도 높아졌음
- 또한, 평균절대오차(MAE)도 1g 낮아졌음
- 따라서, 일반화되고, 오차가 적은 Ridge 모델은 매우 우수한 모델로 판단됨
라쏘(Lasso) 모델
### 사용할 패키지
from sklearn.linear_model import 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) '''
mae = mean_absolute_error(test_target, test_pred)
print(f"훈련 = {train_r2} / 테스트 = {test_r2} / 오차 = {mae}")
해석
- 0.0002 정도의 과소적합이 있는 것으로 보임
- 오차값도 3g정도 작아졌음
- 과소적합이 미세한 차이이기 때문에 릿지 모델과 비교 했을 때 나쁜 모델은 아니지만, 사용하기에는 미흡한 부분으로 판단 됨
💎 하이퍼파라미터 튜닝하기 (규제 적용)
- 릿지(Ridge) 모델 규제 튜닝하기
- alpha : 규제강도 값
- 값의 범위 0.001 ~ 100 사이의 값
- 값이 작을 수록 훈련 정확도는 낮아지면서, 과적합에 도움을 주게 됨
- 값이 커질 수록 훈련 정확도는 높아짐, 과적합에는 도움이 되지 읺을 수도 있음
- 기본 값은 = 1
ridge = Ridge(alpha=1)
ridge.fit(train_scaled, train_target)
ridge.score(train_scaled, train_target), ridge.score(test_scaled, test_target)
# 규제강도 1 (0.9849041294689239, 0.9845173591615219)
# 0 (0.9898271546307025, 0.971377160062062)
# 0.1 (0.9882780161390031, 0.9868237771849514) best!!
# 0.01 (0.9882780161390031, 0.9868237771849514)
# 0.001 (0.9891665643761299, 0.9844479791505587)
# 0.0001 (0.9897131221945868, 0.9790469305992887)
- 라쏘(Lasso) 모델 규제 튜닝하기
lasso = Lasso(alpha=0.1)
lasso.fit(train_scaled, train_target)
lasso.score(train_scaled, train_target), lasso.score(test_scaled, test_target)
# 0.1 (0.9883448062768178, 0.9857016019582314)
'Digital Boot > 인공지능' 카테고리의 다른 글
[인공지능][ML] Machine Learning - 랜덤포레스트 (2) (1) | 2023.12.27 |
---|---|
[인공지능][ML] Machine Learning - 분류모델 / 앙상블모델 / 배깅 / 부스팅 / 랜덤포레스트 (0) | 2023.12.26 |
[인공지능][ML] Machine Learning - KNN 회귀모델 / 평균절대오차(MAE) (0) | 2023.12.21 |
[인공지능][ML] Machine Learning - 훈련 및 테스트 데이터 분류하기 / 정규화 (3) | 2023.12.20 |
[인공지능][ML] Machine Learning - K최근접이웃모델 / KNN (5) | 2023.12.20 |