반응형
How to select Variables
Linear Regression CODE
0. EDA
항상 EDA와 도메인지식을 통해서 이상치와 결측을 제거하고 Feature Engineering을 통해 특성을 잘 조정해야한다. 모델의 성능을 높이는 데 가장 중요한 것은 다른데 있지 않다.
1. KBest
## K Best
from sklearn.feature_selection import SelectKBest, f_regression
selector = SelectKBest(score_func=f_regression, k=20) # Instance 생성
X_train_K = selector.fit_transform(X_train, y_train) # train 적용
X_test_K = selector.transform(X_test) # test 적용
print(X_train_K.shape, X_test_K.shape) # 결과
## 선택된 feature확인
all_names = X_train.columns
selected_mask = selector.get_support()
selected_names = all_names[selected_mask]
unselected_names = all_names[~selected_mask]
print('Selected names: ', selected_names)
print('Unselected names: ', unselected_names)
## K에 따른 RMSE, R2, R2 adj
feature_com = []
for i in range(1,30):
# feature개수 적용
selector = SelectKBest(score_func=f_regression, k=i)
X_train_BEST = selector.fit_transform(X_train, y_train)
X_test_BEST = selector.transform(X_test)
# Poly의 degree적용
poly_features = PolynomialFeatures(degree=3)
X_train_BEST = poly_features.fit_transform(X_train_BEST)
X_test_BEST = poly_features.fit_transform(X_test_BEST)
# Lambda값 적용
ridge = Ridge(alpha=0.1)
ridge.fit(X_train_BEST,y_train)
# 오차값산출
y_test_pred = ridge.predict(X_test_BEST)
mse = mean_squared_error(y_test, y_test_pred)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, y_test_pred)
r2 = r2_score(y_test, y_test_pred)
r2_adj = 1 - (1-r2)*(len(y_test)-1)/(len(y_test)-X_test_BEST.shape[1]-1)
# 리스트에 저장
feature_com.append([i, rmse, r2, r2_adj])
# in DataFrame
df_feature = pd.DataFrame(feature_com)
df_feature.columns = ['Num of K', "RMSE", "R2","R2_adj"]
df_feature.sort_values('R2_adj',ascending=False).head()
## Visualization
# K에 따른 RMSE
plt.figure(figsize=(15,5))
sns.barplot(x='Num of K',y='RMSE',data=df_feature)
plt.grid()
# K에 따른 R2, R2adj
plt.figure(figsize=(15,5))
sns.lineplot(x='Num of K',y='R2',data=df_feature,label='R2')
sns.lineplot(x='Num of K',y='R2_adj',data=df_feature, label='R2_adj')
plt.grid()
plt.show()
plt.show()
2. 전진선택법
## 전진선택법 알고리즘
import statsmodels.api as sm
df_2 = df_1.drop(columns='date').copy()
y = df_2['price'] # 타겟
df_2 = df_2.drop(columns='price').copy()
variables = df_2.columns[:].tolist() # 변수 리스트
selected_variables = [] ## 선택된 변수들
sl_enter = 0.01 # 유의수준
sv_per_step = [] # 각 스텝별로 선택된 변수들
adjusted_r_squared = [] # 각 스텝별 수정된 결정계수
steps = [] # 스텝
step = 0
while len(variables) > 0:
remainder = list(set(variables) - set(selected_variables))
pval = pd.Series(index=remainder) ## 변수의 p-value
# 기존에 포함된 변수와 새로운 변수 하나씩 돌아가면서 만들고 비교합니다.
for col in remainder:
X = df_2[selected_variables+[col]]
X = sm.add_constant(X)
model_OLS = sm.OLS(y,X.astype(float)).fit()
pval[col] = model_OLS.pvalues[col]
min_pval = pval.min()
if min_pval < sl_enter: # 최소 p-value 값이 기준 값보다 작으면 포함시킵니다.
selected_variables.append(pval.idxmin())
step += 1
steps.append(step)
adj_r_squared = sm.OLS(y,sm.add_constant(df_2[selected_variables].astype(float))).fit().rsquared_adj
adjusted_r_squared.append(adj_r_squared)
sv_per_step.append(selected_variables.copy())
else:
break
print(selected_variables) # 선택된 변수보기
## 시각화
fig = plt.figure(figsize=(25,5))
fig.set_facecolor('white')
font_size = 15
plt.xticks(steps,[f'step {s}\n'+'\n'.join(sv_per_step[i]) for i,s in enumerate(steps)], fontsize=12)
plt.plot(steps,adjusted_r_squared, marker='o')
plt.ylabel('Adjusted R Squared',fontsize=font_size)
plt.grid(True)
plt.show()
3. 후진선택법
## 후진 제거법. 전진선택법과 코드는 거의 비슷합니다.
import statsmodels.api as sm
df_2 = df_1.drop(columns='date').copy()
y = df_2['price'] # 타겟
df_2 = df_2.drop(columns='price').copy()
variables = df_2.columns[:].tolist() # 변수 리스트
selected_variables = variables # 이번에는 변수를 다 넣고 시작합니다.
sl_remove = 0.01
sv_per_step = [] # 각 스텝별로 선택된 변수들 넣을 빈 리스트
adjusted_r_squared = [] # 각 스텝별로 수정된 결정계수
steps = [] # 스텝
step = 0
while len(variables) > 0:
X = sm.add_constant(df[selected_variables])
p_vals = sm.OLS(y,X).fit().pvalues[1:] # 절편항의 p-value는 의미가 없으니 빼고
max_pval = p_vals.max() # 최대 p-value
if max_pval >= sl_remove: # 최대 p-value값이 기준값보다 크거나 같으면 제외합니다
remove_variable = p_vals.idxmax()
selected_variables.remove(remove_variable)
step += 1
steps.append(step)
adj_r_squared = sm.OLS(y,sm.add_constant(df_2[selected_variables].astype(float))).fit().rsquared_adj
adjusted_r_squared.append(adj_r_squared)
sv_per_step.append(selected_variables.copy())
else:
break
print(selected_variables) # 선택된 변수보기
## 시각화
fig = plt.figure(figsize=(10,3))
fig.set_facecolor('white')
font_size = 15
plt.xticks(steps,[f'step {s}\n'+'\n'.join(sv_per_step[i]) for i,s in enumerate(steps)], fontsize=12)
plt.plot(steps,adjusted_r_squared, marker='o')
plt.ylabel('Adjusted R Squared',fontsize=font_size)
plt.grid(True)
plt.show()
4. 단계별 선택법
## 단계별 선택법
import statsmodels.api as sm
df_2 = df_1.drop(columns='date').copy()
y = df_2['price'] # 타겟
df_2 = df_2.drop(columns='price').copy()
variables = df_2.columns[:].tolist() # 변수 리스트
selected_variables =[]
sl_enter = 0.05
sl_remove = 0.05
sv_per_step = [] # 각 스텝별로 선택된 변수들
adjusted_r_squared = [] # 각 스텝별 수정된 결정계수
steps = [] # 스텝
step = 0
while len(variables) > 0:
remainder = list(set(variables) - set(selected_variables))
pval = pd.Series(index=remainder) # 변수의 p-value
# 기존에 포함된 변수와 새로운 변수 하나씩 돌아가면서
# 선형 모형을 적합한다.
for col in remainder:
X = df[selected_variables+[col]]
X = sm.add_constant(X)
model_OLS = sm.OLS(y,X).fit()
pval[col] = model_OLS.pvalues[col]
min_pval = pval.min()
if min_pval < sl_enter: # 최소 p-value 값이 기준 값보다 작으면 포함
selected_variables.append(pval.idxmin())
# 선택된 변수들에대해 어떤 변수를 제거할지 고릅니다.
while len(selected_variables) > 0:
selected_X = df[selected_variables]
selected_X = sm.add_constant(selected_X)
selected_pval = sm.OLS(y,selected_X).fit().pvalues[1:] ## 절편항의 p-value는 빼고
max_pval = selected_pval.max()
if max_pval >= sl_remove: ## 최대 p-value값이 기준값보다 크거나 같으면 제외
remove_variable = selected_pval.idxmax()
selected_variables.remove(remove_variable)
else:
break
step += 1
steps.append(step)
adj_r_squared = sm.OLS(y,sm.add_constant(df[selected_variables])).fit().rsquared_adj
adjusted_r_squared.append(adj_r_squared)
sv_per_step.append(selected_variables.copy())
else:
break
print(selected_variables)
## 시각화
fig = plt.figure(figsize=(20,3))
fig.set_facecolor('white')
font_size = 15
plt.xticks(steps,[f'step {s}\n'+'\n'.join(sv_per_step[i]) for i,s in enumerate(steps)], fontsize=12)
plt.plot(steps,adjusted_r_squared, marker='o')
plt.ylabel('Adjusted R Squared',fontsize=font_size)
plt.grid(True)
plt.show()
반응형
'기본소양 > CODE' 카테고리의 다른 글
2. Tree based model CODE [1] Encode, Impute (0) | 2021.02.09 |
---|---|
2. Tree based model CODE [0] 시작은 언제나 EDA (0) | 2021.02.09 |
1. Linear Regression CODE [2] Modeling (0) | 2021.02.03 |
1. Linear Regression CODE [1] Simple Regression (0) | 2021.02.02 |
1. Linear Regression CODE [0] 시작은 언제나 EDA (0) | 2021.02.02 |
댓글