import warnings
warnings.filterwarnings(action='ignore')
# warnings.filterwarnings(action='default')
from sklearn.feature_selection import SelectPercentile
from sklearn.feature_selection import f_regression, f_classif
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_boston
from sklearn.preprocessing import MinMaxScaler, PolynomialFeatures
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
boston = load_boston()
df_boston = pd.DataFrame(boston.data, columns=boston.feature_names)
df_boston['target'] = pd.Series(boston.target)
df_boston.head()
CRIM | ZN | INDUS | CHAS | NOX | RM | AGE | DIS | RAD | TAX | PTRATIO | B | LSTAT | target | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.00632 | 18.0 | 2.31 | 0.0 | 0.538 | 6.575 | 65.2 | 4.0900 | 1.0 | 296.0 | 15.3 | 396.90 | 4.98 | 24.0 |
1 | 0.02731 | 0.0 | 7.07 | 0.0 | 0.469 | 6.421 | 78.9 | 4.9671 | 2.0 | 242.0 | 17.8 | 396.90 | 9.14 | 21.6 |
2 | 0.02729 | 0.0 | 7.07 | 0.0 | 0.469 | 7.185 | 61.1 | 4.9671 | 2.0 | 242.0 | 17.8 | 392.83 | 4.03 | 34.7 |
3 | 0.03237 | 0.0 | 2.18 | 0.0 | 0.458 | 6.998 | 45.8 | 6.0622 | 3.0 | 222.0 | 18.7 | 394.63 | 2.94 | 33.4 |
4 | 0.06905 | 0.0 | 2.18 | 0.0 | 0.458 | 7.147 | 54.2 | 6.0622 | 3.0 | 222.0 | 18.7 | 396.90 | 5.33 | 36.2 |
# 입력 데이터와 출력데이터를 지정해준다.
X = df_boston.loc[ : , 'CRIM':'LSTAT']
y = boston.target
print("정규화, 확장 전 데이터 셋 : ", X.shape, y.shape)
정규화, 확장 전 데이터 셋 : (506, 13) (506,)
## 값을 전체적으로 0~1로 사이로 만들기
nor_X = MinMaxScaler().fit_transform(X)
nor_X.min(), nor_X.max()
(0.0, 1.0)
ex_X = PolynomialFeatures(degree=2, include_bias=False).fit_transform(nor_X)
print( ex_X.shape, type(ex_X) )
(506, 104) <class 'numpy.ndarray'>
X = ex_X # 입력
y = boston.target # 출력
X_train, X_test, y_train, y_test = train_test_split(X, y,
random_state=0,
test_size=0.5)
# 50%를 뽑는 것을 학습
select = SelectPercentile(score_func=f_regression, percentile=50)
select.fit(X_train, y_train)
SelectPercentile(percentile=50, score_func=<function f_regression at 0x000001F9335B2820>)
## 학습 세트에 적용
X_tr_selected = select.transform(X_train)
print( "X_train.shape:", X_train.shape)
print( "X_train_selected.shape", X_tr_selected.shape)
X_train.shape: (253, 104) X_train_selected.shape (253, 52)
import matplotlib.pyplot as plt
### 어떤 특성이 선택되었는지 확인
mask = select.get_support()
print(mask)
plt.matshow(mask.reshape(1, -1), cmap='gray_r')
[ True True True False True True False False False True True False True False False True False True False True True False True True False True False False False True True True False False False False True False True False True False True False True True True False True False False False False False False False False False False True False True False True True True False True True False True False False False True True True False True True True False True False False False False False False True True True False True True True False True True False True False True True]
<matplotlib.image.AxesImage at 0x1f9361f1880>
lr = LinearRegression()
lr.fit(X_train, y_train)
print("전체 특성 사용 score(학습) : {:.3f}".format(lr.score(X_train, y_train)))
print("전체 특성 사용 score(테스트): {:.3f}".format(lr.score(X_test, y_test)))
전체 특성 사용 score(학습) : 0.969 전체 특성 사용 score(테스트): 0.664
select = SelectPercentile(score_func=f_regression, percentile=50)
select.fit(X_train, y_train)
X_tr_selected = select.transform(X_train)
mask = select.get_support()
lr1 = LinearRegression()
lr1.fit(X_tr_selected, y_train)
X_test_selected = X_test[:, mask]
print(X_tr_selected.shape, X_test_selected.shape )
print("선택된 일부 특성 사용(학습용) : {:.3f}".format(lr1.score(X_tr_selected, y_train)))
print("선택된 일부 특성 사용(테스트용) : {:.3f}".format(lr1.score(X_test_selected, y_test)))
(253, 52) (253, 52) 선택된 일부 특성 사용(학습용) : 0.930 선택된 일부 특성 사용(테스트용) : 0.758
from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import RandomForestRegressor
select = SelectFromModel(RandomForestRegressor(n_estimators=100,
random_state=42),
threshold="median") # 1.25*mean, 0.75*mean
select.fit(X_train, y_train)
X_train_l1 = select.transform(X_train)
print("X_train.shape :" , X_train.shape)
print("X_train_l1.shape :", X_train_l1.shape)
X_train.shape : (253, 104) X_train_l1.shape : (253, 52)
### 어떤 특성이 선택되었는지 확인
mask = select.get_support()
print(mask)
plt.matshow(mask.reshape(1, -1), cmap='gray_r')
plt.xlabel("특성 번호")
[False False False False False True False False False False False True True False True True False True True True False False True True False True False True False False False False False False False False False False False False True False True True True False True True True False False False False False False False False False False False False False True False True True False True True True True True True True True True False True True True True True True False True True True True True False False True True True False True True True False True True False True True]
Text(0.5, 0, '특성 번호')
# 학습용, 테스트 데이터 변환
X_train_l1 = select.transform(X_train)
mask = select.get_support()
X_test_l1 = X_test[:, mask]
lr1 = LinearRegression()
lr1.fit(X_train_l1, y_train)
print("일부 특성 사용(SelectFromModel-학습) : {:.3f}".format(lr1.score(X_train_l1, y_train)))
print("일부 특성 사용(SelectFromModel-테스트) : {:.3f}".format(lr1.score(X_test_l1, y_test)))
일부 특성 사용(SelectFromModel-학습) : 0.940 일부 특성 사용(SelectFromModel-테스트) : 0.770
from sklearn.feature_selection import RFE
%%time
# RFE 반복적인 변수의 제거를 통해 좋은 피처만 남긴다.
select = RFE(RandomForestRegressor(n_estimators=100, random_state=42),
n_features_to_select=52)
select.fit(X_train, y_train)
# 선택된 특성을 표시합니다.
mask = select.get_support()
plt.matshow(mask.reshape(1,-1), cmap='gray_r')
plt.xlabel("특성 번호")
Wall time: 32.7 s
Text(0.5, 0, '특성 번호')
X_tr_rfe = select.transform(X_train)
mask = select.get_support()
X_test_rfe = X_test[:, mask]
model = LinearRegression().fit(X_tr_rfe, y_train)
print("일부 특성 사용(RFE-학습) : {:.3f}".format(model.score(X_tr_rfe, y_train)))
print("일부 특성 사용(RFE-테스트) : {:.3f}".format(model.score(X_test_rfe, y_test)))
일부 특성 사용(RFE-학습) : 0.941 일부 특성 사용(RFE-테스트) : 0.799
### RFE에서 사용된 모델로 예측
model = LinearRegression().fit(X_tr_rfe, y_train)
print("최종 모델 테스트 점수 : {:.3f}".format(model.score(X_test_rfe, y_test)))
최종 모델 테스트 점수 : 0.799