見出し画像

時系列向けの特徴量選択手法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()),
])