機械学習
python
自動取引
予測で使っているデータに問題が無いことを確認するためにボンフェローニ補正したコルモゴロフ・スミルノフ(KS)検定で特徴量の異常を検知する。 ボンフェローニ補正についてはwikipediaが詳しかったので、これを参考に実装した。 KS検定はscipyに実装があるので楽に実装できた。
ボンフェローニ補正自体はそんなに難しい概念ではなくて、複数回検定すると偶然棄却されてしまう可能性が上がるので、 全体で行う検定の回数に応じて、各検定の有意水準を割ることで補正を加えるという話のようだ。
def ks_test(
df1: pd.DataFrame, df2: pd.DataFrame, significant_level: float = 0.05, logger: Optional[logging.Logger] = None
) -> bool:
"""kstest with bonferroni correction"""
if set(df1.columns) != set(df2.columns):
raise ValueError("Columns are different")
threshold = significant_level / len(df1.columns)
reject = False
for col in df1.columns:
score = kstest(df1[col], df2[col])
if score.pvalue < threshold:
reject = True
# Log test result
head = "🆗"
if score.pvalue < threshold:
head = "🙅"
if logger:
logger.info(f"{head} p={score.pvalue: .3f} < {threshold: .3f} : {col}")
return reject
ちなみに学習時のデータと予測時のデータを比較してみたところ以下のようなログが出力された(変数名は諸事上でXXXに置き換え処理済み)。 バグってますね。
🆗 p= 1.000 > 0.002 : XXX
🆗 p= 1.000 > 0.002 : XXX
🆗 p= 0.898 > 0.002 : XXX
🆗 p= 1.000 > 0.002 : XXX
🆗 p= 1.000 > 0.002 : XXX
🆗 p= 1.000 > 0.002 : XXX
🆗 p= 1.000 > 0.002 : XXX
🆗 p= 1.000 > 0.002 : XXX
🆗 p= 1.000 > 0.002 : XXX
🆗 p= 0.619 > 0.002 : XXX
🆗 p= 1.000 > 0.002 : XXX
🆗 p= 1.000 > 0.002 : XXX
🆗 p= 0.695 > 0.002 : XXX
🆗 p= 1.000 > 0.002 : XXX
🆗 p= 0.635 > 0.002 : XXX
🆗 p= 0.992 > 0.002 : XXX
🆗 p= 1.000 > 0.002 : XXX
🆗 p= 1.000 > 0.002 : XXX
🙅 p= 0.000 < 0.002 : XXX
🙅 p= 0.000 < 0.002 : XXX
🙅 p= 0.000 < 0.002 : XXX