指定された変数に直交する(相関しない)予測を生成する


8

私が持っているXマトリックス、y変数、および他の変数をORTHO_VAR。私はをy使用して変数を予測する必要がありますXが、そのモデルからの予測は、可能な限りORTHO_VAR相関する一方で、直交する必要がありますy

私は予測がノンパラメトリックな方法で生成されることを望みxgboost.XGBRegressorますが、どうしても必要な場合は線形法を使用できます。

このコード:

import numpy as np
import pandas as pd
from sklearn.datasets import make_regression
from xgboost import XGBRegressor

ORTHO_VAR = 'ortho_var'
TARGET = 'target'
PRED = 'yhat'

# Create regression dataset with two correlated targets
X, y = make_regression(n_features=20, random_state=245, n_targets=2)
indep_vars = ['var{}'.format(i) for i in range(X.shape[1])]

# Pull into dataframe
df = pd.DataFrame(X, columns=indep_vars)
df[TARGET] = y[:, 0]
df[ORTHO_VAR] = y[:, 1]

# Fit a model to predict TARGET
xgb = XGBRegressor(n_estimators=10)
xgb.fit(df[indep_vars], df[TARGET])
df[PRED] = xgb.predict(df[indep_vars])

# Correlation should be low or preferably zero
pred_corr_w_ortho = df.corr().abs()[PRED][ORTHO_VAR]
assert pred_corr_w_ortho < 0.01, "Correlation score: {0} is superior to the given threshold.".format(pred_corr_w_ortho)

これを返します:

---------------------------------------------------------------------------
AssertionError                           
      1 pred_corr_w_ortho = df.corr().abs()[PRED][ORTHO_VAR]
----> 2 assert pred_corr_w_ortho < 0.01, "Correlation score: {0} is superior to the given threshold.".format(pred_corr_w_ortho)

AssertionError: Correlation score: 0.5895885756753665 is superior to the given threshold.

...そして、直交性を維持しながら、可能な限り多くの予測精度を維持するものが欲しい ORTHO_VAR


2
TARGETとORTHO_VARの相関関係は何ですか?
エスマイリアン

良い質問。それらは確かに相関関係があります(50%としましょう)。予測は直交させることによって精度の点で影響を受ける可能性があります。
クリス

回答:


5

この要件は、予測に十分なノイズを追加することで満たすことができます y^ それらを直交値から無相関化する v。理想的にはy^ からすでに非相関です v、ノイズは追加されません y^したがって、 y^ と最大の相関関係があります y

数学的には、 y^=y^+ε から εN0σε、 満たすため

ry^v=σy^vσy^σv<δ
任意のしきい値 δ。では、この不等式を拡張して、標準ノイズの下限を見つけましょうε、すなわち σε
σy^2=σy^2+σε2σy^v=E[y^+εμy^με=0vμv]=E[y^μy^vμv]+E[εvμv]=0=σy^vry^v=σy^vσy^σv=σy^vσvσy^2+σε2<δσy^ry^vδ21<σε

不等式の左側にある変数はすべて計算できるため、次の場所からノイズをサンプリングできます。 N0σε そしてそれらを追加する y^ 元の不平等を満たすため。

まったく同じことを行うコードを次に示します。

import numpy as np
import pandas as pd
from sklearn.datasets import make_regression
from xgboost import XGBRegressor

ORTHO_VAR = 'ortho_var'
IND_VARNM = 'indep_var'
TARGET = 'target'
CORRECTED_VARNM = 'indep_var_fixed'

seed = 245
# Create regression dataset with two correlated targets
X, y = make_regression(n_samples=10000, n_features=20, random_state=seed, n_targets=2)
indep_vars = ['var{}'.format(i) for i in range(X.shape[1])]

# Pull into dataframe
df = pd.DataFrame(X, columns=indep_vars)
df[TARGET] = y[:, 0]
df[ORTHO_VAR] = y[:, 1]

# Fit a model to predict TARGET
xgb = XGBRegressor(n_estimators=10)
xgb.fit(df[indep_vars], df[TARGET])
df['yhat'] = xgb.predict(df[indep_vars])

delta = 0.01

# std of noise required to be added to y_hat to bring the correlation
# of y_hat with ORTHO_VAR below delta
std_y_hat = np.std(df['yhat'], ddof=1)
corr_y_hat_ortho_var = np.corrcoef(df['yhat'], df[ORTHO_VAR])[1, 0]
corr_y_hat_target = np.corrcoef(df['yhat'], df[TARGET])[1, 0]
std_noise_lower_bound = std_y_hat * np.sqrt((corr_y_hat_ortho_var / delta)**2 - 1.0)
std_noise = max(0, std_noise_lower_bound) + 1
print('delta: ', delta)
print('std_y_hat: ', std_y_hat)
print('corr_y_hat_target: ', corr_y_hat_target)
print('corr_y_hat_ortho_var: ', corr_y_hat_ortho_var)
print('std_noise_lower_bound: ', std_noise_lower_bound)
print('std_noise: ', std_noise)

# add noise
np.random.seed(seed)
noises = np.random.normal(0, std_noise, len(df['yhat']))
noises -= np.mean(noises)  # remove slight deviations from zero mean
print('noise_samples: mean:', np.mean(noises), ', std: ', np.std(noises))
df['yhat'] = df['yhat'] + noises

# measure new correlation
corr_y_hat_ortho_var = np.corrcoef(df['yhat'], df[ORTHO_VAR])[1, 0]
corr_y_hat_target = np.corrcoef(df['yhat'], df[TARGET])[1, 0]
print('new corr_y_hat_target: ', corr_y_hat_target)
print('new corr_y_hat_ortho_var: ', corr_y_hat_ortho_var)
# Correlation should be low or preferably zero
assert corr_y_hat_ortho_var < delta, corr_y_hat_ortho_var
assert -delta < corr_y_hat_ortho_var, corr_y_hat_ortho_var

出力:

delta:  0.01
std_y_hat:  69.48568725585938
corr_y_hat_target:  0.8207672834857673
corr_y_hat_ortho_var:  0.7663936356880843
std_noise_lower_bound:  5324.885500165032
std_noise:  5325.885500165032
noise_samples: mean: 1.1059455573558807e-13 , std:  5373.914830034988
new corr_y_hat_target:  -0.004125016071865934
new corr_y_hat_ortho_var:  -0.000541131379457552

deltaのを試すことができます。と比較するstd_y_hatstd_noise_lower_bound、に大きなノイズを追加する必要があることがわかりますy^ それを無相関にする v うなり声 0.01、劇的に非難します y^ から y あまりにも。

注:Assertionしきい値が小さすぎると失敗する可能性がありますδ サンプル数が不十分なため。


yhatとターゲット変数間の相関の欠如は、2つのターゲット変数間の高い相関(たとえば、私の障害)に関連していますか?new corr_y_hat_targetできるだけ高く、できるだけnew corr_y_hat_ortho_var低くしたい
Chris

@Chris間接的にはい。場合targetと低い相関持っていたorthy_hatとの高い相関を持っています(target)も低相関を持っていたでしょうorth。その結果、低ノイズが追加されy_hat、その相関関係targetがわずかに変化します。
エスマイリアン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.