본문 바로가기

CodeStates

[머신러닝 - 선형모델]#3

목차

 

#1

 

  • 선형회귀(Linear Regression)
  • 기준 모델(Baseline Model)
  • 예측 모델(Predictive Model)
  • Scikit-learn을 이용한 선형회귀모델 - 단순 선형 회귀(Simple Linear Regression)
  • 선형 회귀 모델 계수, 회귀계수 (Coeeficients)

 

#2

  • 다중선형회귀(Multiple Linear Regression)
  • Scikit-learn을 이용한 선형회귀모델 - 다중선형회귀(Multiple Linear Regression) 
    1)Categorical한 데이터를 수치화 시키는법
    2)하나의 데이터에서 Train/Test를 나누는 방법
    3)다중선형회귀 모델링
    4)회귀계수 해석
  • Overfitting과 Underfitting
  • 다항회귀모델

 

 

 

 

#3

  • 릿지회귀 (Ridge Regression)
  • Feature Engineering - 특성 선택 (Feature Selection)
    1)SelectKBest이용
  • Ridge Regression 모델링
    -Cross Validation

 

#4

  • 훈련/검증 /테스트
  • 분류(Classification)
  • 로지스틱 회귀모델
#3

 


지난시간에 배운 Overfitting을 해결하기 위해 어떤 방법을 써야할까?

  • 간단한 방법으로 모델의 복잡도를 줄인다.
  • 특성의 개수를 줄이거나 모델을 단순한 모양으로 생성한다.

 

릿지회귀 (Ridge Regression): 

과적합을 줄이기 위해 Bias(편향)을 조금 더하고 Varilance(분산)을 줄이는 방법을 통해 Regularization(정규화)를 한다.

정규화란 모델을 변형해서 과적합을 완화하고 일번화 성능을 높이는 기법이다.

즉, Ridge 회귀는 기존의 다중회귀선을 Train데이터에 덜 적합하게 모델링한다. 하지만 결과적으로 더 좋은 모델이 만들어진다.

  • n: 샘플수
  • p: 특성수
  • λ: 튜닝 파라미터(alpha, lambda, regularization parameter, penalty term라고도 부른다.)

λ값이 0이면 일반적인 다중 회귀 모델과 같고, λ값이 증가할 수록 회귀계수에 대한 영향력이 커진다.

하지만 λ값을 너무 키우면 Baseline 모델과 같아진다.

 

그렇다면 이 패널티값,  λ값을 보다 효율적으로 구할 수 있는 방법이 있을까?

이는 특별한 공식이 있는 것이 아니고 여러 패널티 값을 가지고 검증 실험을 한다.

교차 검증을 사용해 훈련/검증 데이터를 나누어 검증실험을 진행하면 된다.

 


 

 

 

 


Feature Engineering - 특성 선택 (Feature Selection):

특성공학이란 모델에 적합한 특성을 만들어 내는 과정을 뜻한다.

 

특성을 선택하는 방법

 

1)SelectKBest이용:

sklearn의 SelectKBest를 사용해서 특성을 선택한다.

 

from sklearn.feautre_selection import SelectKBest,f_regreesion,f_classfication

##Selector를 인스턴스
n = '특성 숫자'
##n개의 특성을 선택한다. 지금은 regression방식을 사용하지만 분류 학습을 진행할때에는
##classification으로 바꿔줘야한다.
selector = Selector(score_func = f_regression, k = n)

##데이터 특성 선택 
X_train_selected = selector.fit_transform(X_train, y_train)
train_scores = selector.scores_

X_test_selected = selector.transform(X_test, y_test)
test_scores = selector.scores_

fit_transform과 transform의 차이는 fit_transform은 train데이터에 transform은 test데이터에 사용한다.

위의 코드에서 설명을 하자면, fit_transform()은 train데이터를 가지고 학습을 하고 학습된 값을 test데이터에 적용하기위해 transform()을 사용한다. 만약에 fit_transform()을 test데이터에도 적용해 test데이터마저 학습을 하게 된다면 생성된 모델의 성능이 얼마나 좋은지 평가 불가능하기 때문에 사용하면 안된다.

 

from sklearn.feautre_selection import SelectKBest,f_regreesion,f_classfication

##전체 columns을 추출
all_names = X_train.columns

##선택된 특성의 index를 얻음
selected_mask = selector.get_support()

##전체 특성에서 선택된 특성의 index만을 selceted_names에 저장
selected_names = all_names[selected_mask]

