エフロンとハスティの「コンピュータ時代統計推論」の姿を再現


8

私の質問の要約版

(2018年12月26日)

EfronとHastieによるComputer Age Statistical Inferenceから図2.2を再現しようとしていますが、理解できない何らかの理由で、数値が本の数値と一致していません。

観測データ 2つの可能な確率密度関数、帰無仮説密度と代替密度間で決定しようとしていると仮定します。テストルールは、データを観測することを選択するまたはを示します。このようなルールには、2つの頻度エラーの確率が関連付けられています。実際にが生成したときに選択すること、およびその逆xf0(x)f1(x)t(x)01xf1f0x

α=Prf0{tバツ=1}
β=Prf1{tバツ=0}

ましょうである尤度比Lバツ

Lバツ=f1バツf0バツ

したがって、Neyman–Pearson補題は、形式のテストルールが最適な仮説テストアルゴリズムであると述べています。tcバツ

tcバツ={1ログの場合 Lバツc0ログの場合 Lバツ<c

ため、およびサンプルサイズの値であるもの以下のためのと遮断のための?f0N01f1N0.51=10αβc=0.4

  • 図2.2コンピュータ時代の統計的推論・エフロンとHastieによって、私たちは持っています:
    • α=0.10β = 0.38 、C = 0.4カットオフ場合、およびβ=0.38c=0.4
  • 2つの異なるアプローチを使用して、カットオフに対してとを見つけました:A)シミュレーションB)分析的α=0.15β=0.30c=0.4

カットオフに対しておよびを取得する方法を誰かに説明していただければです。ありがとう。α=0.10β=0.38c=0.4

私の質問の要約版はここで終わります。今からあなたは見つけるでしょう:

  • セクションA)で、私のシミュレーションアプローチの詳細と完全なPythonコード。
  • セクションB)で、分析的アプローチの詳細と完全なPythonコード。

A)完全なPythonコードと説明を含む私のシミュレーションアプローチ

(2018年12月20日)

本から...

同じ精神で、Neyman–Pearson補題は、最適な仮説検定アルゴリズムを提供します。これはおそらく、最もエレガントな頻度主義建築です。最も簡単な定式化では、NP補題は、観測データ 2つの可能な確率密度関数、帰無仮説密度と代替密度間で決定しようとしていると想定しています。。テストルールは、データを観測することを選択するまたはを示します。そのようなルールには、2つの頻度の高いエラー確率が関連付けられています。実際に生成されたときに選択するバツf0バツf1バツtバツ01バツf1f0バツ、およびその逆

α=Prf0{tバツ=1}
β=Prf1{tバツ=0}

ましょうである尤度比Lバツ

Lバツ=f1バツf0バツ

