标签(空格分隔): R语言 广义线性模型 logistic回归 泊松回归
我们知道,OLS回归的要求是假设因变量是正态分布(还有独立性、线性及同方差性),但是,我们在使用时,因变量通常会出现二值变量(如是/否、通过/不通过之类)或多分类变量(如优/良/中/差等),又或者为计数变量(如一周的交通事故次数这类非负有限值)。而广义线性回归就是能够解决此类问题的回归。书中只介绍了Logistic回归及泊松回归两个回归的一般方法(像稳健、多项、有序等并未涉及)。
OLS回归的函数式为: μY=β0+∑pj=1βjXj ,其中Y呈正态分布, μY 为Y的均值
广义线性的函数式为: g(μY)=β0+∑pj=1βjXj ,其中 g(μY) 是条件均值的函数(称为连接函数)
同OLS回归,广义线性的使用也是由一个函数统领,为glm()函数,它与OLS回归相似,但多了一些参数,最主要的是family参数,它指定了概率分布及相应默认的连接函数,如下表:
分 布 族 | 默认的连接函数 |
---|---|
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”) |
另外,lm模型的部分函数可以用于glm模型,如summary、coefficient/coef、confit等。
模型的适用性是每个模型必不可少的一个判断,模型的拟合和回归诊断。当评价模型适用性时,可以使用初始响应变量的预测值与残差的图形来进行判断。
plot(predict(glmModel,type=”response”),residuals=(glmModel,type=”deviance”)
书中提到,对广义线性模型的异常点识别仍然未有统一答案,但可以通过帽子值,学生化残差和Cook距离找出异常大的值,然后通过相互比较来进行判断异常,这是一个方法。代码:
plot(hatvalues(glmModel))
plot(rstudent(glmModel))
plot(cooks.distance(glmModel))
还可以使用car包中的一种方法,在OLM回归的时候也有提到的强影响点
library(car)
influencePlot(glmModel)
当响应变量(因变量)的值较多的时候,诊断图较为有用,当响应变量只有有限个时,诊断图的功效会降低很多。
简单说一下它的公式:
Logistic回归需要把因变量转化为二值型因子,使用factor(col,levels=,labels=)进行转换。转换后即可使用glm函数进行拟合,所得结果仍然可以像OLS回归一样,通过P值来判断拟合情况,把不显著的变量删除后(注意,不能随便删除)再次进行拟合,最后使用卡方检验(anova(fit1,fit2,test=”Chisq”))来进行差异检验,若差异显著,则需要谨慎考虑是否删错了变量,若不显著,则说明删除变量后与未删除之前差异不明显,可以考虑删除。
# get summary statistics
data(Affairs, package = "AER")
summary(Affairs)
table(Affairs$affairs)
# create binary outcome variable
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)
# fit full model
fit.full <- glm(ynaffair ~ gender + age + yearsmarried + children + religiousness + education + occupation + rating, data = Affairs, family = binomial())
summary(fit.full)
# fit reduced model
fit.reduced <- glm(ynaffair ~ age + yearsmarried + religiousness + rating, data = Affairs, family = binomial())
summary(fit.reduced)
# compare models
anova(fit.reduced, fit.full, test = "Chisq")
# interpret coefficients
coef(fit.reduced)
exp(coef(fit.reduced))
预测,在原理之处已经说过,它使用预测函数predict得到的是Y=1时的概率值P,这能更好的帮助理解它的含义,如下面两段代码,前一段意思为婚姻评分满意度从1到5分时,婚外情的发生概率,后一段意思为年龄从17到57时,婚外情的发生概率:
# calculate probability of extramariatal affair by marital ratings
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
# calculate probabilites of extramariatal affair by 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
过度离势,意思即为观测到的响应变量的方差大于期望的二项分布的方差,而过度离势会导致奇异的标准误检验和不精确的显著性检验。
存在过度离势时,可以先通过二项分布来拟合,所得结果中的残差偏差及残差自由度的比值与1相比,若比1大很多,则可以认为存在过度离势。
可以通过卡方检验进行过度离势的检验,但需要进行两次拟合,一次为二项分布(即family=binomial()),另一次为类二项分布(即family=quasibinomial()),提供的p值可对零假设为“比值=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)
结果不显著,所以,不存在过度离势问题。
R中扩展的Logistic回归和变种如下所示。
稳健Logistic回归
robust包中的glmRob()函数可用来拟合稳健的广义线性模型,包括稳健Logistic回归。当拟合Logistic回归模型数据出现离群点和强影响点时,稳健Logistic回归便可派上用场。
多项分布回归
若响应变量包含两个以上的无序类别(比如,已婚/寡居/离婚),便可使用mlogit包中的mlogit()函数拟合多项Logistic回归。
序数Logistic回归
若响应变量是一组有序的类别(比如,信用风险为差/良/好),便可
使用rms包中的lrm()函数拟合序数Logistic回归。
可对多类别的响应变量(无论是否有序)进行建模是非常重要的扩展,但它也面临着解释性更复杂的困难。同时,在这种情况下评价模型拟合优度和回归诊断也变得更为复杂。
在婚外情的例子中,婚外偷腥的次数被二值化为一个“是/否”的响应变量,这是因为我们最感兴趣的是在过去一年中调查对象是否有过一次婚外情。如果兴趣转移到量上(过去一年中婚外情的次数),便可直接对计数型数据进行分析。分析计数型数据的一种流行方法是泊松回归,这便是我们接下来的话题。
也简单说一下它的公式:
与Logistic回归一样,连接函数换一下就OK了:glm(Y~X,data=,family=poisson()),书中例子如下
# --Poisson Regression--
# look at dataset
data(breslow.dat, package = "robust")
names(breslow.dat)
summary(breslow.dat[c(6, 7, 8, 10)])
# plot distribution of post-treatment seizure counts
opar <- par(no.readonly = TRUE)
par(mfrow = c(1, 2))
attach(breslow.dat)
hist(sumY, breaks = 20, xlab = "Seizure Count", main = "Distribution of Seizures")
boxplot(sumY ~ Trt, xlab = "Treatment", main = "Group Comparisons")
par(opar)
# fit regression
fit <- glm(sumY ~ Base + Age + Trt, data = breslow.dat, family = poisson())
summary(fit)
# interpret model parameters
coef(fit)
exp(coef(fit))
与Logistic一致,略
泊松分布的均值与方差相等,当响应变量观测的方差比依据泊松分布预测的方差大时,泊松回归可能发生过度离势。而计数型数据会经常性发生过度离势,且过度离势对结果的可解释性造成负面影响,因此过度离势在泊松过程较为重要,造成过度离势的原因一般来说有如下几条:
时间段变化的泊松回归
时间段变化的泊松回归其实就是把固定的时间变为可变化的时间段,相应的,研究的次数 λ 就变为单位时间内的次数,即比率 λtime ,新模型中,glm需要增加一个偏移参数offset。
在普通的泊松回归时,左侧为 ln(λ) ,时间段变化时,左侧为 ln(λtime)=ln(λ)−ln(time) ,而 ln(time) 可以移到右边,就形成了一个偏移量,即 ln(time) ,使用偏移参数offset=log(time)就可以进行时间段变化的泊松回归。如书中例子:
fit<-glm(sumY~Base+Age+Trt,data=breslow.dat,offset=log(time),family=poisson())
零膨胀的泊松回归
零膨胀的意思就是0值太多的意思,比如书中的婚外情例子,有一群人从未有过婚外情(即次数为0),他们相对那些有婚外情的人来说,称之为结构零值。此时使用零膨胀的泊松回归(zero-inflated Poisson regression),它将同时拟合两个模型:一个是预测哪些人会发生婚外情(非零),另一个是预测排除了结构零值之后,那些发生了婚外情的人会有多少次。使用pscl包中的zeroinfl()函数可做零膨胀的泊松回归。此函数相当于做两次模型,一次Logistic,一次Poisson,举个例子:数据框DF中有ABCDEY六个变量,其中Y为零膨胀变量,即Y中含有大量0值,需要用其它五个变量来拟合Y变量,于是函数这么写:
zeroinfl(Y~A+B+C|D+E,data=DF)
zeroinfl(Y~A+B+C+D|A+B+C+E,data=DF)
zeroinfl(Y~A+B+C|1,data=DF)
第一条命令的意思为由A、B、C决定Y的次数,D和E决定Y是否非0,用专业术语来说,就是ABC三个是点模型内变量,DE是零膨胀模型内变量,一个变量既可以属于点模型变量,也属于零膨胀模型变量!如第二条命令。第三条命令的意思是,当Y取得零值是等可能的,此时可以使用1来代替。
稳健泊松回归
robust包中的glmRob()函数可以用来拟合稳健泊松回归,此项在Logistic回归中也有提到。
PS:Logistic和泊松的扩展部分内容都没有仔细说明,这书对这类超出范围的内容都是一笔带过,后续得空再找资料补充吧。