La version résumée de ma question
(26 décembre 2018)
J'essaie de reproduire la figure 2.2 de l' inférence statistique de l'âge de l' ordinateur par Efron et Hastie, mais pour une raison que je ne peux pas comprendre, les chiffres ne correspondent pas à ceux du livre.
Supposons que nous essayons de décider entre deux fonctions de densité de probabilité possibles pour les données observées , une densité d'hypothèse nulle et une densité alternative . Une règle de test dit quel choix, ou , nous ferons après avoir observé les données . Toute règle de ce type a deux probabilités d'erreur fréquentiste associées: choisir alors que réellement généré , et vice versa,
Soit le rapport de vraisemblance ,
Ainsi, le lemme de Neyman – Pearson dit que la règle de test de la forme est l'algorithme de test d'hypothèse optimal
Pour , et la taille de l'échantillon quelles seraient les valeurs pour et pour une coupure ?
- À partir de la figure 2.2 de l' inférence statistique de l'ère informatique par Efron et Hastie, nous avons:
- et pour une coupure
- J'ai trouvé et pour un seuil de coupure utilisant deux approches différentes: A) simulation et B) analytiquement .
J'apprécierais que quelqu'un m'explique comment obtenir et pour un seuil de coupure . Merci.
La version résumée de ma question se termine ici. A partir de maintenant, vous trouverez:
- Dans la section A) les détails et le code python complet de mon approche de simulation .
- Dans la section B) les détails et le code python complet de l' approche analytique .
A) Mon approche de simulation avec code python complet et explications
(20 décembre 2018)
Du livre ...
Dans le même esprit, le lemme de Neyman – Pearson fournit un algorithme de test d'hypothèse optimal. C'est peut-être la plus élégante des constructions fréquentistes. Dans sa formulation la plus simple, le lemme NP suppose que nous essayons de décider entre deux fonctions de densité de probabilité possibles pour les données observées , une densité d'hypothèse nulle et une densité alternative . Une règle de test dit quel choix, ou , nous ferons après avoir observé les données . Une telle règle a deux probabilités d'erreur fréquentiste associées: choisir lorsque réellement généré , et vice versa,
Soit le rapport de vraisemblance ,
(Source: Efron, B. et Hastie, T. (2016). Computer Age Statistical Inference: Algorithms, Evidence, and Data Science. Cambridge: Cambridge University Press. )
J'ai donc implémenté le code python ci-dessous ...
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))
Encore une fois, du livre ...
et définir la règle de test par
(Source: Efron, B. et Hastie, T. (2016). Computer Age Statistical Inference: Algorithms, Evidence, and Data Science. Cambridge: Cambridge University Press. )
J'ai donc implémenté le code python ci-dessous ...
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
Enfin, du livre ...
Où il est possible de conclure qu'un seuil de coupure impliquera et .
J'ai donc implémenté le code python ci-dessous ...
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)
et le code ...
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_)
et le code ...
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-')
pour obtenir quelque chose comme ça:
qui ressemble à la figure originale du livre, mais les 3-tuples de ma simulation ont des valeurs différentes de et par rapport à celles du livre pour la même coupure . Par exemple:
- du livre que nous avons
- de ma simulation, nous avons:
Il semble que le seuil de coupure de ma simulation soit équivalent au seuil de coupure du livre.
J'apprécierais que quelqu'un m'explique ce que je fais mal ici. Merci.
B) Mon approche de calcul avec code python complet et explications
(26 décembre 2018)
Toujours en essayant de comprendre la différence entre les résultats de ma simulation ( alpha_simulation(.), beta_simulation(.)
) et ceux présentés dans le livre, avec l'aide d'un de mes amis statisticien (Sofia), nous avons calculé et analytiquement au lieu de via la simulation, donc .. .
Une fois que
puis
De plus,
donc,
Par conséquent, en effectuant quelques simplifications algébriques (comme ci-dessous), nous aurons:
Donc si
alors, pour nous aurons:
résultant en
Afin de calculer et , nous savons que:
donc,
Pour ...
j'ai donc implémenté le code python ci-dessous:
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)
Pour ...
résultant dans le code python ci-dessous:
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)
et le code ...
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_)
et le code ...
# 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-')
pour obtenir un chiffre et des valeurs pour et très similaires à ma première simulation
Et enfin de comparer côte à côte les résultats entre simulation et calcul ...
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
résultant en
Cela montre que les résultats de la simulation sont très similaires (sinon les mêmes) à ceux de l'approche analytique.
En bref, j'ai encore besoin d'aide pour déterminer ce qui pourrait mal se passer dans mes calculs. Merci. :)