Calcule um intervalo de confiança de dados de amostra

109

Tenho dados de amostra para os quais gostaria de calcular um intervalo de confiança, assumindo uma distribuição normal.

Eu encontrei e instalei os pacotes numpy e scipy e consegui que o numpy retornasse uma média e um desvio padrão (numpy.mean (dados) com os dados sendo uma lista). Qualquer conselho sobre como obter um intervalo de confiança de amostra seria muito apreciado.

Bmayer0122
fonte
1
Acho que você especifica se deseja calcular o IC para a média da amostra ou a média da população. Isso determinaria se você deseja usar a distribuição normal ou t para calcular o z-score. E a primeira resposta abaixo é para a média da amostra, então a distribuição é usada.
Jake de

Respostas:

162
import numpy as np
import scipy.stats


def mean_confidence_interval(data, confidence=0.95):
    a = 1.0 * np.array(data)
    n = len(a)
    m, se = np.mean(a), scipy.stats.sem(a)
    h = se * scipy.stats.t.ppf((1 + confidence) / 2., n-1)
    return m, m-h, m+h

você pode calcular assim.

Shasan
fonte
1
sp.stats.stderr está obsoleto. Substituí sp.stats.sem e funcionou muito bem!
Bmayer0122
1
A importação scipynão importa necessariamente todos os subpacotes automaticamente. Melhor importar o subpacote scipy.statsexplicitamente.
Vikram
31
Cuidado com o uso "privado" de sp.stats.t._ppf. Não estou confortável com isso sem maiores explicações. Melhor usar sp.stats.t.ppfdiretamente, a menos que você tenha certeza de que sabe o que está fazendo. Em uma rápida inspeção da fonte , uma boa quantidade de código foi ignorada _ppf. Possivelmente benigno, mas também possivelmente uma tentativa de otimização insegura?
Russ,
Eu gosto porque você pode simplesmente adicionar *ss.t._ppf((1+conf)/2.,n-1) o .semmétodo de dataframe integrado do pandas para que você não precise se preocuparapply
TNT,
1
Só quero esclarecer que este cálculo é para a média da amostra, então a distribuição é usada. Se a questão é calcular a média da população, uma distribuição normal deve ser usada e o intervalo de confiança será menor para o mesmo nível de confiança.
Jake
133

Aqui está uma versão abreviada do código de shasan, calculando o intervalo de confiança de 95% da média da matriz a:

import numpy as np, scipy.stats as st

st.t.interval(0.95, len(a)-1, loc=np.mean(a), scale=st.sem(a))

Mas usar StatsModels tconfint_meané indiscutivelmente ainda melhor:

import statsmodels.stats.api as sms

sms.DescrStatsW(a).tconfint_mean()

As suposições subjacentes para ambos são que a amostra (matriz a) foi desenhada independentemente de uma distribuição normal com desvio padrão desconhecido (consulte MathWorld ou Wikipedia ).

Para tamanho de amostra grande n, a média da amostra é normalmente distribuída, e pode-se calcular seu intervalo de confiança usando st.norm.interval()(como sugerido no comentário de Jaime). Mas as soluções acima também estão corretas para n pequeno, onde st.norm.interval()fornece intervalos de confiança muito estreitos (ou seja, "confiança falsa"). Veja minha resposta a uma pergunta semelhante para obter mais detalhes (e um dos comentários de Russ aqui).

Aqui está um exemplo em que as opções corretas fornecem (essencialmente) intervalos de confiança idênticos:

In [9]: a = range(10,14)

In [10]: mean_confidence_interval(a)
Out[10]: (11.5, 9.4457397432391215, 13.554260256760879)

In [11]: st.t.interval(0.95, len(a)-1, loc=np.mean(a), scale=st.sem(a))
Out[11]: (9.4457397432391215, 13.554260256760879)

In [12]: sms.DescrStatsW(a).tconfint_mean()
Out[12]: (9.4457397432391197, 13.55426025676088)

E, finalmente, o resultado incorreto usando st.norm.interval():

In [13]: st.norm.interval(0.95, loc=np.mean(a), scale=st.sem(a))
Out[13]: (10.23484868811834, 12.76515131188166)
Ulrich Stern
fonte
1
Acredito que você deva ligar st.t.interval(0.05)para obter o intervalo de confiança de 95%.
Scimonster
5
Não, st.t.interval(0.95)está correto para o intervalo de confiança de 95%, consulte a documentação para scipy.stats.t. Porém, SciPy nomear o argumento alphaparece menos do que ideal.
Ulrich Stern
Se eu tiver duas matrizes de dados e depois calcular a diferença de sua média. Existe alguma maneira de obter um IC de 95% para essa diferença média? Você poderia pensar em alguma maneira fácil de fazer isso como a fornecida aqui usando StatsModelsl?
steven
@steven, descobri, respondi a uma pergunta sobre isso. :)
Ulrich Stern
16

Comece procurando o valor z para o intervalo de confiança desejado em uma tabela de consulta . O intervalo de confiança é então mean +/- z*sigma, onde sigmaé o desvio padrão estimado da média da amostra, dado por sigma = s / sqrt(n), onde sé o desvio padrão calculado a partir dos dados da amostra e né o tamanho da amostra.

bogatron
fonte
29
scipy.stats.norm.interval(confidence, loc=mean, scale=sigma)
Jaime de
4
O autor da pergunta original indicou que uma distribuição normal deveria ser assumida, mas vale a pena apontar que, para pequenas populações de amostra (N <100 ou mais), é melhor procurar z na distribuição t de Student em vez de na distribuição normal . a resposta de shasan já faz isso.
Russ,
3
@bogatron, sobre o cálculo sugerido para o intervalo de confiança, não seria a média +/- z * sigma / sqrt (n) , onde n é o tamanho da amostra?
David
3
@David, você está correto. Eu exprimi o significado de sigma. sigmaem minha resposta deve estar o desvio padrão estimado da média da amostra, não o desvio padrão estimado da distribuição. Eu atualizei a resposta para esclarecer isso. Obrigado por apontar isso.
bogatron de
15

Começando Python 3.8, a biblioteca padrão fornece o NormalDistobjeto como parte do statisticsmódulo:

from statistics import NormalDist

def confidence_interval(data, confidence=0.95):
  dist = NormalDist.from_samples(data)
  z = NormalDist().inv_cdf((1 + confidence) / 2.)
  h = dist.stdev * z / ((len(data) - 1) ** .5)
  return dist.mean - h, dist.mean + h

Este:

  • Cria um NormalDistobjeto a partir da amostra de dados ( NormalDist.from_samples(data), que nos dá acesso à média e ao desvio padrão da amostra por meio de NormalDist.meane NormalDist.stdev.

  • Calcule com Z-scorebase na distribuição normal padrão (representada por NormalDist()) para a confiança fornecida usando o inverso da função de distribuição cumulativa ( inv_cdf).

  • Produz o intervalo de confiança com base no desvio padrão e na média da amostra.


Isso assume que o tamanho da amostra é grande o suficiente (digamos mais de ~ 100 pontos) para usar a distribuição normal padrão em vez da distribuição t do aluno para calcular o zvalor.

Xavier Guihot
fonte