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


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。

ため、およびサンプルサイズの値であるもの以下のためのと遮断のための?f0〜N(0、1)、f1〜N(0.5、1)ん=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(.))と本に掲載されている結果の違いを理解しようと、統計学者(ソフィア)の友人の助けを借りて、シミュレーションではなく分析的にとを計算しました。 。αβ

一度

f0〜N(0、1)
f1〜N(0.5、1)

その後

f(バツ|μ、σ2)=Π私=1ん12πσ2e−(バツ私−μ)22σ2

また、

L(バツ)=f1(バツ)f0(バツ)

そう、

L(バツ)=f1(バツ|μ1、σ2)f0(バツ|μ0、σ2)=Π私=1ん12πσ2e−(バツ私−μ1)22σ2Π私=1ん12πσ2e−(バツ私−μ0)22σ2

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

L(バツ)=(12πσ2)んe−Σ私=1ん(バツ私−μ1)22σ2(12πσ2)んe−Σ私=1ん(バツ私−μ0)22σ2

=e−Σ私=1ん(バツ私−μ1)2+Σ私=1ん(バツ私−μ0)22σ2

=e−Σ私=1ん(バツ私2−2バツ私μ1+μ12)+Σ私=1ん(バツ私2−2バツ私μ0+μ02)2σ2

=e−Σ私=1んバツ私2+2μ1Σ私=1んバツ私−Σ私=1んμ12+Σ私=1んバツ私2−2μ0Σ私=1んバツ私+Σ私=1んμ022σ2

=e2(μ1−μ0)Σ私=1んバツ私+ん(μ02−μ12)2σ2
。

だから、

tc(バツ)={1ログの場合 L(バツ)≥c0ログの場合 L(バツ)<c。

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

ログ (e2(μ1−μ0)Σ私=1んバツ私+ん(μ02−μ12)2σ2)≥c

2(μ1−μ0)Σ私=1んバツ私+ん(μ02−μ12)2σ2≥c

Σ私=1んバツ私≥2cσ2−ん(μ02−μ12)2(μ1−μ0)

Σ私=1んバツ私≥2cσ22(μ1−μ0)−ん(μ02−μ12)2(μ1−μ0)

Σ私=1んバツ私≥cσ2(μ1−μ0)−ん(μ02−μ12)2(μ1−μ0)

Σ私=1んバツ私≥cσ2(μ1−μ0)+ん(μ12−μ02)2(μ1−μ0)

Σ私=1んバツ私≥cσ2(μ1−μ0)+ん(μ1−μ0)(μ1+μ0)2(μ1−μ0)

Σ私=1んバツ私≥cσ2(μ1−μ0)+ん(μ1+μ0)2

(1ん)Σ私=1んバツ私≥(1ん)(cσ2(μ1−μ0)+ん(μ1+μ0)2)

Σ私=1んバツ私ん≥cσ2ん(μ1−μ0)+(μ1+μ0)2

バツ¯≥cσ2ん(μ1−μ0)+(μ1+μ0)2

バツ¯≥k、 どこ k=cσ2ん(μ1−μ0)+(μ1+μ0)2

その結果

tc(バツ)={1もし バツ¯≥k0もし バツ¯<k。、 どこ k=cσ2ん(μ1−μ0)+(μ1+μ0)2

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

α=Prf0{t(バツ)=1}、
β=Prf1{t(バツ)=0}。

そう、

α=Prf0{バツ¯≥k}、β=Prf1{バツ¯<k}。 どこ k=cσ2ん(μ1−μ0)+(μ1+μ0)2

以下のための ...α

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

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

α=Prf0{Zスコア≥k−μ0σん} どこ k=cσ2ん(μ1−μ0)+(μ1+μ0)2

だから、私は以下の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+μ0)2

以下の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 HastieとBrad 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+μ0)2

その結果

tc(バツ)={1もし バツ¯≥k0もし バツ¯<k。、 どこ k=cσ2ん(μ1−μ0)+(μ1+μ0)2

したがって、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.