(出典:Efron、B。、およびHastie、T。(2016)。コンピューター時代の統計的推論:アルゴリズム、証拠、およびデータサイエンス。ケンブリッジ:Cambridge University Press。

だから、私は以下のPythonコードを実装しました...

import numpy as np

def likelihood_ratio(x, f1_density, f0_density):
    return np.prod(f1_density.pdf(x)) / np.prod(f0_density.pdf(x))

再び、本から...

およびテストルール定義することによって tcバツ

tcバツ={1ログの場合 Lバツc0ログの場合 Lバツ<c

(出典:Efron、B。、およびHastie、T。(2016)。コンピューター時代の統計的推論:アルゴリズム、証拠、およびデータサイエンス。ケンブリッジ:Cambridge University Press。

だから、私は以下のPythonコードを実装しました...

def Neyman_Pearson_testing_rule(x, cutoff, f0_density, f1_density):
    lr = likelihood_ratio(x, f1_density, f0_density)
    llr = np.log(lr)

    if llr >= cutoff:
        return 1
    else:
        return 0

最後に、本から...

ここに画像の説明を入力してください

カットオフはおよびを意味すると結論付けることができる場合。c=0.4α=0.10β=0.38

だから、私は以下のPythonコードを実装しました...

def alpha_simulation(cutoff, f0_density, f1_density, sample_size, replicates):
    NP_test_results = []

    for _ in range(replicates):
        x = f0_density.rvs(size=sample_size)
        test = Neyman_Pearson_testing_rule(x, cutoff, f0_density, f1_density)
        NP_test_results.append(test)

    return np.sum(NP_test_results) / float(replicates)

def beta_simulation(cutoff, f0_density, f1_density, sample_size, replicates):
    NP_test_results = []

    for _ in range(replicates):
        x = f1_density.rvs(size=sample_size)
        test = Neyman_Pearson_testing_rule(x, cutoff, f0_density, f1_density)
        NP_test_results.append(test)

    return (replicates - np.sum(NP_test_results)) / float(replicates)

そしてコード...

from scipy import stats as st

f0_density = st.norm(loc=0, scale=1)
f1_density = st.norm(loc=0.5, scale=1)

sample_size = 10
replicates = 12000

cutoffs = []
alphas_simulated = []
betas_simulated = []
for cutoff in np.arange(3.2, -3.6, -0.4):
    alpha_ = alpha_simulation(cutoff, f0_density, f1_density, sample_size, replicates)
    beta_ = beta_simulation(cutoff, f0_density, f1_density, sample_size, replicates)

    cutoffs.append(cutoff)
    alphas_simulated.append(alpha_)
    betas_simulated.append(beta_)

そしてコード...

import matplotlib.pyplot as plt
%matplotlib inline

# Reproducing Figure 2.2 from simulation results.
plt.xlabel('$\\alpha$')
plt.ylabel('$\\beta$')
plt.xlim(-0.1, 1.05)
plt.ylim(-0.1, 1.05)
plt.axvline(x=0, color='b', linestyle='--')
plt.axvline(x=1, color='b', linestyle='--')
plt.axhline(y=0, color='b', linestyle='--')
plt.axhline(y=1, color='b', linestyle='--')
figure_2_2 = plt.plot(alphas_simulated, betas_simulated, 'ro', alphas_simulated, betas_simulated, 'k-')

このようなものを取得するには:

ここに画像の説明を入力してください

これは本の元の図に似ていますが、シミュレーションの3タプルは、同じカットオフ本の値と比較すると、と値が異なります。。例えば:cαβαβc

  • 私たちが持っている本からc=0.4α=0.10β=0.38
  • 私のシミュレーションから:
    • c=0.4α=0.15β=0.30
    • c=0.8α=0.10β=0.39

私のシミュレーションのカットオフは、本のカットオフと同等のようです。c=0.8c=0.4

私がここで間違っていることを誰かに説明していただければ幸いです。ありがとう。

B)完全なPythonコードと説明を使用した計算アプローチ

(2018年12月26日)

私のシミュレーションの結果(alpha_simulation(.), beta_simulation(.))と本に掲載されている結果の違いを理解しようと、統計学者(ソフィア)の友人の助けを借りて、シミュレーションではなく分析的にとを計算しました。 。αβ

一度

f0N01
f1N0.51

その後

fバツ|μσ2=Π=112πσ2eバツμ22σ2

また、

Lバツ=f1バツf0バツ

そう、

Lバツ=f1バツ|μ1σ2f0バツ|μ0σ2=Π=112πσ2eバツμ122σ2Π=112πσ2eバツμ022σ2

したがって、次のような代数的簡略化を実行すると、次のようになります。

Lバツ=12πσ2eΣ=1バツμ122σ212πσ2eΣ=1バツμ022σ2

=eΣ=1バツμ12+Σ=1バツμ022σ2

=eΣ=1バツ22バツμ1+μ12+Σ=1バツ22バツμ0+μ022σ2

=eΣ=1バツ2+2μ1Σ=1バツΣ=1μ12+Σ=1バツ22μ0Σ=1バツ+Σ=1μ022σ2

=e2μ1μ0Σ=1バツ+μ02μ122σ2

だから、

tcバツ={1ログの場合 Lバツc0ログの場合 Lバツ<c

次に、場合:ログ Lバツc

ログ e2μ1μ0Σ=1バツ+μ02μ122σ2c

2μ1μ0Σ=1バツ+μ02μ122σ2c

Σ=1バツ2cσ2μ02μ122μ1μ0

Σ=1バツ2cσ22μ1μ0μ02μ122μ1μ0

Σ=1バツcσ2μ1μ0μ02μ122μ1μ0

Σ=1バツcσ2μ1μ0+μ12μ022μ1μ0

Σ=1バツcσ2μ1μ0+μ1μ0μ1+μ02μ1μ0

Σ=1バツcσ2μ1μ0+μ1+μ02

1Σ=1バツ1cσ2μ1μ0+μ1+μ02

Σ=1バツcσ2μ1μ0+μ1+μ02

バツ¯cσ2μ1μ0+μ1+μ02

バツ¯k、 どこ k=cσ2μ1μ0+μ1+μ02

その結果

tcバツ={1もし バツ¯k0もし バツ¯<k、 どこ k=cσ2μ1μ0+μ1+μ02

とを計算するために、次のことがわかります。αβ

α=Prf0{tバツ=1}
β=Prf1{tバツ=0}

そう、

α=Prf0{バツ¯k}β=Prf1{バツ¯<k} どこ k=cσ2μ1μ0+μ1+μ02

以下のための ...α

α=Prf0{バツ¯k}=Prf0{バツ¯μ0kμ0}

α=Prf0{バツ¯μ0σkμ0σ}

α=Prf0{Zスコアkμ0σ} どこ k=cσ2μ1μ0+μ1+μ02

だから、私は以下のpythonコードを実装しました:

def alpha_calculation(cutoff, m_0, m_1, variance, sample_size):
    c = cutoff
    n = sample_size
    sigma = np.sqrt(variance)

    k = (c*variance)/(n*(m_1-m_0)) + (m_1+m_0)/2.0

    z_alpha = (k-m_0)/(sigma/np.sqrt(n))

    # Pr{z_score >= z_alpha}
    return 1.0 - st.norm(loc=0, scale=1).cdf(z_alpha)

以下のための ...β

β=Prf1{バツ¯<k}=Prf1{バツ¯μ1<kμ1}

β=Prf1{バツ¯μ1σ<kμ1σ}

β=Prf1{Zスコア<kμ1σ} どこ k=cσ2μ1μ0+μ1+μ02

以下のpythonコードになります:

def beta_calculation(cutoff, m_0, m_1, variance, sample_size):
    c = cutoff
    n = sample_size
    sigma = np.sqrt(variance)

    k = (c*variance)/(n*(m_1-m_0)) + (m_1+m_0)/2.0

    z_beta = (k-m_1)/(sigma/np.sqrt(n))

    # Pr{z_score < z_beta}
    return st.norm(loc=0, scale=1).cdf(z_beta)

そしてコード...

alphas_calculated = []
betas_calculated = []
for cutoff in cutoffs:
    alpha_ = alpha_calculation(cutoff, 0.0, 0.5, 1.0, sample_size)
    beta_ = beta_calculation(cutoff, 0.0, 0.5, 1.0, sample_size)

    alphas_calculated.append(alpha_)
    betas_calculated.append(beta_)

そしてコード...

# Reproducing Figure 2.2 from calculation results.
plt.xlabel('$\\alpha$')
plt.ylabel('$\\beta$')
plt.xlim(-0.1, 1.05)
plt.ylim(-0.1, 1.05)
plt.axvline(x=0, color='b', linestyle='--')
plt.axvline(x=1, color='b', linestyle='--')
plt.axhline(y=0, color='b', linestyle='--')
plt.axhline(y=1, color='b', linestyle='--')
figure_2_2 = plt.plot(alphas_calculated, betas_calculated, 'ro', alphas_calculated, betas_calculated, 'k-')

最初のシミュレーションと非常によく似たと図と値を取得するにはαβ

ここに画像の説明を入力してください

そして最後に、シミュレーションと計算の結果を並べて比較します...

df = pd.DataFrame({
    'cutoff': np.round(cutoffs, decimals=2), 
    'simulated alpha': np.round(alphas_simulated, decimals=2),
    'simulated beta': np.round(betas_simulated, decimals=2),
    'calculated alpha': np.round(alphas_calculated, decimals=2),
    'calculate beta': np.round(betas_calculated, decimals=2)
})
df

その結果

ここに画像の説明を入力してください

これは、シミュレーションの結果が分析アプローチの結果と非常に似ている(同じではない場合)ことを示しています。

要するに、私はまだ私の計算で何が間違っているのかを理解するのに助けが必要です。ありがとう。:)


3
読者が11ページのコンピューターコード、統計出力、および代数に目を通すことを必要とする質問は、だれにも読まれそうになく、まともな回答もないようです。あなたがこれに費やした時間と注意からそうであるように、これを追求することに興味がある場合は、問題の核心を特定し、それを説明して質問できるかどうかを確認することをお勧めします1ページまたは最大2ページの資料?
whuber

1
こんにちは@whuber、ご提案ありがとうございます!私の意図は、誰でも私の結果を再現できるように詳細(ソースコードと説明)を投稿することでしたが、この戦略は正しく観察したようにうまく機能しなかったようです:)。ありがとうございました。次に、質問を編集して、投稿の冒頭で疑問を要約しました。これがうまくいくことを願っています。
Francisco Fonseca

回答:


3

書籍Computer Age Statistical InferenceのWebサイトには、Trevor HastieBrad Efronがしばしばいくつかの質問に答えるディスカッションセッションがあります。そこで、私はこの質問を(以下に)投稿し、Trevor Hastieから、修正される本にエラーがあることの確認を受け取りました(つまり、私のシミュレーションと計算-この質問のPythonで実装されている-は正しいです) )。

ここに画像の説明を入力してください

Trevor Hastie「実際にはそのプロットのc = .75」と答えたとき、下の図(本の元の図2.2)では、カットオフはではなくになるはずです。cc=0.75c=0.4

ここに画像の説明を入力してください

だから、私の機能を使用してalpha_simulation(.)beta_simulation(.)alpha_calculation(.)およびbeta_calculation(.)(その完全なPythonのコードはこの質問で利用可能です)私が得たおよびカットオフするために私のコードが正しいことを確認として。α=0.10β=0.38c=0.75

alpha_simulated_c075 = alpha_simulation(0.75, f0_density, f1_density, sample_size, replicates)
beta_simulated_c075 = beta_simulation(0.75, f0_density, f1_density, sample_size, replicates)

alpha_calculated_c075 = alpha_calculation(0.75, 0.0, 0.5, 1.0, sample_size)
beta_calculated_c075 = beta_calculation(0.75, 0.0, 0.5, 1.0, sample_size)

print("Simulated: c=0.75, alpha={0:.2f}, beta={1:.2f}".format(alpha_simulated_c075, beta_simulated_c075))
print("Calculated: c=0.75, alpha={0:.2f}, beta={1:.2f}".format(alpha_calculated_c075, beta_calculated_c075))

ここに画像の説明を入力してください

最後に、Trevor Hastie「... xのしきい値が.4になる」と回答した場合、次の方程式でであることを意味します(この質問のセクションBを参照):k=0.4

バツ¯k、 どこ k=cσ2μ1μ0+μ1+μ02

その結果

tcバツ={1もし バツ¯k0もし バツ¯<k、 どこ k=cσ2μ1μ0+μ1+μ02

したがって、Pythonでは、次のようにカットオフに対してを取得できます。k=0.4c=0.75

n = 10
m_0 = 0.0
m_1 = 0.5
variance = 1.0
c = 0.75

k = (c*variance)/(n*(m_1-m_0)) + (m_1+m_0)/2.0
threshold_for_x = k

print("threshold for x (when cutoff c=0.75) = {0:.1f}".format(threshold_for_x))

ここに画像の説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.