がゼロ以外の平均測定誤差で測定される可能性がある場合の回帰重みの使用


8

データを観察し、回帰モデルを近似したいとします。残念ながら、は平均値がゼロ以外の誤差で測定される場合があります。Y,XE[Y|X]Y

ましょうかどうかを示す、それぞれ古典的なゼロ平均誤差又は非ゼロ平均誤差で測定されます。を推定し。残念ながら、は通常観測されず、です。我々はの回帰合う場合は上の、我々は偏った予測を取得します。Z{unbiased,biased}YE[Y|X,Z=unbiased]ZE[Y|X,Z=unbiased]E[Y|X]YX

一般的に観察することはできないが、モデルにアクセスできるとします(Zを小さなトレーニングセットで手動で学習し、Zをターゲット変数として分類モデルを近似したため)。 。\ Pr [Z = \ text {unbiased} \、| \、X、Y]を使用してXYの回帰を当てはめますか?回帰の重みは\ mathbf {E} [Y \、| \、X、 Z = \ text {unbiased}](または、それに失敗すると、重みを使用しない場合よりもバイアスの少ない推定になります)?この方法は実際に使用されていますか、それとも名前がありますか?ZPr[Z|X,Y]ZZYXPr[Z=unbiased|X,Y]E[Y|X,Z=unbiased]

明確化:目標は、Z=unbiasedである目に見えないデータ(テストデータ)の平均二乗誤差を最小化するモデルに適合することです。その目的の最適な予測子はE[Y|X,Z=unbiased]なので、これが推定しようとしている関数です。この問題を解決する方法は、その目的をどれだけ達成できるかという点でランク付けする必要があります。


Rの小さな例df$y_is_unbiasedのロールプレイングZdf$y_observedのロールプレイングY

library(ggplot2)
library(randomForest)

set.seed(12345)

get_df <- function(n_obs, constant, beta, sd_epsilon, mismeasurement) {
    df <- data.frame(x1=rnorm(n_obs), x2=rnorm(n_obs), epsilon=rnorm(n_obs, sd=sd_epsilon))

    ## Value of Y if measured correctly
    df$y_unbiased <- constant + as.matrix(df[c("x1", "x2")]) %*% beta + df$epsilon

    ## Value of Y if measured incorrectly
    df$y_biased <- df$y_unbiased + sample(mismeasurement, size=n_obs, replace=TRUE)

    ## Y is equally likely to be measured correctly or incorrectly
    df$y_is_unbiased<- sample(c(TRUE, FALSE), size=n_obs, replace=TRUE)
    df$y_observed <- ifelse(df$y_is_unbiased, df$y_unbiased, df$y_biased)

    return(df)
}

## True coefficients
constant <- 5
beta <- c(1, 5)

df <- get_df(n_obs=2000, constant=constant, beta=beta, sd_epsilon=1.0, mismeasurement=c(-10.0, 5.0))

ggplot(df, aes(x=x1, y=y_observed, color=y_is_unbiased)) + geom_point() + scale_color_manual(values=c("#ff7f00", "#377eb8"))

## For facet_wrap title
df$string_y_is_unbiased <- paste0("y_is_unbiased: ", df$y_is_unbiased)

## Notice that Pr[Y | Z = biased] differs from Pr[Y | Z = unbiased]
ggplot(df, aes(x=y_observed)) + geom_histogram(color="black", fill="grey", binwidth=0.5) + facet_wrap(~ string_y_is_unbiased, ncol=1)

## Recover true constant and beta (plus noise) when using y_unbiased
summary(lm(y_unbiased ~ x1 + x2, data=df))

## Biased estimates when using y_biased (constant is biased downward)
summary(lm(y_biased ~ x1 + x2, data=df))

## Also get biased estimates when using y_observed (constant is biased downward)
summary(lm(y_observed ~ x1 + x2, data=df))

## Now image that we "rate" subset of the data (manually check/research whether y was measured with or without bias)
n_rated <- 1000
df_rated <- df[1:n_rated, ]

## Use a factor so that randomForest does classification instead of regression
df_rated$y_is_unbiased <- factor(df_rated$y_is_unbiased)

model_pr_unbiased <- randomForest(formula=y_is_unbiased ~ y_observed + x1 + x2, data=df_rated, mtry=2)

## Examine OOB confusion matrix (error rate < 5%)
print(model_pr_unbiased)

## Use the model to get Pr[Y is unbiased | X, observed Y] on unrated data
df_unrated <- df[(n_rated+1):nrow(df), ]
df_unrated$pr_unbiased <- as.vector(predict(model_pr_unbiased, newdata=df_unrated, type="prob")[, "TRUE"])

