Por que numpy std () dá um resultado diferente para matlab std ()?


87

Tento converter o código matlab em numpy e descobri que numpy tem um resultado diferente com a função std.

em matlab

std([1,3,4,6])
ans =  2.0817

em entorpecido

np.std([1,3,4,6])
1.8027756377319946

Isso é normal? E como devo lidar com isso?

Respostas:


145

A função NumPy np.stdtem um parâmetro opcional ddof: "Delta Degrees of Freedom". Por padrão, é 0. Defina como para 1obter o resultado do MATLAB:

>>> np.std([1,3,4,6], ddof=1)
2.0816659994661326

Para adicionar um pouco mais de contexto, no cálculo da variância (da qual o desvio padrão é a raiz quadrada), normalmente dividimos pelo número de valores que temos.

Mas se selecionarmos uma amostra aleatória de Nelementos de uma distribuição maior e calcularmos a variância, a divisão por Npode levar a uma subestimação da variância real. Para corrigir isso, podemos diminuir o número que dividimos ( os graus de liberdade ) para um número menor que N(normalmente N-1). O ddofparâmetro nos permite alterar o divisor pelo valor que especificamos.

Salvo indicação em contrário, NumPy calculará o estimador enviesado para a variância ( ddof=0, dividindo por N). Isso é o que você deseja se estiver trabalhando com toda a distribuição (e não com um subconjunto de valores que foram escolhidos aleatoriamente em uma distribuição maior). Se o ddofparâmetro for fornecido, NumPy será dividido por N - ddof.

O comportamento padrão do MATLAB stdé corrigir o viés da variância da amostra dividindo por N-1. Isso elimina parte (mas provavelmente não toda) do viés no desvio padrão. É provável que seja isso que você deseja se estiver usando a função em uma amostra aleatória de uma distribuição maior.

A boa resposta de @hbaderts fornece mais detalhes matemáticos.


4
Vou adicionar isso no Matlab, std([1 3 4 6],1)é equivalente ao padrão do NumPy np.std([1,3,4,6]). Tudo isso é explicado claramente na documentação do Matlab e do NumPy, então eu recomendo fortemente que o OP leia-o no futuro.
Horchler

Em algum ponto, esse padrão mudou: np.std () = np.std (ddof = 1), embora a documentação diga que np.std () deve ser o padrão para ddof = 0 ...
ColinMac

61

O desvio padrão é a raiz quadrada da variância. A variância de uma variável aleatória Xé definida como

definição de variância

Um estimador para a variância seria, portanto,

estimador tendencioso

onde média da amostradenota a média da amostra. Para selecionados aleatoriamente XI, pode-se mostrar que este estimador não converge para a variância real, mas para

estimador imparcial

Se você selecionar amostras aleatoriamente e estimar a média e a variância da amostra, você terá que usar um estimador corrigido (imparcial)

estimador imparcial

que irá convergir para sigma ao quadrado. O termo de correção n-1também é chamado de correção de Bessel.

Agora, por padrão, o MATLABs stdcalcula o estimador imparcial com o termo de correção n-1. No entanto, NumPy (como @ajcr explicado) calcula o estimador tendencioso sem termo de correção por padrão. O parâmetro ddofpermite definir qualquer termo de correção n-ddof. Definindo para 1, você obtém o mesmo resultado do MATLAB.

Da mesma forma, o MATLAB permite adicionar um segundo parâmetro w, que especifica o "esquema de pesagem". O default,, w=0resulta no termo de correção n-1(estimador enviesado), enquanto para w=1, apenas n é usado como termo de correção (estimador enviesado).


2
Na fórmula do estimador corrigido, o fator n (dentro da soma) não deve estar presente.
Frunobulax de

3
A intuição por trás do termo n-1 na variância: você já usou suas amostras para estimar a média que usará para aproximar a variância. Isso introduz uma correlação e, portanto, ddof deve ser 1.
Matthias

@Frunobulax Corrigi o erro de digitação para a posteridade. O que aconteceu na equação original foi que o limite superior da soma não estava sendo renderizado corretamente. Em vez de nir para o topo da notação de soma, ele ia dentro da soma.
rayryeng de

4

Para pessoas que não são boas com estatísticas, um guia simplista é:

  • Incluir ddof=1se estiver calculando np.std()para uma amostra retirada de seu conjunto de dados completo.

  • Certifique- ddof=0se de que você está calculando np.std()para toda a população

O DDOF é incluído para amostras a fim de contrabalançar o viés que pode ocorrer nos números.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.