A versão resumida da minha pergunta
(26 de dezembro de 2018)
Estou tentando reproduzir a Figura 2.2 da Inferência Estatística da Era do Computador de Efron e Hastie, mas por alguma razão que não sou capaz de entender, os números não são correspondentes aos do livro.
Suponha que estamos tentando decidir entre duas funções possíveis de densidade de probabilidade para os dados observados , uma densidade de hipótese nula e uma densidade alternativa . Uma regra de teste diz qual escolha, ou , faremos tendo observado os dados . Qualquer regra desse tipo tem duas probabilidades de erro frequente associadas: escolher quando na verdade gerou vice-versa,
Seja a razão de verossimilhança ,
Portanto, o lema de Neyman – Pearson diz que a regra de teste da forma é o algoritmo ideal de teste de hipótese
Para e tamanho da amostra quais seriam os valores para e para um ponto de corte ?
- Na Figura 2.2 da Inferência Estatística da Era do Computador por Efron e Hastie, temos:
- e para um ponto de corte
- Encontrei e para um ponto de corte usando duas abordagens diferentes: A) simulação e B) analiticamente .
Eu apreciaria se alguém pudesse me explicar como obter e para um ponto de corte . Obrigado.
A versão resumida da minha pergunta termina aqui. A partir de agora você encontrará:
- Na seção A), detalhes e código python completo da minha abordagem de simulação .
- Na seção B) detalhes e código python completo da abordagem analítica .
A) Minha abordagem de simulação com código python completo e explicações
(20 de dezembro de 2018)
Do livro ...
No mesmo espírito, o lema Neyman – Pearson fornece um algoritmo ideal de teste de hipóteses. Esta é talvez a mais elegante das construções freqüentistas. Em sua formulação mais simples, o lema NP assume que estamos tentando decidir entre duas funções possíveis de densidade de probabilidade para os dados observados , uma densidade de hipótese nula e uma densidade alternativa . Uma regra de teste diz qual escolha, ou , faremos tendo observado os dados . Qualquer regra desse tipo tem duas probabilidades de erro frequente associadas: escolher quando na verdade gerado e vice-versa,
Seja a razão de verossimilhança ,
(Fonte: Efron, B., & Hastie, T. (2016). Inferência estatística da era do computador: algoritmos, evidências e ciência de dados. Cambridge: Cambridge University Press. )
Então, eu implementei o código python abaixo ...
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))
Mais uma vez, a partir do livro ...
e defina a regra de teste por
(Fonte: Efron, B., & Hastie, T. (2016). Inferência estatística da era do computador: algoritmos, evidências e ciência de dados. Cambridge: Cambridge University Press. )
Então, eu implementei o código python abaixo ...
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
Finalmente, do livro ...
Onde é possível concluir que um ponto de corte implicará e .
Então, eu implementei o código python abaixo ...
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)
e o código ...
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_)
e o código ...
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-')
para obter algo parecido com isto:
que se parece com a figura original do livro, mas as três tuplas da minha simulação têm valores diferentes de e quando comparadas com as do livro para o mesmo ponto de corte . Por exemplo:
- do livro que temos
- da minha simulação, temos:
Parece que o ponto de corte da minha simulação é equivalente ao ponto de corte do livro.
Eu apreciaria se alguém pudesse me explicar o que estou fazendo de errado aqui. Obrigado.
B) Minha abordagem de cálculo com código python completo e explicações
(26 de dezembro de 2018)
Ainda tentando entender a diferença entre os resultados da minha simulação ( alpha_simulation(.), beta_simulation(.)
) e os apresentados no livro, com a ajuda de uma estatística (Sofia) minha amiga, calculamos e analiticamente em vez de via simulação, então ...
Uma vez que
então
Além disso,
tão,
Portanto, realizando algumas simplificações algébricas (como abaixo), teremos:
Então se
resulting in
In order to calculate and , we know that:
so,
For ...
so, I implemented the python code below:
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)
For ...
resulting in the python code below:
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)
and the 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_)
and the 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-')
to obtain a figure and values for and very similar to my first simulation
And finally to compare the results between simulation and calculation side by side ...
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
resulting in
This shows that the results of the simulation are very similar (if not the same) to those of the analytical approach.
In short, I still need help figuring out what might be wrong in my calculations. Thanks. :)