회귀분석에서 변수 선택법은 종속변수 y에 대한 독립변수 x가 미치는 영향력을 파악하고 유의미한 변수만을 추출하여 분석하기 위함이다.
변수선택법은 세 가지 방법이 존재하는데 1. 전진선택법 2. 후진제거법 3. 단계적선택법이 있다.
1. 회귀분석 전진선택법은 예측 모델을 만들 때 독립 변수를 선택하는 방법 중 하나이다. 이 방법은 단계별로 변수들을 추가해가며 모델을 구축하는 과정에서 가장 유의미한 변수들을 선택한다. 장점은 패턴을 찾기 쉬우며, 직관적이다. 단점은 최적의 변수 조합을 찾기가 어렵다. 독립변수를 차례대로 넣기 때문에 가장 좋은 모형인지 확인이 어렵다.
아래는 전진선택법을 진행하는 과정이다.
출처 : https://quantifyinghealth.com/stepwise-selection/
# 필요한 라이브러리 임포트
import statsmodels.api as sm
import pandas as pd
import numpy as np
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
# 데이터 로드 및 준비
boston = load_boston()
X = pd.DataFrame(boston.data, columns=boston.feature_names)
y = pd.Series(boston.target, name='MEDV')
# 데이터셋 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
# 전진 선택법 구현 함수
def forward_selection(data, target, significance_level=0.05):
initial_features = data.columns.tolist()
best_features = []
while initial_features:
remaining_features = list(set(initial_features) - set(best_features))
new_pval = pd.Series(index=remaining_features)
for new_column in remaining_features:
model = sm.OLS(target, sm.add_constant(data[best_features + [new_column]])).fit()
new_pval[new_column] = model.pvalues[new_column]
min_p_value = new_pval.min()
if min_p_value < significance_level:
best_features.append(new_pval.idxmin())
else:
break
return best_features
# 전진 선택법 적용
selected_features = forward_selection(X_train, y_train)
# 최종 모델 학습
final_model = sm.OLS(y_train, sm.add_constant(X_train[selected_features])).fit()
# 모델 요약 출력
print(final_model.summary())
# 모델 성능 평가
y_pred = final_model.predict(sm.add_constant(X_test[selected_features]))
mse = np.mean((y_test - y_pred) ** 2)
print(f'Mean Squared Error: {mse}')
- forward_selection 함수: 전진 선택법을 구현한 함수로, 각 단계에서 가장 유의한 변수를 선택하여 최종적으로 선택된 변수를 반환합니다.
- OLS 모델: statsmodels의 OLS(Ordinary Least Squares) 모델을 사용하여 회귀분석을 수행합니다.
- 평가: 최종 모델의 성능을 MSE(Mean Squared Error)로 평가합니다.
2. 후진제거법은 전진선택법과 반대로 모든 변수를 포함한 상태에서 영향력이 저조한 변수들을 하나씩 제거하며 높은 성능을 보이는 변수만 추출한다. 장점은 변수를 제거할 때마다 해당 변수의 중요도를 평가할 수 있다. 또한, 많은 변수를 선정할 가능성이 있어 설명력이 높은 모델이 만들어진다. 단점은 과적합이 될 가능성이 있다.
아래는 후진제거법을 진행하는 과정이다.
출처 : https://quantifyinghealth.com/stepwise-selection/
# 필요한 라이브러리 임포트
import statsmodels.api as sm
import pandas as pd
import numpy as np
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
# 데이터 로드 및 준비
boston = load_boston()
X = pd.DataFrame(boston.data, columns=boston.feature_names)
y = pd.Series(boston.target, name='MEDV')
# 데이터셋 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
# 후진 제거법 구현 함수
def backward_elimination(data, target, significance_level=0.05):
features = data.columns.tolist()
while len(features) > 0:
model = sm.OLS(target, sm.add_constant(data[features])).fit()
max_p_value = model.pvalues.max()
if max_p_value > significance_level:
excluded_feature = model.pvalues.idxmax()
features.remove(excluded_feature)
else:
break
return features
# 후진 제거법 적용
selected_features = backward_elimination(X_train, y_train)
# 최종 모델 학습
final_model = sm.OLS(y_train, sm.add_constant(X_train[selected_features])).fit()
# 모델 요약 출력
print(final_model.summary())
# 모델 성능 평가
y_pred = final_model.predict(sm.add_constant(X_test[selected_features]))
mse = np.mean((y_test - y_pred) ** 2)
print(f'Mean Squared Error: {mse}')
3. 마지막으로 단계적 선택법이다. 단계적 선택법은 전진선택법과 후진제거법을 결합하여 사용한다. 두 가지 모두를 사용하기 때문에 두 방법의 장점을 전부 가지고 있다. 하지만, 그만큼 단점도 모두 가지고 있기 때문에 과적합이 될 수 있고 불필요한 변수를 선택하거나 필요한 변수를 제거를 해버리는 실수를 할 수 있다.
아래는 단계적 선택법을 진행하는 과정이다.
# 필요한 라이브러리 임포트
import statsmodels.api as sm
import pandas as pd
import numpy as np
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
# 데이터 로드 및 준비
boston = load_boston()
X = pd.DataFrame(boston.data, columns=boston.feature_names)
y = pd.Series(boston.target, name='MEDV')
# 데이터셋 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
# 단계적 선택법 구현 함수
def stepwise_selection(data, target, significance_level_in=0.05, significance_level_out=0.05):
initial_features = data.columns.tolist()
best_features = []
while True:
changed = False
# 전진 선택법
remaining_features = list(set(initial_features) - set(best_features))
new_pval = pd.Series(index=remaining_features)
for new_column in remaining_features:
model = sm.OLS(target, sm.add_constant(data[best_features + [new_column]])).fit()
new_pval[new_column] = model.pvalues[new_column]
min_p_value = new_pval.min()
if min_p_value < significance_level_in:
best_features.append(new_pval.idxmin())
changed = True
# 후진 제거법
model = sm.OLS(target, sm.add_constant(data[best_features])).fit()
pvalues = model.pvalues.iloc[1:] # 상수(constant)를 제외한 p-values
max_p_value = pvalues.max()
if max_p_value > significance_level_out:
worst_feature = pvalues.idxmax()
best_features.remove(worst_feature)
changed = True
if not changed:
break
return best_features
# 단계적 선택법 적용
selected_features = stepwise_selection(X_train, y_train)
# 최종 모델 학습
final_model = sm.OLS(y_train, sm.add_constant(X_train[selected_features])).fit()
# 모델 요약 출력
print(final_model.summary())
# 모델 성능 평가
y_pred = final_model.predict(sm.add_constant(X_test[selected_features]))
mse = np.mean((y_test - y_pred) ** 2)
print(f'Mean Squared Error: {mse}')
다중공선성이란, 독립 변수들 간에 상관관계가 높아지는 현상을 말한다. 다중공선성이 높으면 회귀 모델의 추정치의 분산을 증가시켜 회귀 계수의 신뢰도를 낮추고, 모델 해석을 어렵게 만들어 버린다.
아래 출처 : ChatGPT
- 회귀 계수의 표준 오차가 증가: 이는 회귀 계수의 추정치가 불안정해지고, 통계적으로 유의하지 않은 변수를 중요한 변수로 잘못 판단하게 만들 수 있습니다.
- 모델의 예측력 저하: 모델의 예측 성능이 떨어질 수 있습니다.
- 회귀 계수 해석의 어려움: 어떤 독립 변수가 종속 변수에 영향을 미치는지 명확히 해석하기 어렵습니다.
다중공선성을 확인하기 위해서 산점도 그래프와 VIF를 활용 할 수 있다.
1. 산점도 그래프 행렬 시각화(독립변수만 확인하기 때문에 X 데이터 샘플만 생성)
# 라이브러리 가져오기
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# 예제 데이터를 생성합니다.
data = {
'X1': [1, 2, 3, 4, 5],
'X2': [2, 4, 6, 8, 10],
'X3': [5, 4, 3, 2, 1],
'X4': [10, 20, 30, 40, 50]
}
df = pd.DataFrame(data)
# 산점도 행렬 생성
sns.pairplot(df)
plt.show()
2. VIF란, 분산 팽창 계수로 다중공선성을 진단하기 위해 사용하는 지표이다. VIF는 특정 독립 변수가 다른 모든 독립 변수들에 의해 얼마나 설명되는지를 나타내며, 값이 클수록 다중공선성 문제가 심각하다는 것을 의미한다.
VIF 계산 방법:
VIF는 아래의 공식을 통해 계산됩니다.
여기서 분모에 R^2 회귀 분석에서 해당 독립 변수가 다른 독립 변수들로 설명되는 정도를 나타내는 결정 계수이다.
import pandas as pd
import numpy as np
import statsmodels.api as sm
from statsmodels.stats.outliers_influence import variance_inflation_factor
# 예제 데이터셋 생성
data = {
'X1': [10, 20, 30, 40, 50],
'X2': [20, 30, 40, 50, 60],
'X3': [30, 40, 50, 60, 70],
'Y': [1, 2, 3, 4, 5]
}
df = pd.DataFrame(data)
# 다중공선성 확인을 위해 독립 변수들만 추출
X = df[['X1', 'X2', 'X3']]
# 상수항 추가
X = sm.add_constant(X)
# VIF 계산
vif_data = pd.DataFrame()
vif_data["Feature"] = X.columns
vif_data["VIF"] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]
print(vif_data)
설명 :
예제 데이터셋을 생성합니다. 여기서 X1, X2, X3는 독립 변수들이고 Y는 종속 변수입니다.
독립 변수 추출 및 상수항 추가:
df[['X1', 'X2', 'X3']]을 통해 독립 변수들만 추출합니다.
sm.add_constant(X)을 통해 상수항을 추가합니다. 이는 회귀 분석에서 절편(intercept)을 고려하기 위함입니다.
VIF 계산:
variance_inflation_factor 함수를 사용하여 각 독립 변수의 VIF를 계산합니다.
VIF 해석 기준:
- VIF = 1: 다중공선성이 없음.
- 1 < VIF < 5: 다중공선성이 약간 있음.
- VIF > 5: 다중공선성이 있음. 주의가 필요함.
- VIF > 10: 다중공선성이 심각함. 조치가 필요함.
다중공선성을 해결하는 방법은 다음과 같다.
다중공선성 문제 해결 방법
- 독립 변수 제거: 다중공선성이 높은 변수를 모델에서 제거합니다.
- 주성분 분석 (PCA): 독립 변수들을 주성분으로 변환하여 상관관계를 줄입니다.
- 릿지 회귀 (Ridge Regression): 다중공선성을 완화하기 위해 L2 정규화를 사용합니다.
- 변수 선택 방법: 전진선택법, 후진제거법 또는 단계적 선택법을 사용하여 중요한 변수를 선택합니다.
독립 변수를 제거하기위해 변수를 선택하는 방법을 포스팅해보았다. 회귀분석에서는 모델의 성능을 올리기 위한 변수선택이 정말 중요하기 때문에 필수로 해야하는 작업이다.
출처 : https://quantifyinghealth.com/stepwise-selection/
Understand Forward and Backward Stepwise Regression – QUANTIFYING HEALTH
Running a regression model with many variables including irrelevant ones will lead to a needlessly complex model. Stepwise regression is a way of selecting important variables to get a simple and easily interpretable model. Below we discuss how forward and
quantifyinghealth.com
'Scientist > ML.DL' 카테고리의 다른 글
[ML/DL] NLP BERT 감정분석 (0) | 2024.07.15 |
---|---|
[ML/DL] NLP 단어 가방 모형 (0) | 2024.07.15 |
[ML/DL] Boosting 알고리즘 - XGBoost (1) | 2024.07.12 |
[ML/DL] 과대적합 및 과소적합 (1) | 2024.07.12 |
[Python] 가상환경 생성 및 쥬피터 커널 연결방법 (1) | 2024.07.10 |