Yêu cầu này có thể được thỏa mãn bằng cách thêm tiếng ồn vào dự đoán y^ để giải mã chúng từ các giá trị trực giao v. Lý tưởng nhất lày^ đã được giải mã từ v, không có tiếng ồn sẽ được thêm vào y^, do đó y^ sẽ được tương quan tối đa với y.
Về mặt toán học, chúng tôi muốn tạo ra y^'= =y^+ ε từ ϵ ∼ N( 0 ,σε), để thỏa mãn ry^'v= =σy^'vσy^'σv< δ
cho ngưỡng tùy ý δ. Bây giờ, hãy mở rộng sự bất bình đẳng này để tìm giới hạn thấp hơn cho std của tiếng ồnε, I E σε.
σ2y^'σy^'vry^'v= =σ2y^+σ2ε,= E [ (y^+ ϵ -μy^-με= 0) ( V -μv) ]= E [ (y^-μy^) ( V -μv) ] +E [ϵ(v-μv) ]= 0= =σy^v,= =σy^'vσy^'σv= =σy^vσvσ2y^+σ2ε------√<δ⇒σy^(ry^vδ)2- 1----------√<σε
Vì tất cả các biến ở phía bên trái của bất đẳng thức có thể được tính toán, chúng tôi có thể lấy mẫu tiếng ồn từ N( 0 ,σε) và thêm chúng vào y^ để thỏa mãn sự bất bình đẳng ban đầu.
Đây là một mã thực hiện chính xác điều tương tự:
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
đầu ra nào:
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
Bạn có thể thử nghiệm với các delta
s khác . Bằng cách so sánh std_y_hat
với std_noise_lower_bound
, bạn có thể thấy rằng một tiếng ồn lớn phải được thêm vàoy^ để giải mã nó từ v dưới đây 0,01, mà giảm đáng kể y^ từ y quá.
Lưu ý: Assertion
có thể thất bại cho các ngưỡng quá nhỏδ do số lượng mẫu không đủ.