1. 릿지, 라쏘, 엘라스틱 넷이란?
회귀모델에 규제를 가하는 방식인데요!! 규제를 통해 설명력이 좋은 변수는 남기고 좋지 않은 변수는 버리는 방식의 변수선택 개념입니다.
릿지: L2 규제를 사용!! -> 설명력이 낮은 변수를 0으로, 특성 무력화
라쏘: L1 규제를 사용!! -> 설명력이 낮은 변수를 0에 가깝게, 특성들의 영향력 감소
엘라스틱: 릿지 + 라쏘 적절히 조합!!
일부 특성이 중요하다면 릿지모델을!!, 특성의 중요도가 전체적으로 비슷하다면 라쏘 모델을!! 애매하면 둘을 적절히 조합해서 엘라스틱 넷을!! 사용하면 됩니다.
2. 릿지, 라쏘, 엘라스틱 넷 회귀모델 구현 - 데이터 확인-
데이터는 캐글에 있는 NBA 파이널 경기 데이터를 사용했어요!!
총 220개의 데이터이고 변수는 24개이고 각 변수들은 다음과 같습니다!!
Year : 시즌연도
Team : 팀명
Win: 승패여부 Win: 1, Loss: 0
Home : 홈어웨이여부 Home: 1, Away: 0
Game : 파이널 몇차전 경기인지 ex) 1: 1차전 , 2: 2차전
MP : 전체 경기 시간, 240을 넘어갈 경우 연장전
FG Field Goal : 성공 횟수
FGA Field Goal : 시도
FGP Field Goal : 성공률 (FGP=FG/FGA)
TP : 3점슛 성공횟수
TPA : 3점슛 시도 횟수
TPP : 3점슛 성공률 (TPP=TP/TPA)
FT : 자유투 성공횟수
FTA : 자유투 시도 횟수
FTP : 자유투 성공률 (FTP=FT/FTA)
ORB : 공격 리바운드 횟수
DRB : 수비 리바운드 횟수
TRB : 전체 리바운드 횟수(TRB=ORB+DRB)
AST : 어시스트 횟수
STL : 스틸 횟수
BLK : 블록 횟수
TOV : 턴오버 횟수
PF : 상대팀의 퍼스널 파울 횟수
PTS : 전체 득점
3. 릿지, 라쏘, 엘라스틱 넷 회귀모델 구현 - 변수간의 산점도 -
산점도를 통해 변수들간의 상관관계랑 선형관계도 보았는데요 PTS랑 FG가 눈에 띄는 선형관계를 가지네요!!
필드골이 많으면 전체득점도 많다는 일반적인 상식으로 볼 수 있겠죠?
4. 릿지, 라쏘, 엘라스틱 넷 회귀모델 구현 - 모델 생성 -
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
|
from sklearn.model_selection import cross_val_score
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.linear_model import Ridge, Lasso, ElasticNet
# alphas list 값을 반복하면서 alpha에 따른 평균 rmse를 구함
# cross_val_score를 이용해 5 폴드의 평균 RMSE를 계산
# alpha값에 따른 회귀 모델의 폴드 평균 RMSE를 출력하고 회귀계수 값들을 DataFrame으로 반환
y_target = team['PTS']
X_data = team.drop(['PTS','Team','Year','Game','Win','Home'], axis=1, inplace=False)
def get_linear_reg_eval(model_name, params=None, X_data_n=None, y_target_n=None, verbose=True):
coeff_df = pd.DataFrame()
if verbose : print('######', model_name, '######')
for param in params:
if model_name =='Ridge': model = Ridge(alpha=param)
elif model_name =='Lasso' : model = Lasso(alpha=param)
elif model_name =='ElasticNet': model = ElasticNet(alpha=param, l1_ratio=0.7)
neg_mse_scores = cross_val_score(model, X_data_n, y_target_n,
scoring='neg_mean_squared_error', cv = 5)
avg_rmse = np.mean(np.sqrt(-1*neg_mse_scores))
print('alpha {0}일 때 5 폴드 세트의 평균 RMSE: {1:.3f}'.format(param, avg_rmse))
model.fit(X_data, y_target)
coeff = pd.Series(data=model.coef_, index=X_data.columns )
colname='alpha:'+str(param)
coeff_df[colname] = coeff
return coeff_df
alphas = [0.07, 0.1, 0.5, 1, 3]
|
cs |
8번과 9번에서 독립변수와 종속변수를 구분했습니다. 그리고 데이터를 5개의 split으로 나누어 교차검증을 할 것이기 때문에 Train/test를 따로 분리해두지 않습니다. 11번부터는 alphas에 따른 릿지, 라쏘, 엘라스틱 넷 모델을 구축하고 5 fold의 평균 rmse를 뽑아내는 함수 입니다. 15번부터 17번까지 조건문에 따라 릿지, 라쏘, 엘라스틱 넷이 적용되는 것을 알 수 있습니다. alpha=param 는 29번에서 정의한 alphas가 들어갑니다. 18번에서 21번은 교차검증을 하고 평균 RMSE를 뽑아내는 코드입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# 릿지 회귀
coeff_ridge_df = get_linear_reg_eval('Ridge', params=alphas, X_data_n=X_data, y_target_n=y_target)
### 라쏘회귀
### W의 절댓값에 페널티를 부여하는 L1규제를 선형 회귀에 적용한 것
### 불필용한 회귀 계수를 급격하게 감소시켜 0으로 만들고 제거한다
coeff_lasso_df = get_linear_reg_eval('Lasso', params=alphas, X_data_n=X_data, y_target_n=y_target)
### 엘라스틱넷 회귀는 L2규제와 L1 규제를 결합한 회귀
# 엘라스틱넷에 사용될 alpha 파라미터의 값들을 정의하고 get_linear_reg_eval() 함수 호출
# ㅣ1_ratio는 0.7로 고정
coeff_elastic_df = get_linear_reg_eval('ElasticNet', params=alphas,
X_data_n=X_data, y_target_n=y_target)
|
cs |
위에서 정의한 함수를 다음과 같이 매개변수를 지정해서 모델을 생성하고 결과를 추출합니다.
5. 회귀계수 시각화
마지막으로 alpaha 값에 따른 릿지, 라쏘, 엘라스틱 넷 모델의 회귀계수를 시각화하는 코드입니다.
- 릿지 -
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# 반환된 coeff_ridge_df를 첫 번째 칼럼순으로 내림차순 정렬해 회귀계수 DataFrame 출력
sort_column = 'alpha:'+str(alphas[0])
coeff_ridge_df.sort_values(by=sort_column, ascending=False)
# 각 alpha에 따른 회귀 계수 값을 시각화하기 위해 5개의 열로 된 맷플롯립 축 생성
fig, axs = plt.subplots(figsize=(18, 6), nrows=1, ncols=5)
# 각 alpha에 따른 회귀 계수 값을 데이터로 저장하기 위한 DataFrame 생성
coeff_df = pd.DataFrame()
# alphas 리스트 값을 차례로 입력해 회귀 계수 값 시각화 및 데이터 저장.
for pos, alpha in enumerate(alphas) :
ridge = Ridge(alpha = alpha)
ridge.fit(X_data, y_target)
# alpha에 따른 피처별로 회귀 계수를 Series로 변환하고 이를 DataFrame의 칼럼으로 추가
coeff = pd.Series(data=ridge.coef_, index=X_data.columns)
colname='alpha:'+str(alpha)
coeff_df[colname] = coeff
# 막대 그래프로 각 alpha 값에서의 회귀 계수를 시각화. 회귀 계수값이 높은 순으로 표현
coeff = coeff.sort_values(ascending=False)
axs[pos].set_title(colname)
axs[pos].set_xlim(-3, 6)
sns.barplot(x=coeff.values, y=coeff.index, ax=axs[pos])
plt.show()
|
cs |
-라쏘-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# 반환된 coeff_lass_df를 첫 번째 칼럼순으로 내림차순 정렬해 회귀계수 DataFrame 출력
sort_column = 'alpha:'+str(alphas[0])
coeff_lasso_df.sort_values(by=sort_column, ascending=False)
# 각 alpha에 따른 회귀 계수 값을 시각화하기 위해 5개의 열로 된 맷플롯립 축 생성
fig, axs = plt.subplots(figsize=(18, 6), nrows=1, ncols=5)
# 각 alpha에 따른 회귀 계수 값을 데이터로 저장하기 위한 DataFrame 생성
coeff_df = pd.DataFrame()
# alphas 리스트 값을 차례로 입력해 회귀 계수 값 시각화 및 데이터 저장.
for pos, alpha in enumerate(alphas) :
lasso = Lasso(alpha = alpha)
lasso.fit(X_data, y_target)
# alpha에 따른 피처별로 회귀 계수를 Series로 변환하고 이를 DataFrame의 칼럼으로 추가
coeff = pd.Series(data=lasso.coef_, index=X_data.columns)
colname='alpha:'+str(alpha)
coeff_df[colname] = coeff
# 막대 그래프로 각 alpha 값에서의 회귀 계수를 시각화. 회귀 계수값이 높은 순으로 표현
coeff = coeff.sort_values(ascending=False)
axs[pos].set_title(colname)
axs[pos].set_xlim(-3, 6)
sns.barplot(x=coeff.values, y=coeff.index, ax=axs[pos])
plt.show()
|
cs |
-엘라스틱 넷-
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
|
# 반환된 coeff_elastic_df를 첫 번째 칼럼순으로 내림차순 정렬해 회귀계수 DataFrame 출력
sort_column = 'alpha:'+str(alphas[0])
coeff_elastic_df.sort_values(by=sort_column, ascending=False)
# 각 alpha에 따른 회귀 계수 값을 시각화하기 위해 5개의 열로 된 맷플롯립 축 생성
fig, axs = plt.subplots(figsize=(18, 6), nrows=1, ncols=5)
# 각 alpha에 따른 회귀 계수 값을 데이터로 저장하기 위한 DataFrame 생성
coeff_df = pd.DataFrame()
# alphas 리스트 값을 차례로 입력해 회귀 계수 값 시각화 및 데이터 저장.
for pos, alpha in enumerate(alphas) :
elastic = ElasticNet(alpha = alpha)
elastic.fit(X_data, y_target)
# alpha에 따른 피처별로 회귀 계수를 Series로 변환하고 이를 DataFrame의 칼럼으로 추가
coeff = pd.Series(data=elastic.coef_, index=X_data.columns)
colname='alpha:'+str(alpha)
coeff_df[colname] = coeff
# 막대 그래프로 각 alpha 값에서의 회귀 계수를 시각화. 회귀 계수값이 높은 순으로 표현
coeff = coeff.sort_values(ascending=False)
axs[pos].set_title(colname)
axs[pos].set_xlim(-3, 6)
sns.barplot(x=coeff.values, y=coeff.index, ax=axs[pos])
plt.show()
|
cs |
'머신러닝' 카테고리의 다른 글
[XGB][파라미터 최적화] Bayesian Optimization (0) | 2022.02.16 |
---|---|
[데이터 불균형][해결방안] Random UnderSampling (0) | 2022.02.11 |
[머신러닝][파이썬] Random Forest Regressor(회귀) (6) | 2022.01.26 |
[머신러닝][파이썬] Random Forest Classifier(분류) (0) | 2022.01.25 |
[머신러닝][앙상블/배깅][개념] 랜덤포레스트(Random Forest) (0) | 2022.01.20 |
댓글