特徴量の選択法の一つとして、単変量特徴量選択(univariate feature selection)という手法があり、scikit-learnのSelectKBestとSelectPercentileで実装が可能である。
Kaggle Grandmasterに学ぶ 機械学習 実践アプローチではこれら2つの手法を組み込んだラッパークラスが紹介されており、使ってみた。
# 単変量特徴量選択(univariate feature selection)のラッパークラスを作成
class UnivariateFeatureSelection:
def __init__(self, n_features, problem_type, scoring):
if problem_type == 'classification':
valid_scoring = {
'f_classif': f_classif,
'chi2': chi2,
'mutual_info_classif': mutual_info_classif
}
else:
valid_scoring = {
'f_regression': f_regression,
'mutual_info_regression': mutual_info_regression
}
# 手法が対応していない場合の例外の発生
if scoring not in valid_scoring:
raise Exception('Invalid scoring function')
if isinstance(n_features, int):
self.selection = SelectKBest(
valid_scoring[scoring],
k=n_features
)
elif isinstance(n_features, float):
self.selection = SelectPercentile(
valid_scoring[scoring],
percentile=int(n_features * 100)
)
else:
raise Exception('Invalid type of feature')
# fit関数
def fit(self, X, y):
return self.selection.fit(X, y)
# transform関数
def transform(self, X):
return self.selection.transform(X)
# fit_transform関数
def fit_transform(self, X, y):
return self.selection.fit_transform(X, y)
パラメータ
n_features:float型の場合はSelectPercentile、それ以外のときはSelectKBestを利用。
problem_type:分類('classification'
)or 回帰('regression'
)を文字列で。
scoring:
problem_type
がclassification
の場合、'f_classif'
(ANOVA F値)、'chi2'
(カイ二乗値)、'mutual_info_classif'
(相互情報量)のいずれかを文字列で。
problem_type
がregression
の場合、'f_regression'
(回帰分析 F値)、'mutual_info_regression'
(相互情報量)
ボストンデータセットで試してみた
# Bonstonデータセット
boston = load_boston()
X = boston.data
y = boston.target
ボストンデータセットの目的変数は住宅価格なので回帰分析(regression)。scoring
はf_regression
をせんたくしてみた。'n_features'
は4とし、特徴量を4つ選択した。
ufs = UnivariateFeatureSelection(n_features=4,
problem_type='regression',
scoring='f_regression'
)
ufs.fit(X, y) # X = boston.data, y = boston.target
X_transformed = ufs.transform(X)
mask = ufs.selection.get_support() # 各特徴量を選択した(True)、していない(False)
# 結果の確認(input: 特徴量、selected: 特徴量として選択されたかどうか)
selection_result = pd.DataFrame({'input': boston.feature_names, 'selected': mask})
print(selection_result)
input selected
0 CRIM False
1 ZN False
2 INDUS True
3 CHAS False
4 NOX False
5 RM True
6 AGE False
7 DIS False
8 RAD False
9 TAX False
10 PTRATIO True
11 B False
12 LSTAT True
今回のケースではINDUS(非小売業の割合)、RM(部屋数)、PTRATIO(生徒と先生の比率)、LSTAT(低所得者人口の割合)が選択された。