## Train a model on unrated data, using pr_unbiased as regression weights -- is this unbiased?
summary(lm(y_observed ~ x1 + x2, data=df_unrated, weights=df_unrated$pr_unbiased))

この例では、モデルは、を持つランダムフォレストです。このモデルが完全に正確である場合、がバイアスされていない場合は1.0、がバイアスされている場合は0.0の重みが生成され、加重回帰は明らかにバイアスされません。のモデルにテストの精度があり、再現率が完全ではない(100%未満の精度)場合、どうなりますか?加重回帰は、上の非加重回帰よりもバイアスが少ないことが保証されていますか?Pr[Z=unbiased|X,Y]Y Y Pr [ Z = 不偏formula=y_is_unbiased ~ y_observed + x1 + x2YYPr[Z=unbiased|X,Y]YX


がによって変化する少し複雑な例(上記で投稿した簡単な例である):Pr[Z=unbiased|X]XPr[Z=unbiased|X]=12X

library(ggplot2)
library(randomForest)

set.seed(12345)

logistic <- function(x) {
    return(1 / (1 + exp(-x)))
}

pr_y_is_unbiased <- function(x1, x2) {
    ## This function returns Pr[ Z = unbiased | X ]
    return(logistic(x1 + 2*x2))
}

get_df <- function(n_obs, constant, beta, sd_epsilon, mismeasurement) {
    df <- data.frame(x1=rnorm(n_obs), x2=rnorm(n_obs), epsilon=rnorm(n_obs, sd=sd_epsilon))

    ## Value of Y if measured correctly
    df$y_unbiased <- constant + as.matrix(df[c("x1", "x2")]) %*% beta + df$epsilon

    ## Value of Y if measured incorrectly
    df$y_biased <- df$y_unbiased + sample(mismeasurement, size=n_obs, replace=TRUE)

    ## Note: in this example, Pr[ Z = biased | X ] varies with X
    ## In the first (simpler) example I posted, Pr[ Z = biased | X ] = 1/2 was constant with respect to X
    df$y_is_unbiased <- runif(n_obs) < pr_y_is_unbiased(df$x1, df$x2)

    df$y_observed <- ifelse(df$y_is_unbiased, df$y_unbiased, df$y_biased)

    return(df)
}

## True coefficients
constant <- 5
beta <- c(1, 5)

df <- get_df(n_obs=2000, constant=constant, beta=beta, sd_epsilon=1.0, mismeasurement=c(-10.0, 5.0))

ggplot(df, aes(x=x1, y=y_observed, color=y_is_unbiased)) + geom_point() + scale_color_manual(values=c("#ff7f00", "#377eb8"))

## For facet_wrap title
df$string_y_is_unbiased <- paste0("y_is_unbiased: ", df$y_is_unbiased)

## Notice that Pr[Y | Z = biased] differs from Pr[Y | Z = unbiased]
ggplot(df, aes(x=y_observed)) + geom_histogram(color="black", fill="grey", binwidth=0.5) + facet_wrap(~ string_y_is_unbiased, ncol=1)

## Recover true constant and beta (plus noise) when using y_unbiased
summary(lm(y_unbiased ~ x1 + x2, data=df))

## Biased estimates when using y_biased (constant is biased downward)
summary(lm(y_biased ~ x1 + x2, data=df))

## Also get biased estimates when using y_observed
## Note: the constant is biased downward _and_ the coefficient on x2 is biased upward!
summary(lm(y_observed ~ x1 + x2, data=df))

## Now image that we "rate" subset of the data (manually check/research whether y was measured with or without bias)
n_rated <- 1000
df_rated <- df[1:n_rated, ]

## Use a factor so that randomForest does classification instead of regression
df_rated$y_is_unbiased <- factor(df_rated$y_is_unbiased)

model_pr_unbiased <- randomForest(formula=y_is_unbiased ~ y_observed + x1 + x2, data=df_rated, mtry=2)

## Examine OOB confusion matrix (error rate < 5%)
print(model_pr_unbiased)

## Use the model to get Pr[Y is unbiased | X, observed Y] on unrated data
df_unrated <- df[(n_rated+1):nrow(df), ]
df_unrated$pr_unbiased <- as.vector(predict(model_pr_unbiased, newdata=df_unrated, type="prob")[, "TRUE"])

## Train a model on unrated data, using pr_unbiased as regression weights -- is this unbiased? If not, is it _less_ biased than the unweighted model?
summary(lm(y_observed ~ x1 + x2, data=df_unrated, weights=df_unrated$pr_unbiased))

## What happens if we use pr_unbiased as a feature (aka predictor) in the regression, rather than a weight?
## In this case the weighted regression seems to do better, but neither is perfect
## Note: copied from shabbychef's answer
summary(lm(formula = y_observed ~ x1 + x2 + I(1 - pr_unbiased), data = df_unrated))

この例では、の加重回帰上のルックスが少ない非加重回帰よりも偏っ。それは一般的に本当ですか?また、この例についてシャビーシェフの提案(以下の回答を参照)を試したところ、加重回帰よりもパフォーマンスが悪いようです。YX


RよりPythonを好む方のために、Pythonでの2番目のシミュレーションを示します。

import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LinearRegression

def logistic(x):
    return 1 / (1 + np.exp(-x))

def pr_y_is_unbiased(x1, x2):
    # This function returns Pr[ Z = unbiased | X ]
    return logistic(x1 + 2*x2)

def get_df(n_obs, constant, beta, sd_epsilon, mismeasurement):
    df = pd.DataFrame({
        'x1': np.random.normal(size=n_obs),
        'x2': np.random.normal(size=n_obs),
        'epsilon': np.random.normal(size=n_obs, scale=sd_epsilon),
    })

    df['y_unbiased'] = constant + np.dot(np.array(df[['x1', 'x2']]), beta) + df['epsilon']

    # Note: df['y_biased'].mean() will differ from df['y_unbiased'].mean() if the mismeasurements have a nonzero mean
    df['y_biased'] = df['y_unbiased'] + np.random.choice(mismeasurement, size=n_obs)

    df['y_is_unbiased'] =  np.random.uniform(size=n_obs) < pr_y_is_unbiased(df['x1'], df['x2'])

    df['y_observed'] = df.apply(lambda row: row['y_unbiased'] if row['y_is_unbiased'] else row['y_biased'], axis=1)

    return df


constant = 5
beta = np.array([1, 5])
print(f'true coefficients:\n constant = {constant}, beta = {beta}')

n_obs = 2000

# Note: the mean of the possible mismeasurements is nonzero (this is the source of the bias)
df = get_df(n_obs=n_obs, constant=constant, beta=beta, sd_epsilon=1.0, mismeasurement=[-10.0, 5.0])

lr = LinearRegression()
lr.fit(X=df[['x1', 'x2']], y=df['y_observed'])

print(f'estimates from unweighted regression of Y on X ({df.shape[0]} obs):\n constant = {lr.intercept_}, beta = {lr.coef_}')

# Note: pretend that we only observe y_is_unbiased on a "rated" subset of the data
n_rated = n_obs // 2
df_rated = df.iloc[:n_rated].copy()
df_unrated = df.iloc[n_rated:].copy()

rf = RandomForestClassifier(n_estimators=500, max_features=2, oob_score=True)
rf_predictors = ['y_observed', 'x1', 'x2']

rf.fit(X=df_rated[rf_predictors], y=df_rated['y_is_unbiased'])

print(f'random forest classifier OOB accuracy (for predicting whether Y is unbiased): {rf.oob_score_}')

df_unrated['pr_y_is_unbiased'] = rf.predict_proba(df_unrated[rf_predictors])[:, 1]

lr.fit(X=df_unrated[['x1', 'x2']], y=df_unrated['y_observed'], sample_weight=df_unrated['pr_y_is_unbiased'])
print(f'estimates from weighted regression of Y on X ({df_unrated.shape[0]} obs):\n constant = {lr.intercept_}, beta = {lr.coef_}')

1
これは、「インストルメンタル変数」のように聞こえます。ここでは、回帰のエラーと相関するいくつかの変数を観察します。でも、それはあまり役に立たないと思います。
shabbychef

@shabbychef真ですが、この設定で使用できる楽器はありません。
エイドリアン

1
更新された問題により、バイアスは関数になり、回帰係数が変化することを期待できます。つまり、「バイアス」の項はで、です。私は拡大する、余分な線形依存性があることを示すために、テイラー展開と上と。元の質問に戻ると、表示されるバイアス項と観察される変数は、分散をまったく変更しませんが、期待値を変更します。したがって、それらは線形仕様にハッキングされるべきであり、重みにはハッキングされるべきではないと思います。0.25 p p = ロジスティックx 1 + 2 x 2p y x 1 x 2 zxi0.25pp=logistic(x1+2x2)pyx1x2z
シャビーシェフ

回答:


2

私は「バイアスの確率」を回帰のダミー変数として使用します。バイアスされたケースに存在するバイアスを「吸収」する可能性があります。あなたの例を使用して(しかしの呼び出しのset.seed(1234)前に呼び出しますget_df)、私は試しました

summary(lm(y_observed ~ x1 + x2 + I(1-pr_unbiased), data=df_unrated))

そして得た:

Call:
lm(formula = y_observed ~ x1 + x2 + I(1 - pr_unbiased), data = df_unrated)

Residuals:
   Min     1Q Median     3Q    Max 
-9.771 -2.722 -0.386  2.474 11.238 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)           5.515      0.250   22.07   <2e-16 ***
x1                    1.108      0.169    6.54    1e-10 ***
x2                    4.917      0.168   29.26   <2e-16 ***
I(1 - pr_unbiased)   -3.727      0.383   -9.72   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 5.25 on 996 degrees of freedom
Multiple R-squared:  0.514,     Adjusted R-squared:  0.513 
F-statistic:  351 on 3 and 996 DF,  p-value: <2e-16

