Como lidar adequadamente com Infs em uma função estatística?

8

Suponha que eu tenha uma função como:

f <- function(x){
  exp(x) / (1 + exp(x))
}

ele deve funcionar com qualquer valor real de x, mas na verdade ele retorna NaN quando x é 710 ou maior. Gostaria de saber qual é a maneira correta de lidar com esse problema. Sei que é fácil fazê-lo retornar apenas 1, mas talvez não seja um bom comportamento do ponto de vista estatístico. Alguém tem algum comentário ou sugestão?

David Z
fonte
Não sei se eu poderia confiar em estimativas de parâmetros baseadas em modelo com valores tão altos de influência na função. Você pode esperar que seus algoritmos padrão de Newton-Raphson forneçam estimativas absurdas de parâmetros com valores de como um preditor linear em modelos de regressão logística. As proporções de probabilidades podem ser relatadas como valor infinito. Além disso, acredito que você pode inverter o teste de pontuação para obter um intervalo de confiança válido para o odds ratio. x
Adamo
exp(x)/(1+exp(x))x1exp(x)

Respostas:

11

Nesse caso, o NaN(não é um número) é retornado porque o cálculo do exponencial transborda em aritmética de precisão dupla.

0

exp(x)1+exp(x)=11+exp(x)=1exp(x)+exp(2x).

x>710exp(710)1030821024 1

Curiosamente, Rnão produzirá um NaNquando o exponencial for insuficiente . Assim, você pode escolher a versão mais confiável do cálculo, dependendo do sinal de x, como em

f <- function(x) ifelse(x < 0, exp(x) / (1 + exp(x)), 1 / (1 + exp(-x)))

Esse problema aparece em quase todas as plataformas de computação (ainda não vi uma exceção) e elas variam na maneira como lidam com estouros e subfluxos. Os exponenciais são notórios por criar esses tipos de problemas, mas não estão sozinhos. Portanto, não basta apenas ter uma solução R: um bom estatístico entende os princípios da aritmética computacional e sabe como usá-los para detectar e solucionar as idiossincrasias de seu ambiente de computação.

whuber
fonte
1
x<361+exp(x)1x>361+exp(x)exp(x)1|x|>710
whuber
1

Outros já discutiram as questões computacionais, então deixarei isso para eles. Como suponho que você esteja trabalhando com R, pensei em apontar que o pacote de inicialização vem com sua própria função de logit inversa para você usar, que é bastante computacionalmente estável:

require(boot) inv.logit(710)

parece avaliar para 1 como desejado.

Samuel Benidt
fonte
1
Ou, se você deseja evitar a introdução de uma dependência de pacote, plogis(710)obtém o mesmo resultado. (De fato, inv.logité apenas um pseudônimo para plogis.) #
1155