R语言统计系列第11篇-Logistic回归

今天是各类统计方法R语言实现的第11期,我们主要介绍Logistic回归。Logistic回归属于广义线性回归,因此我们从广义线性回归讲起。

广义线性回归

线性回归模型要求因变量服从正态分布,但是当结果变量是分类型(有无,患病与否等,二分类常用Logistic回归)、计数型(某地区某年发生肿瘤患者的人数等,常用泊松回归)或者临床上经常使用的无复发生存期数据等(常用Cox回归),因变量不符合正态分布,无法直接使用线性回归。而广义线性模型扩展了线性模型的框架,可以进行非正态因变量的分析,在R语言中可以通过glm()函数实现。

glm()函数的参数

分布族 默认的连接函数
binomial (link = “logit”)
gaussian (link = “identity”)
gamma (link = “inverse”)
inverse.gaussian (link = “1/mu^2”)
poisson (link = “log”)
quasi (link = “identity”, variance = “constant”)
quasibinomial (link = “logit”)
quasipoisson (link = “log”)

连用的函数

函数 描述
summary() 展示拟合模型的细节
coefficients(), coef() 列出拟合模型的参数(截距项和斜率)
confint() 给出模型参数的置信区间(默认为95%)
residuals() 列出拟合模型的残差值
anova() 生成两个拟合模型的方差分析表
plot() 生成评价拟合模型的诊断图
predict() 用拟合模型对新数据集进行预测

Logistic回归

二分类因变量常用Logistic回归,假设因变量Y服从二项分布,查表得(link = “logit”)

此处是一份婚外情数据,我们用性别、年龄等因素预测参与者是否发生婚外情affairs。

# 载入数据
data(Affairs, package = "AER")
summary(Affairs)
##     affairs          gender         age         yearsmarried    children 
##  Min.   : 0.000   female:315   Min.   :17.50   Min.   : 0.125   no :171  
##  1st Qu.: 0.000   male  :286   1st Qu.:27.00   1st Qu.: 4.000   yes:430  
##  Median : 0.000                Median :32.00   Median : 7.000            
##  Mean   : 1.456                Mean   :32.49   Mean   : 8.178            
##  3rd Qu.: 0.000                3rd Qu.:37.00   3rd Qu.:15.000            
##  Max.   :12.000                Max.   :57.00   Max.   :15.000            
##  religiousness     education       occupation        rating     
##  Min.   :1.000   Min.   : 9.00   Min.   :1.000   Min.   :1.000  
##  1st Qu.:2.000   1st Qu.:14.00   1st Qu.:3.000   1st Qu.:3.000  
##  Median :3.000   Median :16.00   Median :5.000   Median :4.000  
##  Mean   :3.116   Mean   :16.17   Mean   :4.195   Mean   :3.932  
##  3rd Qu.:4.000   3rd Qu.:18.00   3rd Qu.:6.000   3rd Qu.:5.000  
##  Max.   :5.000   Max.   :20.00   Max.   :7.000   Max.   :5.000
table(Affairs$affairs)
## 
##   0   1   2   3   7  12 
## 451  34  17  19  42  38
# 创建二分类因变量,1表示发生婚外情,0表示不发生婚外情
Affairs$ynaffair[Affairs$affairs > 0] <- 1
Affairs$ynaffair[Affairs$affairs == 0] <- 0
Affairs$ynaffair <- factor(Affairs$ynaffair, levels = c(0, 1), labels = c("No", "Yes"))
table(Affairs$ynaffair)
## 
##  No Yes 
## 451 150
# 拟合模型(link = “logit”) 
fit.full <- glm(ynaffair ~ gender + age + yearsmarried + children + religiousness +
                  education + occupation + rating, data = Affairs, family = binomial())
summary(fit.full)
## 
## Call:
## glm(formula = ynaffair ~ gender + age + yearsmarried + children + 
##     religiousness + education + occupation + rating, family = binomial(), 
##     data = Affairs)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -1.5713  -0.7499  -0.5690  -0.2539   2.5191  
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)    1.37726    0.88776   1.551 0.120807    
## gendermale     0.28029    0.23909   1.172 0.241083    
## age           -0.04426    0.01825  -2.425 0.015301 *  
## yearsmarried   0.09477    0.03221   2.942 0.003262 ** 
## childrenyes    0.39767    0.29151   1.364 0.172508    
## religiousness -0.32472    0.08975  -3.618 0.000297 ***
## education      0.02105    0.05051   0.417 0.676851    
## occupation     0.03092    0.07178   0.431 0.666630    
## rating        -0.46845    0.09091  -5.153 2.56e-07 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 675.38  on 600  degrees of freedom
## Residual deviance: 609.51  on 592  degrees of freedom
## AIC: 627.51
## 
## Number of Fisher Scoring iterations: 4

