¿Cómo simular datos artificiales para la regresión logística?

45

Sé que me falta algo en mi comprensión de la regresión logística, y realmente agradecería cualquier ayuda.

Hasta donde yo entiendo, la regresión logística supone que la probabilidad de un resultado '1' dadas las entradas, es una combinación lineal de las entradas, pasadas a través de una función de logística inversa. Esto se ejemplifica en el siguiente código R:

#create data:
x1 = rnorm(1000)           # some continuous variables 
x2 = rnorm(1000)
z = 1 + 2*x1 + 3*x2        # linear combination with a bias
pr = 1/(1+exp(-z))         # pass through an inv-logit function
y = pr > 0.5               # take as '1' if probability > 0.5

#now feed it to glm:
df = data.frame(y=y,x1=x1,x2=x2)
glm =glm( y~x1+x2,data=df,family="binomial")

y recibo el siguiente mensaje de error:

Mensajes de advertencia: 1: glm.fit: el algoritmo no convergió 2: glm.fit: las probabilidades ajustadas numéricamente 0 o 1 ocurrieron

He trabajado con R por algún tiempo; suficiente para saber que probablemente yo sea el culpable ... ¿qué está pasando aquí?

zorbar
fuente
2
La forma en que simula sus datos me parece extraña. Si lo desea, para una forma alternativa más estándar, puede echar un vistazo aquí: stats.stackexchange.com/questions/12857/…
ocram
@ocram: tienes razón; esta es una pregunta duplicada!
usuario603
2
Realicé una simulación errónea, como explicó @ Stéphane Laurent. Sin embargo, el problema era la separación perfecta en la regresión logística , un problema con el que no estaba familiarizado y que me sorprendió bastante conocer.
zorbar
@zorbar: fue en mi respuesta a su pregunta (ahora eliminada).
user603
1
@ usuario603: Probablemente perdí tu respuesta; Gracias de todos modos
zorbar

Respuestas:

63

No. La variable de respuesta es una variable aleatoria de Bernoulli que toma el valor con probabilidad . 1 p r ( i )yi1pr(i)

> set.seed(666)
> x1 = rnorm(1000)           # some continuous variables 
> x2 = rnorm(1000)
> z = 1 + 2*x1 + 3*x2        # linear combination with a bias
> pr = 1/(1+exp(-z))         # pass through an inv-logit function
> y = rbinom(1000,1,pr)      # bernoulli response variable
> 
> #now feed it to glm:
> df = data.frame(y=y,x1=x1,x2=x2)
> glm( y~x1+x2,data=df,family="binomial")

Call:  glm(formula = y ~ x1 + x2, family = "binomial", data = df)

Coefficients:
(Intercept)           x1           x2  
     0.9915       2.2731       3.1853  

Degrees of Freedom: 999 Total (i.e. Null);  997 Residual
Null Deviance:      1355 
Residual Deviance: 582.9        AIC: 588.9 
Stéphane Laurent
fuente
Tienes razón, he perdido este paso. ¡muchas gracias por tu ayuda!
zorbar
1
Tenía una pregunta sobre la forma en que simula datos. Cuando simulamos datos para regresión lineal, también simulamos un ruido (\ epsilon). Entiendo que la función logística es una función de la expectativa que por sí sola cancela el ruido. ¿Es esa la razón por la que no tienes ningún ruido en tu z?
Sam
55
@Sepehr La regresión lineal supone una distribución gaussiana. El "ruido" es solo una interpretación de la variabilidad alrededor de la media, pero esto no es un ruido agregado a la respuesta: la respuesta se escribe como , esto es solo una interpretación. La regresión logística supone que la respuesta tiene una distribución binomial y, de manera similar, no se agrega ruido a la respuesta. mean response+noise
Stéphane Laurent
@ StéphaneLaurent, exactamente. Lo entiendo completamente. Muchas gracias por tu respuesta.
Sam
2

LogisticRegression es adecuado para el ajuste si se proporcionan probabilidades o proporciones como objetivos, no solo resultados 0/1.

import numpy as np
import pandas as pd
def logistic(x, b, noise=None):
    L = x.T.dot(b)
    if noise is not None:
        L = L+noise
    return 1/(1+np.exp(-L))

x = np.arange(-10., 10, 0.05)
bias = np.ones(len(x))
X = np.vstack([x,bias]) # Add intercept
B =  [1., 1.] # Sigmoid params for X

# True mean
p = logistic(X, B)
# Noisy mean
pnoisy = logistic(X, B, noise=np.random.normal(loc=0., scale=1., size=len(x)))
# dichotomize pnoisy -- sample 0/1 with probability pnoisy
dichot = np.random.binomial(1., pnoisy)

pd.Series(p, index=x).plot(style='-')
pd.Series(pnoisy, index=x).plot(style='.')
pd.Series(dichot, index=x).plot(style='.')

Aquí tenemos tres objetivos potenciales para la regresión logística. pcuál es la proporción / probabilidad real / objetivo, pnoisyque es p con ruido normal agregado en la escala de probabilidades de registro, y dichotque es molesto tratado como un parámetro para el PDF binomial, y muestreado a partir de eso. Debería probar los 3: descubrí que algunas implementaciones de LR de código abierto no pueden caber p.

Dependiendo de su aplicación, es posible que prefiera molesto.

En la práctica, también debe considerar cómo es probable que se forme el ruido en su aplicación de destino e intentar emularlo.

usuario48956
fuente