用語の係数1-pr_unbiasedはバイアスのサイズでなければなりません。


面白いアイデア(+1)!が定数ではなく変化する2番目の少し複雑な例で投稿を更新しました。この場合、でを回帰するときに、x2の定数と係数の両方にバイアスがかかります。また、定数からバイアスを削除するだけなので、あなたの方法も機能しないと思います。見て、あなたの考えを教えてください!X Y XPr[Z=unbiased|X]XYX
エイドリアン

2

これは、観察されていないが応答変数と関係がある標識変数がある場合の省略された変数の問題です。「バイアス」は推定変数のプロパティであり、回帰変数ではないため、この変数を含まない回帰データを使用して、を条件とする真の回帰関数を見つけたい場所として質問を再構成します。確率を推定するために使用される回帰トレーニングデータの別のセット。ZZ=0p0(x,y)P(Z=0|X=x,Y=y)

pY|XYXZ

p(Y=y|X=x,Z=0)=p(Y=y,Z=0|X=x)p(Z=0|X=x)=p0(x,y)pY|X(y|x)Rp0(x,y)pY|X(y|x) dyyp0(x,y)pY|X(y|x).

pY|XZp0

YXpY|XZp^Y|Xp^0

p^(Y=y|X=x,Z=0)p^0(x,y)p^Y|X(y|x).

