일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 데이터 분석
- SQL
- 데이터 전처리
- 자격증
- 머신러닝
- IRIS
- 파이썬
- Python
- 데이터분석준전문가
- 딥러닝
- 이것이 코딩테스트다
- matplotlib
- tableau
- SQLD
- Google ML Bootcamp
- 데이터분석
- ADsP
- 이코테
- sklearn
- 태블로
- 코딩테스트
- r
- Deep Learning Specialization
- scikit learn
- pytorch
- 통계
- pandas
- 시각화
- 회귀분석
- ML
- Today
- Total
함께하는 데이터 분석
[Python] 규제 회귀 모델 본문
이어서 Python으로
규제 회귀 모델인
라쏘, 릿지, 엘라스틱넷 regression을 알아보겠습니다.
모듈 및 데이터 불러오기
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression, Lasso, Ridge, ElasticNet, LassoCV, RidgeCV, ElasticNetCV
from sklearn.preprocessing import StandardScaler
from sklearn import metrics
from sklearn.metrics import mean_squared_error
import warnings
warnings.simplefilter('ignore')
train데이터와 test데이터를 분리하고
선형회귀, 라쏘, 릿지, 엘라스틱넷 회귀모델을 사용하고
mse와 표준화 작업을 하기위해
사이킷런 모듈을 불러왔습니다.
from sklearn.datasets import load_boston
boston = load_boston()
df = pd.DataFrame(boston.data, columns = boston.feature_names)
df['price'] = boston.target
df.head()
보스턴 데이터를 불러와줬고
데이터 프레임으로 바꿔줬습니다.
변수 설명
CRIM | 범죄율 |
ZN | 25,000 평방 피트 당 주거용 토지의 비율 |
INDUS | 비소매(non-retail) 비즈니스 면적 비율 |
CHAS | 찰스 강 더미 변수 (통로가 하천을 향하면 1; 그렇지 않으면 0) |
NOX | 산화 질소 농도 (천만 분의 1) |
RM | 주거 당 평균 객실 수 |
AGE | 1940 년 이전에 건축된 자가 소유 점유 비율 |
DIS | 5 개의 보스턴 고용 센터까지의 가중 거리 |
RAD | 고속도로 접근성 지수 |
TAX | 10,000 달러 당 전체 가치 재산 세율 |
PTRATIO | 도시 별 학생-교사 비율 |
B | 1000 (Bk-0.63) ^ 2 여기서 Bk는 도시 별 검정 비율 |
LSTAT | 인구의 낮은 지위 |
price | 자가 주택의 중앙값 (1,000 달러 단위) |
데이터 구조
df.info()
df.describe()
데이터 전처리
# X, y 분할
X = df.drop(['price', 'CHAS'], axis = 1)
y = df['price']
X와 y로 분리시켜줬고
X를 설명변수, y를 타깃변수로 지정해줬습니다.
타깃변수를 price로 설정했죠.
print("X : ", X.shape)
print("y : ", y.shape)
>>> X : (506, 12)
y : (506,)
설명변수인 X는 506행 12열
타깃변수인 y는 506행 1 열인 것을 알 수 있습니다.
# StandardScaler
X_scaled = StandardScaler().fit_transform(X)
X_scaled = pd.DataFrame(X_scaled, columns = X.columns)
X_scaled.head()
앞서 이론에서 말씀드린 것처럼
변수 간의 값 차이가 많이 나므로
표준화 작업을 진행해줬습니다.
# train, test 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size = 0.3, random_state = 1234)
X와 y 각각 train데이터와 test데이터로 분리해줬는데
test데이터의 사이즈를 전체의 30%
즉, train데이터를 70%로 만들어줬습니다.
print("X_train : ", X_train.shape)
print("y_train : ", y_train.shape)
print("X_test : ", X_test.shape)
print("y_test : ", y_test.shape)
>>> X_train : (354, 12)
y_train : (354,)
X_test : (152, 12)
y_test : (152,)
따라서 train데이터가 354행으로 구성되고
test데이터가 152행으로 구성된 것을 볼 수 있죠.
모델링
1. Linear Regression
model = LinearRegression()
model.fit(X_train, y_train)
pred_train = model.predict(X_train)
pred_test = model.predict(X_test)
rmse_train = np.sqrt(mean_squared_error(y_train, pred_train))
rmse_test = np.sqrt(mean_squared_error(y_test, pred_test))
print("-----Linear regression-----")
print("train RMSE : ", round(rmse_train,3))
print("test RMSE : ", round(rmse_test,3))
>>> -----Linear regression-----
train RMSE : 4.731
test RMSE : 4.934
Linear regression 결과 train데이터의 RMSE는 4.731
test데이터의 RMSE는 4.934가 나왔습니다.
model.coef_
>>> array([-0.84140014, 1.52655434, -0.03424108, -2.46775466, 1.82310149,
0.21601194, -3.98417659, 3.37876671, -2.61704632, -2.4071317 ,
0.87645959, -4.12483541])
model.coef_ 를 통해 각각의 회귀계수 추정치를 알아봤습니다.
model.intercept_
>>> 22.447346745312675
model.intercept_를 통해 회귀선의 절편을 알아봤습니다.
2. Lasso Regression
model = Lasso(alpha = 0.1, random_state = 1234)
model.fit(X_train, y_train)
pred_train = model.predict(X_train)
pred_test = model.predict(X_test)
rmse_train = np.sqrt(mean_squared_error(y_train, pred_train))
rmse_test = np.sqrt(mean_squared_error(y_test, pred_test))
print("-----Lasso regression-----")
print("train RMSE : ", round(rmse_train,3))
print("test RMSE : ", round(rmse_test,3))
>>> -----Lasso regression-----
train RMSE : 4.788
test RMSE : 4.811
Lasso regression에서 알파를 0.1을 주었을 때
train데이터의 RMSE값이 4.788
test데이터의 RMSE값이 4.811인 것을 확인할 수 있습니다.
plt.figure(figsize = (6, 3))
coef = pd.Series(model.coef_, index = X_train.columns).sort_values()
plt.bar(coef.index, coef.values)
plt.title("Lasso / alpha = 0.1")
plt.xticks(rotation = 90)
Lasso regression을 활용할 때 각각의 회귀계수를 시각화한 결과입니다.
이번에는 알파 값을 여러 가지로 바꿔볼까요?
alpha_list = [0.001, 0.01, 0.1, 0.5, 1]
for alpha in alpha_list:
model = Lasso(alpha = alpha, random_state = 1234)
model.fit(X_train, y_train)
pred = model.predict(X_test)
rmse = np.sqrt(mean_squared_error(y_test, pred))
print("alpha = ", alpha, "일 때, RMSE = ", round(rmse,3))
>>> alpha = 0.001 일 때, RMSE = 4.932
alpha = 0.01 일 때, RMSE = 4.914
alpha = 0.1 일 때, RMSE = 4.811
alpha = 0.5 일 때, RMSE = 5.006
alpha = 1 일 때, RMSE = 5.27
알파 값이 여러 가지로 바뀜에 따라
test데이터의 RMSE값이 바뀌는 것을 볼 수 있죠.
이제 alpha 값의 변화에 따른 각각의 회귀 계수를 시각 해보겠습니다.
fig, axs = plt.subplots(figsize = (18, 6), nrows = 1, ncols = 5)
for pos, alpha in enumerate(alpha_list):
model = Lasso(alpha = alpha, random_state = 1234)
model.fit(X_train, y_train)
coef = pd.Series(model.coef_, index = X_train.columns).sort_values()
sns.barplot(x = coef.values, y = coef.index, ax = axs[pos])
axs[pos].set_title("alpha = " + str(alpha))
axs[pos].set_xlim(-5, 4)
plt.show()
앞서 말씀드린 것처럼 Lasso regression은 회귀계수 값을 0으로 만들 수 있는 것을 볼 수 있습니다.
3. Ridge Regression
model = Ridge(alpha = 10, random_state = 1234)
model.fit(X_train, y_train)
pred_train = model.predict(X_train)
pred_test = model.predict(X_test)
rmse_train = np.sqrt(mean_squared_error(y_train, pred_train))
rmse_test = np.sqrt(mean_squared_error(y_test, pred_test))
print("-----Ridge regression-----")
print("train RMSE : ", round(rmse_train,3))
print("test RMSE : ", round(rmse_test,3))
>>> -----Ridge regression-----
train RMSE : 4.754
test RMSE : 4.825
알파를 10을 줬을 때 train과 test데이터의 RMSE값입니다.
마찬가지로 회귀계수를 시각화해보겠습니다.
plt.figure(figsize = (6, 3))
coef = pd.Series(model.coef_, index = X_train.columns).sort_values()
plt.bar(coef.index, coef.values)
plt.title("Ridge / alpha = 10")
plt.xticks(rotation = 90)
이번에도 마찬가지로 알파 값에 변화를 주고 RMSE값을 비교해보겠습니다.
alpha_list = [0, 0.1, 1, 10, 100]
for alpha in alpha_list:
model = Ridge(alpha = alpha, random_state = 1234)
model.fit(X_train, y_train)
pred = model.predict(X_test)
rmse = np.sqrt(mean_squared_error(y_test, pred))
print("alpha = ", alpha, "일 때, RMSE = ", round(rmse,3))
>>> alpha = 0 일 때, RMSE = 4.934
alpha = 0.1 일 때, RMSE = 4.932
alpha = 1 일 때, RMSE = 4.917
alpha = 10 일 때, RMSE = 4.825
alpha = 100 일 때, RMSE = 4.93
알파가 10일 때 가장 낮은 RMSE값을 가지는 것을 볼 수 있습니다.
마찬가지로 각각의 알파 값에 대한 회귀계수를 시각화해보겠습니다.
fig, axs = plt.subplots(figsize = (18, 6), nrows = 1, ncols = 5)
for pos, alpha in enumerate(alpha_list):
model = Ridge(alpha = alpha, random_state = 1234)
model.fit(X_train, y_train)
coef = pd.Series(model.coef_, index = X_train.columns).sort_values()
sns.barplot(x = coef.values, y = coef.index, ax = axs[pos])
axs[pos].set_title("alpha = " + str(alpha))
axs[pos].set_xlim(-5, 4)
plt.show()
3. ElasticNet Regression
model = ElasticNet(alpha = 0.1, random_state = 1234)
model.fit(X_train, y_train)
pred_train = model.predict(X_train)
pred_test = model.predict(X_test)
rmse_train = np.sqrt(mean_squared_error(y_train, pred_train))
rmse_test = np.sqrt(mean_squared_error(y_test, pred_test))
print("-----ElasticNet regression-----")
print("train RMSE : ", round(rmse_train,3))
print("test RMSE : ", round(rmse_test,3))
>>> -----ElasticNet regression-----
train RMSE : 4.821
test RMSE : 4.782
알파가 0.1일 때 ElasticNet regression의 RMSE를 구해봤습니다.
k-fold cross validation으로 하이퍼 파라미터 찾기
cv = 5
alpha_list = [0.01, 0.05, 0.07, 0.1, 0.5, 0.75, 1, 3, 5, 7, 10]
k-fold cross validation을 통해
모든 데이터를 최소 한번 test데이터로 사용하여
결과가 편향되는 것을 방지하여
최적의 하이퍼 파라미터 값을 찾아보겠습니다.
# find optimal Lasso model
model = LassoCV(alphas = alpha_list, cv = cv)
model.fit(X_train, y_train)
print("Lasso : alpha = ", model.alpha_)
>>> Lasso : alpha = 0.01
위에서 Lasso regression에서 RMSE값이
알파가 0.01에서 가장 작았던 것처럼
하이퍼 파라미터도 0.01로 나오는 것을 볼 수 있습니다.
# find optimal Ridge model
model = RidgeCV(alphas = alpha_list, cv = cv)
model.fit(X_train, y_train)
print("Ridge : alpha = ", model.alpha_)
>>> Ridge : alpha = 10.0
Ridge regression도 마찬가지로 알파가 10일 때
RMSE가 가장 작았었죠.
# find optimal ElasticNet model
model = ElasticNetCV(alphas = alpha_list, cv = cv)
model.fit(X_train, y_train)
print("ElasticNet : alpha = ", model.alpha_)
>>> ElasticNet : alpha = 0.01
ElasticNet regression은 여러 가지 알파 값일 때
돌려보지는 않았지만 알파 값이 0.01일 때
RMSE가 가장 작을 것이라고 유추할 수 있습니다.
여기까지 규제 회귀 모델에 대해
Python으로 실습해봤습니다.
Copyright
- 비어플 빅데이터 학회
'학회 세션 > 비어플' 카테고리의 다른 글
규제 회귀 모델 (0) | 2022.04.02 |
---|---|
[R] 로지스틱 회귀 & LDA (0) | 2022.03.26 |
[Classification] LDA(선형 판별분석) (0) | 2022.03.26 |
[Python] IMAGE(2D data) AUGMENTATION (0) | 2022.03.24 |
[R] 데이터 불균형 해소 (0) | 2022.03.20 |