从结果中,我们发现性别gendermale、是否有孩子childrenyes、教育水平education和职业occupation对于模型贡献不显著,因此去除这些变量重新拟合模型。

# 重新拟合模型
fit.reduced <- glm(ynaffair ~ age + yearsmarried + religiousness + rating, data = Affairs, family = binomial())
summary(fit.reduced)
## 
## Call:
## glm(formula = ynaffair ~ age + yearsmarried + religiousness + 
##     rating, family = binomial(), data = Affairs)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -1.6278  -0.7550  -0.5701  -0.2624   2.3998  
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)    1.93083    0.61032   3.164 0.001558 ** 
## age           -0.03527    0.01736  -2.032 0.042127 *  
## yearsmarried   0.10062    0.02921   3.445 0.000571 ***
## religiousness -0.32902    0.08945  -3.678 0.000235 ***
## rating        -0.46136    0.08884  -5.193 2.06e-07 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 675.38  on 600  degrees of freedom
## Residual deviance: 615.36  on 596  degrees of freedom
## AIC: 625.36
## 
## Number of Fisher Scoring iterations: 4

此时,每一个变量对模型贡献都非常显著,我们可以使用卡方检验比较两个模型。

# 比较模型
anova(fit.reduced, fit.full, test = "Chisq")
## Analysis of Deviance Table
## 
## Model 1: ynaffair ~ age + yearsmarried + religiousness + rating
## Model 2: ynaffair ~ gender + age + yearsmarried + children + religiousness + 
##     education + occupation + rating
##   Resid. Df Resid. Dev Df Deviance Pr(>Chi)
## 1       596     615.36                     
## 2       592     609.51  4   5.8474   0.2108

发现最终p=0.21,表明两个模型没有显著差异,因此用age + yearsmarried + religiousness + rating四个变量就能很好地预测是否发生婚外情。

# 输出回归系数,解释回归系数
coef(fit.reduced)
##   (Intercept)           age  yearsmarried religiousness        rating 
##    1.93083017   -0.03527112    0.10062274   -0.32902386   -0.46136144
exp(coef(fit.reduced))
##   (Intercept)           age  yearsmarried religiousness        rating 
##     6.8952321     0.9653437     1.1058594     0.7196258     0.6304248
#置信区间
exp (confint(fit.reduced))
## Waiting for profiling to be done...
##                   2.5 %     97.5 %
## (Intercept)   2.1255764 23.3506030
## age           0.9323342  0.9981470
## yearsmarried  1.0448584  1.1718250
## religiousness 0.6026782  0.8562807
## rating        0.5286586  0.7493370

回归系数可用coef()获取,exp(回归系数)可以求得自变量引起因变量变化的优势比OR,对于发病率较低的慢性疾病,OR可作为相对危险度RR的估计。

OR=1,自变量X对于应变量发生与否不起作用,OR>1是一个危险因素,OR<1是一个保护因素。(当1表示发生,0表示不发生的情况)

此处结婚年龄yearsmarried是发生婚外情的危险因素,age、religiousness、rating是保护因素。

评价预测变量对结果概率的影响

我们可以假定其他因素不变,仅改变其中一个变量,从而评价这个变量对于结果概率的影响。

# 评价婚姻评分rating 
testdata <- data.frame(rating = c(1, 2, 3, 4, 5),  age = mean(Affairs$age), yearsmarried = mean(Affairs$yearsmarried),  religiousness = mean(Affairs$religiousness))
testdata$prob <- predict(fit.reduced, newdata = testdata, type = "response") 
testdata
##   rating      age yearsmarried religiousness      prob
## 1      1 32.48752     8.177696      3.116473 0.5302296
## 2      2 32.48752     8.177696      3.116473 0.4157377
## 3      3 32.48752     8.177696      3.116473 0.3096712
## 4      4 32.48752     8.177696      3.116473 0.2204547
## 5      5 32.48752     8.177696      3.116473 0.1513079

婚姻评分从1到5,婚外情概率从0.53降到0.15

# 评价年龄age
testdata <- data.frame(rating = mean(Affairs$rating), age = seq(17, 57, 10), yearsmarried = mean(Affairs$yearsmarried), religiousness = mean(Affairs$religiousness))
testdata$prob <- predict(fit.reduced, newdata = testdata,  type = "response")
testdata
##    rating age yearsmarried religiousness      prob
## 1 3.93178  17     8.177696      3.116473 0.3350834
## 2 3.93178  27     8.177696      3.116473 0.2615373
## 3 3.93178  37     8.177696      3.116473 0.1992953
## 4 3.93178  47     8.177696      3.116473 0.1488796
## 5 3.93178  57     8.177696      3.116473 0.1094738

年龄从17到57,婚外情概率从0.34降到0.11

过度离势

过度离势是指观测到的响应变量的方差大于期望的二项分布的方差,过度离势会导致奇异的标准误检验和不精确的显著性检验。