##선택되지 않은 index를 unselceted_names에 저장
unselected_names = all_names[~selected_mask] 

##선택된 특성의 이름과 값을 dic형태로 저장후 sorting
dictonary = dict(zip(selected_names, train_scores))
dictonary = sorted(dictonary.items(), key = lambda item: item[1], reverse=True) 
dic_max = dictonary[0]

print("\nSelected list: \n",dictonary)

 

##예상 결과

 

Selected list: [('Reems', 7014.026027529143), ('CouncilArea_Boroondara City Council', 5292.991446822433), ('Method_SP', 3601.1771890708287), ('Type_h', 3463.9730175023456), ('CouncilArea_Wyndham City Council', 2163.955907353098), ('CouncilArea_Brimbank City Council', 1130.0222593349977), ('CouncilArea_Stonnington City Council', 936.9293644907547), ('Regionname_Northern Metropolitan', 371.0853744259934), ('Regionname_Western Metropolitan', 313.1768857767297), ('CouncilArea_Bayside City Council', 212.74036214264726), ('CouncilArea_Frankston City Council', 122.89081928637671), ('Type_u', 99.5939584695649), ('CouncilArea_Manningham City Council', 94.79227181446213), ('CouncilArea_Hume City Council', 80.7361356209319), ('CouncilArea_Melton City Council', 76.599580909311), ('CouncilArea_Whittlesea City Council', 72.25900122907373), ('Regionname_Southern Metropolitan', 49.31530828796826), ('Regionname_South-Eastern Metropolitan', 5.488496955752266), ('Method_VB', 2.7212403524002315), ('Distance', 1.363963996979283)]

 

 


 

 

 

 


Ridge Regression 모델링:

Cross Validation : 교차 검증이라는 뜻으로 데이터가 적어 데이터 하나하나가 귀할때 주로 사용한다.

def RidgeCVRegression(degree=3, **kwargs):
    return make_pipeline(PolynomialFeatures(degree), 
                         RidgeCV(**kwargs))

alphas = np.arange(0.01, 0.2, 0.01)

model = RidgeCVRegression(alphas=alphas, normalize=True, cv=5)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f'Test MAE: ${mae:,.0f}')
print(f'R2 Score: {r2:,.4f}\n')

coefs = model.named_steps["ridgecv"].coef_
print(f'Number of Features: {len(coefs)}')

print(f'alpha: {model.named_steps["ridgecv"].alpha_}')
print(f'cv best score: {model.named_steps["ridgecv"].best_score_}') # best score: R2

Test MAE: $111,705

R2 Score: 0.6945

Number of Features: 1330

alpha: 0.06999999999999999

cv best score: 0.7403019606698997

 

-> 최종모델링:

최종적으로 모델을 만들기 위해서는 가지고 있는 데이터를 다 사용해 최적의 모델을 만들어야한다.

지금 가지고 있는 테스트 데이터를 validation 데이터로 사용하려면 RidgeCV에 train 데이터로 함께 넣어 주어야 한다. RidgeCV내에서 train 데이터를 train ,validation 데이터로 나누어 최고 스코어를 가지는 alpha를 찾는다.

 

X_total = pd.concat([X_train, X_test])
y_total = pd.concat([y_train, y_test])

# 모든 데이터를 사용해 최종 모델을 만든다.
model = RidgeCVRegression(alphas=alphas, normalize=True, cv=5)
model.fit(X_total, y_total)

coefs = model.named_steps["ridgecv"].coef_
print(f'Number of Features: {len(coefs)}')

print(f'alpha: {model.named_steps["ridgecv"].alpha_}')
print(f'cv best score: {model.named_steps["ridgecv"].best_score_}')

coefs.max(), coefs.mean(), coefs.sort()

Number of Features: 1330

alpha: 0.19

cv best score: 0.7255485997685633

 

(70325.16065760396, 42.115772616436196)

 

array([-17325.27799422, -1175.83656738, -919.34030661, ..., 715.54010685, 719.44854755, 70325.1606576 ])

 

-> 몇몇 중요 회귀 계수를 제외하고는 대부분 0값을 갖는다.

'CodeStates' 카테고리의 다른 글

[note] 파이프라인  (0) 2021.04.14
[머신러닝 - 선형모델]#4  (0) 2021.04.08
[머신러닝 - 선형모델]#2  (0) 2021.04.08
[머신러닝 - 선형모델]#1  (0) 2021.04.07
[선형대수학]#2  (0) 2021.03.22