時系列向けの特徴量選択手法2
以下のバリエーションを考えました。
アイデア
要らない特徴量を選択する基準を、各特徴量と時刻の相互情報量にしました。
ポイント
上記のオリジナルのnote記事との違いは、まだ良くわかっていないですが、多分、ポイントは、n_neighborsです。sklearnのmutual_info_regressionの実装は、以下がベースになっているみたいです。
雑メモ: オリジナルのnote記事は本当はcvでpurge(ファイナンス機械学習みたいなやつ)しないといけない気がする(memorizeされてしまう)。purgeすると、この記事の手法に近くなる気がする。purgeのサンプル数と、n_neighborsが多分似た意味のパラメータになる気がする。
コード例
# license: CC0
import numpy as np
from sklearn.feature_selection import SelectPercentile, mutual_info_regression
from sklearn.linear_model import Ridge
from sklearn.pipeline import Pipeline
def calc_time_mi(x, n_neighbors=3):
return mutual_info_regression(
x.reshape(-1, 1),
np.linspace(0, 1, x.shape[0]),
n_neighbors=n_neighbors,
)[0]
def time_mi_feature_remover_score_func(X, y, n_neighbors=None):
mis = []
for i in range(X.shape[1]):
mis.append(calc_time_mi(X[:, i], n_neighbors=n_neighbors))
return -np.array(mis)
time_mi_feature_removal_mi_neighbors = 100
time_mi_feature_removal_ratio = 0.3
time_mi_feature_remover = SelectPercentile(
score_func=partial(time_mi_feature_remover_score_func, n_neighbors=time_mi_feature_removal_mi_neighbors),
percentile=100 * (1 - time_mi_feature_removal_ratio)
)
model = Pipeline([
('time_mi_feature_remover', time_mi_feature_remover),
('model', Ridge()),
])