① [보스톤 집값 예측]
# 패키지 로딩
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression, Lasso, Ridge, ElasticNet
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
import numpy as np
import pandas as pd
# 데이터 로드 및 확인
boston = pd.read_csv('./Dataset/HousingData.csv')
print(boston.shape) # (506, 14)
display(boston.head())
# 결측값이 있는 레코드 삭제
boston.dropna(inplace=True)
# MEDV 주택 가격의 중위값은 종속변수
data_x = boston.drop('MEDV', axis=1) # MEDV 컬럼을 제외한 모든 컬럼은 독립변수
data_y = boston['MEDV']
data_x.describe()
# 학습, 평가 데이터 분리
scaled_data = StandardScaler().fit_transform(data_x)
x_train, x_test, y_train, y_test = train_test_split(scaled_data, data_y, test_size=0.3, random_state=10)
▷ 알파값 변화에 따른 회귀계수 및 상관계수 계산
- 알파값 : 규제의 강도를 제어하는 상수, [0, inf) 범위의 부동 소수점 값을 사용할 수 있다.
- alpha=0이면 LinearRegression에서 사용하는 일반적인 최소제곱법과 같아진다.
- 회귀계수 : weight값
- 상관계수 : r square깂
# 규제 비교 함수 (alpha값은 리스트로 반환, 회귀모형 종류)
def regulation_compare(alpha, model_name):
df = pd.DataFrame() # 결과를 데이터프레임으로 반환
for a in alpha: # alpha값의 종류만큼 반복
print('회귀모형:', model_name)
print('알파값:', a)
if model_name == 'Ridge':
model = Ridge(alpha=a)
elif model_name == 'Lasso':
model = Lasso(alpha=a)
elif model_name == 'ElasticNet': # Ridge와 Lasso 혼합 (l1_ratio 비율 지정)
model = ElasticNet(alpha=a, l1_ratio=0.5)
model.fit(x_train, y_train)
print(f'결정계수: {model.score(x_test, y_test):.3f}')
# 각 독립변수의 weight값을 만들기 위해서 딕셔너리 사용
# zip(f=컬럼의 이름, w=weight값)
weight = {f:w for f, w in zip(data_x.columns, model.coef_)}
y_hat = model.predict(x_test) # 예측값
# 정답과 예측값을 넣어서 MSE를 구하고 그 값을 근의 값으로 넣어서 RMSE를 구함
print(f'RMSE: {np.sqrt(mean_squared_error(y_test, y_hat)):.2f}')
print('='*20)
# 시리즈 값으로 딕셔너리를 넣어줌 (딕셔너리의 키가 인덱스가 됨)
df['alpha='+str(a)] = pd.Series(weight)
return df
▷ 라쏘 회귀모델 생성 (L1 규제)
# alpha값은 아주 작은 값부터 시작
alpha = [0.07, 0.1, 0.5, 1, 3]
regulation_compare(alpha, 'Lasso')
# 알파값이 증가할수록 제거되는 항이 많아지고 결정계수는 낮아짐
회귀모형: Lasso
알파값: 0.07
결정계수: 0.796
RMSE: 3.38
====================
회귀모형: Lasso
알파값: 0.1
결정계수: 0.798
RMSE: 3.37
====================
회귀모형: Lasso
알파값: 0.5
결정계수: 0.770
RMSE: 3.59
====================
회귀모형: Lasso
알파값: 1
결정계수: 0.738
RMSE: 3.84
====================
회귀모형: Lasso
알파값: 3
결정계수: 0.585
RMSE: 4.82
====================
▷ 릿지 회귀모델 생성 (L2 규제)
alpha = [0, 1, 5, 10, 100]
regulation_compare(alpha, 'Ridge')
# alpha값을 10으로 더 높였을 때 결정계수도 높아지고 오차율도 낮아짐
# 완전히 제외되는 항은 존재하지 않음
회귀모형: Ridge
알파값: 0
결정계수: 0.782
RMSE: 3.50
====================
회귀모형: Ridge
알파값: 1
결정계수: 0.784
RMSE: 3.48
====================
회귀모형: Ridge
알파값: 5
결정계수: 0.791
RMSE: 3.42
====================
회귀모형: Ridge
알파값: 10
결정계수: 0.796
RMSE: 3.39
====================
회귀모형: Ridge
알파값: 100
결정계수: 0.776
RMSE: 3.54
====================
▷ 엘라스틱 회귀모델 생성 (L1 + L2)
alpha = [0, 1, 5, 10, 100]
regulation_compare(alpha, 'ElasticNet')
# L1 규제 특성 포함 -> 알파값이 증가할수록 결정계수가 확 낮아짐
회귀모형: ElasticNet
알파값: 0
결정계수: 0.782
RMSE: 3.50
====================
회귀모형: ElasticNet
알파값: 1
결정계수: 0.725
RMSE: 3.93
====================
회귀모형: ElasticNet
알파값: 5
결정계수: 0.406
RMSE: 5.77
====================
회귀모형: ElasticNet
알파값: 10
결정계수: 0.108
RMSE: 7.07
====================
회귀모형: ElasticNet
알파값: 100
결정계수: -0.014
RMSE: 7.54
====================
② [대한민국 육군 몸무게 예측하기]
# 패키지 로딩
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression, Lasso, Ridge
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_absolute_error, r2_score
import numpy as np
import pandas as pd
# 데이터 로드 및 확인
army = pd.read_csv('./Dataset/Army-Dataset.csv')
print(army.shape) # (59996, 7)
display(army.head())
# Seq 컬럼 삭제
army.drop('Seq', axis=1, inplace=True)
army.describe()
# Weight는 종속변수, 나머지는 독립변수
data_x = army.drop('Weight', axis=1)
data_y = army['Weight']
# 독립변수간 상관관계 확인
import seaborn as sns
import matplotlib.pyplot as plt
sns.pairplot(data_x)
plt.show()
data_x.corr()
# 데이터 스케일링
# 스케일러를 먼저 만들고 transform으로 변형, fit과 transform 분리
scaler = StandardScaler().fit(data_x)
scaled_data = scaler.transform(data_x)
# 학습, 평가 데이터 분리
x_train, x_test, y_train, y_test = train_test_split(scaled_data, data_y, test_size=0.2, random_state=10)
ridge_alpha = 10
lasso_alpha = 1
linear = LinearRegression()
ridge = Ridge(alpha=ridge_alpha)
lasso = Lasso(alpha=lasso_alpha)
linear.fit(x_train, y_train)
ridge.fit(x_train, y_train)
lasso.fit(x_train, y_train)
# 예측 및 평가
linear_y_hat = linear.predict(x_test)
ridge_y_hat = ridge.predict(x_test)
lasso_y_hat = lasso.predict(x_test)
# r2_score는 정답과 예측값을 넣어줌
linear_r2 = r2_score(y_test, linear_y_hat)
ridge_r2 = r2_score(y_test, ridge_y_hat)
lasso_r2 = r2_score(y_test, lasso_y_hat)
linear_mae = mean_absolute_error(y_test, linear_y_hat)
ridge_mae = mean_absolute_error(y_test, ridge_y_hat)
lasso_mae = mean_absolute_error(y_test, lasso_y_hat)
print(f'R2 score - Linear: {linear_r2:.2f}, Ridge: {ridge_r2:.2f}, Lasso: {lasso_r2:.2f}')
print(f'MAE score - Linear: {linear_mae:.2f}, Ridge: {ridge_mae:.2f}, Lasso: {lasso_mae:.2f}')
# 규제를 썼을 때와 안 썼을 때 차이 없음
R2 score - Linear: 0.89, Ridge: 0.89, Lasso: 0.88
MAE score - Linear: 3.54, Ridge: 3.54, Lasso: 3.68
# 모든 컬럼의 0행 확인
data_x.iloc[0]
Chest 96.3
Height 185.5
Waist 82.5
Head 57.1
Foot 28.5
Name: 0, dtype: float64
# 새로운 값이 들어왔을 때의 예측
# 가슴둘레 90, 키 178, 허리둘레 80, 머리둘레 55, 발길이 26.5
new_data = np.array([90, 178, 80, 55, 26.5]).reshape(1,5) # 1행5열의 2차원으로 변환
linear.predict(scaler.transform(new_data)) # 그냥 new_data값을 넣어주면 값이 너무 크게 나오기 때문에 스케일러를 써줘야 함
array([65.2490275])
'데이터 분석 > 머신러닝' 카테고리의 다른 글
[ML] 5. 이진분류 - Logistic Regression (0) | 2023.11.20 |
---|---|
[ML] 4. 교차 검증 (Cross Validation) (1) | 2023.11.20 |
[ML] 지도학습 알고리즘 - 분류분석, 다항 로지스틱 회귀분석 (0) | 2023.11.20 |
[ML] 과대적합(Over Fitting) 방지 - 데이터 규제, 교차검증 (0) | 2023.11.20 |
[ML] 다중공선성과 변수 선택 (1) | 2023.11.20 |