Bagaimana cara mensimulasikan data buatan untuk regresi logistik?

45

Saya tahu saya kehilangan sesuatu dalam pemahaman saya tentang regresi logistik, dan akan sangat menghargai bantuan apa pun.

Sejauh yang saya mengerti, regresi logistik mengasumsikan bahwa probabilitas hasil '1' diberikan input, adalah kombinasi linear dari input, melewati fungsi invers-logistik. Ini dicontohkan dalam kode R berikut:

#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")

dan saya mendapatkan pesan kesalahan berikut:

Pesan peringatan: 1: glm.fit: algoritma tidak konvergen 2: glm.fit: probabilitas dipasang secara numerik 0 atau 1 terjadi

Saya telah bekerja dengan R untuk beberapa waktu sekarang; cukup untuk mengetahui bahwa mungkin saya yang harus disalahkan .. apa yang terjadi di sini?

zorbar
sumber
2
Cara Anda mensimulasikan data Anda terlihat aneh bagi saya. Jika Anda mau, untuk alternatif cara yang lebih standar, Anda dapat melihatnya di sini: stats.stackexchange.com/questions/12857/…
ocram
@ocram: Anda benar; ini pertanyaan rangkap!
user603
2
Saya memang menjalankan simulasi yang salah, seperti yang dijelaskan oleh @ Stéphane Laurent. Namun, masalahnya adalah pemisahan yang sempurna dalam regresi logistik , masalah yang tidak saya kenal, dan saya agak terkejut mengetahui hal itu.
zorbar
@zorbar: itu dalam tanggapan saya terhadap pertanyaan Anda (sekarang dihapus).
user603
1
@ user603: Saya mungkin melewatkan respons Anda; Terima kasih
zorbar

Jawaban:

63

Tidak. Variabel respons adalah variabel acak Bernoulli yang mengambil nilai dengan probabilitas . 1 p r ( i )ysaya1halr(saya)

> 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
sumber
Anda benar - saya melewatkan langkah ini. terima kasih banyak atas bantuan anda!
zorbar
1
Saya punya pertanyaan tentang cara Anda mensimulasikan data. Ketika kami mensimulasikan data untuk regresi linier, kami juga mensimulasikan noise (\ epsilon). Saya mengerti bahwa fungsi logistik adalah fungsi dari harapan yang dengan sendirinya membatalkan kebisingan. Apakah itu alasan mengapa Anda tidak memiliki noise di z Anda?
Sam
5
@Sepehr Regresi linier mengasumsikan distribusi Gaussian. "Noise" hanyalah sebuah interpretasi dari variabilitas di sekitar mean, tetapi ini bukan noise yang ditambahkan ke respons: respons ditulis sebagai , ini hanya interpretasi. Regresi logistik mengasumsikan respons memiliki distribusi binomial, dan sama juga tidak ada noise yang ditambahkan ke respons. respon berarti+kebisingan
Stéphane Laurent
@ StéphaneLaurent, tepatnya. Saya benar-benar mengerti. Terima kasih banyak atas jawaban Anda.
Sam
2

LogisticRegression cocok untuk penyesuaian jika probabilitas atau proporsi disediakan sebagai target, bukan hanya hasil 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='.')

Di sini kita memiliki tiga target potensial untuk regresi logistik. pyang merupakan proporsi sebenarnya / target / probabilitas, pnoisyyang p dengan noise normal ditambahkan dalam skala log odds, dan dichot, yang pnoisy diperlakukan sebagai parameter ke file binomial PDF, dan disampel dari situ. Anda harus menguji semua 3 - Saya menemukan beberapa implementasi LR open source tidak cocok p.

Bergantung pada aplikasi Anda, Anda dapat memilih pnoisy.

Dalam praktiknya, Anda juga harus mempertimbangkan bagaimana suara itu kemungkinan akan dibentuk dalam aplikasi target Anda dan mencoba untuk menirunya.

pengguna48956
sumber