これらの推定量を置き換えたら、あとは、適切な密度関数を生成するスケーリング定数を決定することだけです。これは、さまざまな数値積分手法(シンプソンの法則、求積法、メトロポリスヘイスティングスなど)によって実行できます。


1
この詳細な回答(+1)をありがとうございます。慎重に読んで折り返しご連絡いたします。問題のより正確な説明は、「Yが偏っている」ではなく、「Yが非ゼロの平均誤差で測定されることがある」という場合があることに同意します。
エイドリアン

面白い!ここでの欠点の1つは、完全な分布を推定する必要があることです。Y|X

はい、しかし、それは実際にはトリッキーではないはずです。使用する回帰モデルには、この条件付き分布を決定する明確なモデル形式があります。
ベン-モニカを

1
YXY

1
エイドリアンは必ずしも(Y | X、Z = 0)の完全な分布に興味があるとは思わない。Y | X、Z = 0の完全な分布を知りたい場合はもちろん、YとXの正確な分布が非常に重要ですが、E [Y | X、Z = 0]のみを推定したい場合は、必要ありません:多数の法則は任意の分布に対して機能します。
user1111929

1

α<1α

P(Z=biased|X,Y)P(Z=biased|X,Y)<0.01NMnmf=n(N+M)N(n+m)nNmMf1

p=P(Z=biased|X,Y)>βββ=0.01(1pβ)2


分類器が100%正確でない限り、加重回帰は一般に不偏推定を生成しないことに同意します。バイアスを減らすことが保証されていますか?カットオフアプローチは必然的に優れていますか、それともサンプルサイズと分類子の精度に依存していますか?
エイドリアン

非常に小さなデータセットの場合、多数の行を破棄する余裕がない場合があるため、実際には分類子の正確さではなく、主に結果の行数が重要です。しかし、十分なデータがあれば、疑いの余地はありません。このアプローチでは、バイアスの確率が50%の行を、バイアスの確率が0%の行の半分と比較して重み付けします。個人的には、私は決してそれをしません。私は、それぞれがバイアスの50%の確率を持つ2000行よりも1000行のクリーンな保証行を強く望みます。両方のアプローチを組み合わせることもできます。プレーンなカットオフよりも緩やかなシステムを適用するために、これについて詳しく説明するように回答を更新しました。
user1111929
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.