首页 > 代码库 > Logistic Regression in R
Logistic Regression in R
1.模型简介:
说起统计中最常用的模型,非回归莫属。在挖掘中,也只有回归能很好的解决因变量为连续型变量的预测问题,这篇文章主要对回归中一种特殊的形式:Logistic回归。
Logistic回归解决的是分类问题,特别在二项分布中,Logistic是最重要的模型(没有之一)。Logistic回归根据因变量类别不同,又可以分为Binary Logistic 回归分析和Multinomial Logistic 回归分析,Binary Logistic回归模型中因变量只能取两个值1和0虚拟因变量),而Multinomial Logistic 回归模型中因变量可以取多个值。本文主要基于R讨论Binary Logistic回归。
2.主要思想:
Logistic回归主要通过构造一个重要的指标:发生比来判定因变量的类别。
在这里我们引入概率的概念,把事件发生定义为Y=1,事件未发生定义为Y=0,那么事件发生的概率为p,事件未发生的概率为1-p,把p看成x的线性函数;
首先看简单的概率线性模型:
回归中,最常用的估计是最小二乘估计,因为使得p在[0,1]之间变换,最小二乘估计不太合适,有木有一种估计法能让p在趋近与0和1的时候变换缓慢一些(不敏感),这种变换是我们想要的,于是引入Logit变换:
我们对p/(1-p)也就是发生与不发生的比值取对数,也称对数差异比。经过变换后,p对x就不是线性关系了。
于是,模型为:
用p来代替θ,公式变换为:
我们用r来看一下曲线的形状:
library(ggplot2)
x=seq(-10,10,by=0.2)
p=exp(x)/(1+exp(x))
df=data.frame(x,p)
qplot(x,p,data=http://www.mamicode.com/df,geom="line",group=1)
p在0和1附近变化不敏感,ps:这条曲线帮了我一个大忙,最近做RTB竞价算法时,需要按照CTR设定一个CTR指导价,然后以CPC做曲线的修正,出于成本考虑,我们的出价不会高于某个固定值K,所以把这条曲线变换一下就派上大用场了。(扯远了)
这条曲线的主要特性是θ函数取值可以在-∞变到+∞,p的取值在[0,1],且极值端变化不敏感。这就是我们想要的。值得注意的是,经过logit变换,已经不是线性模型。
3.基于R的案例
以下这个例子主要参考《Introduction to statistical learning with R》,强烈推荐这本书。尤其是回归部分,讲解的很透彻。
数据以Smarket为例,该数据包含2001-2005年标准普尔500指数1250个观测值,9个变量。9个变量分别为:年份,前5个交易日的收益率,前一个交易日和交易额(单位:billions),今天的回报率和走势(上升或下降)。
df=read.csv("house.csv",header=TRUE)
str(df)
data.frame‘: 1250 obs. of 9 variables:
$ Year : num 2001 2001 2001 2001 2001 ...
$ Lag1 : num 0.381 0.959 1.032 -0.623 0.614 ...
$ Lag2 : num -0.192 0.381 0.959 1.032 -0.623 ...
$ Lag3 : num -2.624 -0.192 0.381 0.959 1.032 ...
$ Lag4 : num -1.055 -2.624 -0.192 0.381 0.959 ...
$ Lag5 : num 5.01 -1.055 -2.624 -0.192 0.381 ...
$ Volume : num 1.19 1.3 1.41 1.28 1.21 ...
$ Today : num 0.959 1.032 -0.623 0.614 0.213 ...
$ Direction: Factor w/ 2 levels "Down","Up": 2 2 1 2 2 2 1 2 2 2 ...
#以前5个交易日的收益率和前一个工作日的交易额为自变量,今天的走势做因变量做Logistic回归;
glm.fit=glm(Direction~Lag1+Lag2+Lag3+Lag4+Lag5+Volume,
data=http://www.mamicode.com/Smarket,family="binomial")
summary(glm.fit)
Call:
glm(formula = Direction ~ Lag1 + Lag2 + Lag3 + Lag4 + Lag5 +
Volume, family = "binomial", data = http://www.mamicode.com/Smarket)
Deviance Residuals:
Min 1Q Median 3Q Max
-1.446 -1.203 1.065 1.145 1.326
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -0.126000 0.240736 -0.523 0.601
Lag1 -0.073074 0.050167 -1.457 0.145
Lag2 -0.042301 0.050086 -0.845 0.398
Lag3 0.011085 0.049939 0.222 0.824
Lag4 0.009359 0.049974 0.187 0.851
Lag5 0.010313 0.049511 0.208 0.835
Volume 0.135441 0.158360 0.855 0.392
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 1731.2 on 1249 degrees of freedom
Residual deviance: 1727.6 on 1243 degrees of freedom
AIC: 1741.6
Number of Fisher Scoring iterations: 3
有时候,预测股市就是这么不靠谱。很多自变量没通过验证,接下来我们基于AIC准则用逐步回归做一下变量筛选;
注:AIC一般公式为 AIC=2k-ln(L),其中k为参数的个数,L为估计模型最大化的似然函数值;
step(glm.fit)
Start: AIC=1741.58
Direction ~ Lag1 + Lag2 + Lag3 + Lag4 + Lag5 + Volume
Df Deviance AIC
- Lag4 1 1727.6 1739.6
- Lag5 1 1727.6 1739.6
- Lag3 1 1727.6 1739.6
- Lag2 1 1728.3 1740.3
- Volume 1 1728.3 1740.3
<none> 1727.6 1741.6
- Lag1 1 1729.7 1741.7
#此处略去一百字;
Direction ~ 1
Call: glm(formula = Direction ~ 1, family = "binomial", data = http://www.mamicode.com/Smarket)
Coefficients:
(Intercept)
0.07363
Degrees of Freedom: 1249 Total (i.e. Null); 1249 Residual
Null Deviance: 1731
Residual Deviance: 1731 AIC: 1733
这个结果足以让你崩溃,扔硬币都比这靠谱。原来不用任何变量预测是最靠谱的。
#模型的评估
glm.probs =predict(glm.fit,type ="response")
glm.probs[1:10]
#生成哑变量
contrasts(Smarket$Direction)
glm.pred=rep ("Down " ,1250)
glm.pred[glm .probs >.5]=" Up"
table(glm .pred ,Direction )
mean(glm.pred== Direction )
[1] 0.5216
通过混淆矩阵计算分类的准确性仅有52%,很不乐观;
挖掘本质上是挖掘有趣的的模式,以上数据说明我们白忙活了一场,但是我们通过实例学习了Logistic模型。
当然我们还可以通过数据变换或构造新的变量来提升拟合降低AIC,最终,模型讲究的还是泛化能力;
有时候:拟合很丰满,泛化很骨感。