Come simulare i dati artificiali per la regressione logistica?


45

So che mi manca qualcosa nella mia comprensione della regressione logistica e apprezzerei molto qualsiasi aiuto.

Per quanto ho capito, la regressione logistica presuppone che la probabilità di un risultato "1" dato gli input, sia una combinazione lineare degli input, passata attraverso una funzione inversa-logistica. Questo è esemplificato nel seguente codice 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")

e ricevo il seguente messaggio di errore:

Messaggi di avviso: 1: glm.fit: l'algoritmo non converge 2: glm.fit: probabilità adattate numericamente 0 o 1 verificatesi

Ho lavorato con R per qualche tempo; abbastanza per sapere che probabilmente sono io la colpa .. cosa sta succedendo qui?


2
Il modo in cui simuli i tuoi dati mi sembra strano. Se vuoi, per un modo alternativo più standard, puoi dare un'occhiata qui: stats.stackexchange.com/questions/12857/…
ocram,

@ocram: hai ragione; questa è una domanda duplicata!
user603

2
Ho eseguito una simulazione errata, come ha spiegato @ Stéphane Laurent. Tuttavia, il problema era la perfetta separazione nella regressione logistica , un problema che non conoscevo e che ero piuttosto sorpreso di apprendere.
Zorbar,

@zorbar: era nella mia risposta alla tua domanda (ora cancellata).
user603,

1
@ user603: probabilmente ho perso la tua risposta; Grazie comunque
Zorbar il

Risposte:


63

No. La variabile di risposta è una variabile casuale di Bernoulli che assume valore con probabilità . 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 

Hai ragione - ho perso questo passaggio. Grazie mille per il vostro aiuto!
Zorbar,

1
Ho avuto una domanda sul modo in cui simuli i dati. Quando simuliamo i dati per la regressione lineare, simuliamo anche un rumore (\ epsilon). Capisco che la funzione logistica è una funzione dell'aspettativa che da sola annulla il rumore. È questo il motivo per cui non hai alcun rumore nella tua z?
Sam,

5
La regressione lineare di @Sepehr assume una distribuzione gaussiana. Il "rumore" è solo un'interpretazione della variabilità attorno alla media, ma questo non è un rumore aggiunto alla risposta: la risposta è scritta come , questa è solo un'interpretazione. La regressione logistica presuppone che la risposta abbia una distribuzione binomiale e allo stesso modo non viene aggiunto alcun rumore alla risposta. mean response+noise
Stéphane Laurent,

@ StéphaneLaurent, esattamente. Ho completamente capito. Grazie mille per la tua risposta.
Sam,

2

LogisticRegression è adatto per l'adattamento se le probabilità o le proporzioni sono fornite come obiettivi, non solo risultati 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='.')

Qui abbiamo tre potenziali obiettivi per la regressione logistica. pche è la proporzione / probabilità vera / target, pnoisyche è p con il rumore normale aggiunto nella scala delle probabilità del log e dichotche è considerato come un parametro nel PDF binomiale, e campionato da quello. Dovresti testare tutti e 3: ho trovato che alcune implementazioni LR open source non sono adatte p.

A seconda della tua applicazione, potresti preferire la pnoisy.

In pratica, dovresti anche considerare come è probabile che il rumore si modifichi nell'applicazione di destinazione e provare ad emularlo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.