deviance(fit.reduced)/df.residual(fit.reduced)
## [1] 1.03248

结果非常接近1,表示没有过度离势。

fit <- glm(ynaffair ~ age + yearsmarried + religiousness +  rating, family = binomial(), data = Affairs)
fit.od <- glm(ynaffair ~ age + yearsmarried + religiousness +  rating, family = quasibinomial(), data = Affairs)
pchisq(summary(fit.od)$dispersion * fit$df.residual, fit$df.residual, lower = F)
## [1] 0.340122

p=0.34,二者之间没有显著差异,表明没有过度离势。

如果存在过度离势,可使用类二项分布 family = quasibinomial()。

条件logistic回归

使用survival包中的clogit(),用于分析配对数据

library(survival)
## Warning: package 'survival' was built under R version 3.6.3
data(logan)
summary(logan)
##         occupation            focc       education            race    
##  farm        : 19   farm        : 92   Min.   : 2.00   non-black:764  
##  operatives  :217   operatives  :235   1st Qu.:12.00   black    : 74  
##  craftsmen   :202   craftsmen   :232   Median :13.00                  
##  sales       :105   sales       : 82   Mean   :13.58                  
##  professional:295   professional:197   3rd Qu.:16.00                  
##                                        Max.   :20.00
#整理数据
resp <- levels(logan$occupation)
n <- nrow(logan)
indx <- rep(1:n, length(resp))
logan2 <- data.frame(logan[indx,],
                     id = indx,
                     tocc = factor(rep(resp, each=n)))
logan2$case <- (logan2$occupation == logan2$tocc)

# strata(id)表示配对样本的编号,其余与之前一致,不过此处分析了交互作用
model <-clogit(case ~ tocc + tocc:education + strata(id), logan2)

summary(model)
## Call:
## coxph(formula = Surv(rep(1, 4190L), case) ~ tocc + tocc:education + 
##     strata(id), data = logan2, method = "exact")
## 
##   n= 4190, number of events= 838 
## 
##                                  coef  exp(coef)   se(coef)       z Pr(>|z|)
## toccfarm                   -1.8964629  0.1500986  1.3807822  -1.373  0.16961
## toccoperatives              1.1667502  3.2115388  0.5656465   2.063  0.03914
## toccprofessional           -8.1005492  0.0003034  0.6987244 -11.593  < 2e-16
## toccsales                  -5.0292297  0.0065438  0.7700862  -6.531 6.54e-11
## tocccraftsmen:education    -0.3322842  0.7172835  0.0568682  -5.843 5.13e-09
## toccfarm:education         -0.3702858  0.6905370  0.1164100  -3.181  0.00147
## toccoperatives:education   -0.4222188  0.6555906  0.0584328  -7.226 4.98e-13
## toccprofessional:education  0.2782469  1.3208122  0.0510212   5.454 4.94e-08
## toccsales:education                NA         NA  0.0000000      NA       NA
##                               
## toccfarm                      
## toccoperatives             *  
## toccprofessional           ***
## toccsales                  ***
## tocccraftsmen:education    ***
## toccfarm:education         ** 
## toccoperatives:education   ***
## toccprofessional:education ***
## toccsales:education           
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
##                            exp(coef) exp(-coef) lower .95 upper .95
## toccfarm                   0.1500986     6.6623 1.002e-02  2.247505
## toccoperatives             3.2115388     0.3114 1.060e+00  9.731781
## toccprofessional           0.0003034  3296.2778 7.713e-05  0.001193
## toccsales                  0.0065438   152.8152 1.447e-03  0.029603
## tocccraftsmen:education    0.7172835     1.3941 6.416e-01  0.801857
## toccfarm:education         0.6905370     1.4481 5.497e-01  0.867512
## toccoperatives:education   0.6555906     1.5253 5.846e-01  0.735141
## toccprofessional:education 1.3208122     0.7571 1.195e+00  1.459723
## toccsales:education               NA         NA        NA        NA
## 
## Concordance= 0.766  (se = 0.012 )
## Likelihood ratio test= 665.5  on 8 df,   p=<2e-16
## Wald test            = 413.5  on 8 df,   p=<2e-16
## Score (logrank) test = 682.1  on 8 df,   p=<2e-16

另外,有时我们还需要分析交互作用,使用逐步回归法step()等,之前推文均已讲过,此处不再赘述。

还要注意年龄等连续变量每增加一个变量对于二分类结果影响不大,经常会分组为有序多分类变量。有序多分类变量按照各个分类与因变量是否线性变化决定是否哑变量化。无序多分类自变量需要哑变量化。R中使用factor函数即可实现哑变量化。

好了,今天的R语言实现统计方法系列推文暂时告一段落,我们下次再见吧! 小伙伴们如果有什么统计上的问题,或者如果想要学习什么方面的生物信息内容,可以在微信群或者知识星球提问,没准哪天的推文就是专门解答你的问题哦!

©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350