最近做项目涉及到要使用multinomial logit model (MNL) 模型。看了一堆文献讲mnl, 但是没有给什么具体能上手的实例,就算有也是一笔带过,打算找一些使用R 语言来实现mnl模型的例子,在模仿和实践中慢慢理解。

Multinomial Logit Model又有很多其它说法,诸如Multinomial Logistic Regression等等。

本文的实例来自两篇文章。

[1]R Data Analysis Examples: Multinomial Logistic Regression: http://www.ats.ucla.edu/stat/r/dae/mlogit.htm

[2]How to: Multinomial regression models in R  :https://www.r-bloggers.com/how-to-multinomial-regression-models-in-r/

第一篇  R Data Analysis Examples: Multinomial Logistic Regression

第一篇是UCLA的idre机构网站中,关于R语言实现 Multinomial Logistic Regression 的教程

Multinomial logistic regression被用于输出结果为 nominal variables 的建模。

本文使用了一下的包,请确保你能载入这些包,如果你没有安装,可以使用语句 :install.packages("packagename"), 或者如果你使用的包的版本太低,可以使用语句: update.packages()  .

require(foreign)
require(nnet)
require(ggplot2)
require(reshape2)

Version info: Code for this page was tested in R version 3.1.1 (2014-07-10)
On: 2015-12-17
With: reshape2 1.4.1; ggplot2 1.0.1; nnet 7.3-10; foreign 0.8-65; knitr 1.10.5

Multinomial Logistic Regression的例子

例1: 人们的职业选择结果可能会被父母的职业和他们自己的教育水平所影响。我们可以研究某个人的职业选择和他的教育水平、父母的职业之间的关系。而人们所选择的职业多种多样,不是只有一种或者两种。

例2:一个生物学家啃呢个会对短吻鳄所选择的食物感兴趣。成年的短吻鳄可能与幼年的短吻鳄的食物偏好不同。所以我们这里的有各种各样的食物作为选择结果,该结果是被短吻鳄的形体大小和环境变量所影响。

例3:进入高等教育的学生对于选择什么样的学习项目类型有三种选择:普通项目,针对工作的项目以及学术型的项目。他们的选择可能被他们的写作成绩和社会经济地位影响。

数据描述

我们的数据分析例子使用的是第三个例子,使用 hsbdemo 数据。首先是先读入数据。

ml <- read.dta("http://www.ats.ucla.edu/stat/data/hsbdemo.dta")

该数据包括200个学生的选择的项目类型(prog, 三种类型 categorical variable), 他们的社会地位(ses 三种地位 categorical variable),写作分数(write, a continuous variable)。读完数据后,我们可以使用一些语句来对我们的数据建立一个初步的概念和感觉。

with(ml, table(ses, prog))
##         prog
## ses      general academic vocation
##   low         16       19       12
##   middle      20       44       31
##   high         9       42        7

从结果中可以看出,社会经济地位中等的学生最多,低等的最少。社会经济地位高的学生中,绝大多数都是选择学术型的program 。

with(ml, do.call(rbind, tapply(write, prog, function(x) c(M = mean(x), SD = sd(x)))))
##             M   SD
## general  51.3 9.40
## academic 56.3 7.94
## vocation 46.8 9.32

从结果中可以看出,选择学术型项目的学生的写作成绩平均分最高,且波动最小。 选择职业型项目的学生写作成绩平均分最低。

Multinomial Logistic Regression 方法

以下的方法中我们使用的nnet 包中的multinom 函数。其实在R语言的其它包中也有其它函数可以实现MNL方法(诸如 mlogit)。 我们选择multinom 函数的原因是,它不需要将数据reshape(而mlogit就需要)。

在运行我们的模型之前,选择一个合适的参照组(a reference group)非常重要。 我们可以使用relevel 来调换outcome variable 的等级顺序。值得注意的是, multinom 包不包含对于回归系数的p-value的计算。

ml$prog2 <- relevel(ml$prog, ref = "academic")
test <- multinom(prog2 ~ ses + write, data = ml)
## # weights:  15 (8 variable)
## initial  value 219.722458
## iter  10 value 179.982880
## final  value 179.981726
## converged
summary(test)
## Call:
## multinom(formula = prog2 ~ ses + write, data = ml)
##
## Coefficients:
##          (Intercept) sesmiddle seshigh   write
## general         2.85    -0.533  -1.163 -0.0579
## vocation        5.22     0.291  -0.983 -0.1136
##
## Std. Errors:
##          (Intercept) sesmiddle seshigh  write
## general         1.17     0.444   0.514 0.0214
## vocation        1.16     0.476   0.596 0.0222
##
## Residual Deviance: 360
## AIC: 376
z <- summary(test)$coefficients/summary(test)$standard.errors
z
##          (Intercept) sesmiddle seshigh write
## general         2.45    -1.202   -2.26 -2.71
## vocation        4.48     0.612   -1.65 -5.11
#2-tailed z test
p <- (1 - pnorm(abs(z), 0, 1))*2
p
##          (Intercept) sesmiddle seshigh    write
## general     1.45e-02     0.229  0.0237 6.82e-03
## vocation    7.30e-06     0.541  0.0989 3.18e-07

我们首先可以看到,即使我们已经将multinom运行赋值给了test,模型运行后仍然得到了一些结果。运行结果包括 some iteration history 和最终的负log-likelihood 179.981726. 这一结果乘以2后即为模型summary结果中的 Residual Deviance:360, 它可以用来和 nested models 来比较,但是本例中我们不做比较。

模型summary 后的结果一块是系数,一块是  standard errors。每一个块中,都有一行与模型等式对应。在系数块中,第一行是general program 与academic program 的比较,第二行代表 vocation program 与 academic program 的比较(academic program 是我们的参考组reference group。 如果我们把第一行的系数记为b1_, 第二行的系数记为b2_, 我们可以写出我们的模型等式。

ln(P(prog=general)P(prog=academic))=b10+b11(ses=2)+b12(ses=3)+b13write
ln(P(prog=vocation)P(prog=academic))=b20+b21(ses=2)+b22(ses=3)+b23write

一种选择结果类别的概率与基准选择的概率的比被称为相对危险度(relative risk), 有时候只是为了描述回归参数,我们也叫做odds. 相对危险度是对线性方程等号右边部分的取幂,取幂后的回归系数就是自变量每单位变化的相对危险度。下面我们开对模型的系数取幂来观察是如何变化的。

## extract the coefficients from the model and exponentiate
exp(coef(test))
##          (Intercept) sesmiddle seshigh write
## general         17.3     0.587   0.313 0.944
## vocation       184.6     1.338   0.374 0.893
  • “write”变量增加一个单位,普通项目vs学术项目的相对危险风险比(the relative risk ratio)是0.9437
  • “ses”社会地位变量从1变为3时,普通项目VS学术项目的相对风险比是0.3126
你也可以使用预测的概率来帮助你理解这个模型。你可以使用 fitted 函数来得到模型的拟合值(估计值)。(在这里和原数据比对了一下,感觉不是很精确呀。)
head(pp <- fitted(test))

##   academic general vocation
## 1    0.148   0.338    0.513
## 2    0.120   0.181    0.699
## 3    0.419   0.237    0.345
## 4    0.173   0.351    0.476
## 5    0.100   0.169    0.731
## 6    0.353   0.238    0.409

然后,如果你想检测我们变量中某个变量的改变对预测结果的影响,可以创建一个小的数据组,改变其中一个变量,其它变量保持不变。首先,我们让"write" 变量保持不变,检测社会地位的改变对预测值的影响。
dses <- data.frame(ses = c("low", "middle", "high"),write = mean(ml$write))
predict(test, newdata = dses, "probs")

##   academic general vocation
## 1    0.440   0.358    0.202
## 2    0.478   0.228    0.294
## 3    0.701   0.178    0.121

另一种理解模型的方式是在三种不同的社会地位下,连续改变"write"值,并对该社会地位中的预测值取平均。

dwrite <- data.frame(ses = rep(c("low", "middle", "high"), each = 41),write = rep(c(30:70), 3))## store the predicted probabilities for each value of ses and write
pp.write <- cbind(dwrite, predict(test, newdata = dwrite, type = "probs", se = TRUE))## calculate the mean probabilities within each level of ses
by(pp.write[, 3:5], pp.write$ses, colMeans)

## pp.write$ses: high
## academic  general vocation
##    0.616    0.181    0.203
## ------------------------------------------------------
## pp.write$ses: low
## academic  general vocation
##    0.397    0.328    0.275
## ------------------------------------------------------
## pp.write$ses: middle
## academic  general vocation
##    0.426    0.201    0.373

有时候,一组图能过很好地表达大量的信息。使用我们上面的“pp.write” 对象,我们可以绘制在不同社会地位下,预测值与写作分数的关系的图。
## melt data set to long for ggplot2
lpp <- melt(pp.write, id.vars = c("ses", "write"), value.name = "probability")
head(lpp) # view first few rows

##   ses write variable probability
## 1 low    30 academic      0.0984
## 2 low    31 academic      0.1072
## 3 low    32 academic      0.1165
## 4 low    33 academic      0.1265
## 5 low    34 academic      0.1370
## 6 low    35 academic      0.1483

## plot predicted probabilities across write values for
## each level of ses facetted by program type
ggplot(lpp, aes(x = write, y = probability, colour = ses)) +geom_line() +facet_grid(variable ~ ., scales="free")

Multinomial Logit Model (MNL) 模型R语言nnet包multinom函数实现实例相关推荐

  1. R语言survival包clogit函数构建条件logistic回归模型、summary函数查看模型汇总统计信息、通过似然比检验分析结果判断模型有无统计学意义

    R语言survival包clogit函数构建条件logistic回归模型.summary函数查看模型汇总统计信息.通过似然比检验分析结果判断模型有无统计学意义 目录

  2. R语言survival包coxph函数构建cox回归模型、ggrisk包ggrisk函数可视化Cox回归的风险评分图、使用风险得分的中位数计算最佳截断值cutoff(基于LIRI基因数据集)

    R语言survival包coxph函数构建cox回归模型.ggrisk包ggrisk函数可视化Cox回归的风险评分图.使用风险得分的中位数计算最佳截断值cutoff(基于LIRI基因数据集) 目录

  3. 机器学习之R语言caret包trainControl函数(控制调参)

    机器学习之R语言caret包trainControl函数(控制调参) trainControl参数详解 源码 参数详解 示例 trainControl参数详解 源码 caret::trainContr ...

  4. R语言stringr包str_dup函数字符串多次复制实战

    R语言stringr包str_dup函数字符串多次复制实战 目录 R语言stringr包str_dup函数字符串多次复制实战 #导入stringr包 #仿真数据

  5. R语言stringr包str_count函数计算字符串匹配个数实战

    R语言stringr包str_count函数计算字符串匹配个数实战 目录 R语言stringr包str_count函数计算字符串匹配个数实战 #导入stringr包 #仿真数据

  6. R语言ggpubr包ggsummarystats函数可视化分组条形图(自定义分组颜色、添加抖动数据点jitter、误差条)并在X轴标签下方添加分组对应的统计值(样本数N、中位数、四分位数的间距iqr)

    R语言ggpubr包ggsummarystats函数可视化分组条形图(自定义分组颜色.添加抖动数据点jitter.误差条error bar)并在X轴标签下方添加分组对应的统计值(样本数N.中位数med ...

  7. R语言plyr包round_any函数将向量数据近似到任意精度实战

    R语言plyr包round_any函数向量将数据近似到任意精度实战 目录 R语言plyr包round_any函数向量将数据近似到任意精度实战 #导入plyr包 #仿真数据

  8. R语言stringr包str_detect函数检测字符串中模式存在与否实战

    R语言stringr包str_detect函数检测字符串中模式存在与否实战 目录 R语言stringr包str_detect函数检测字符串中模式存在与否实战 #导入stringr包

  9. R语言dplyr包arrage函数排序dataframe实战:单列排序、多列排序、自定义排序

    R语言dplyr包arrage函数排序dataframe实战:单列排序.多列排序.自定义排序 目录 R语言dplyr包arrage函数排序dataframe实战:单列排序.多列排序

最新文章

  1. 即使用ADO.NET,也要轻量级实体映射,比Dapper和Ormlite均快
  2. 如何获得Java中泛型类的类型参数?
  3. 全球及中国抗甲状腺药物行业应用现状调研及未来产销需求预测报告2021-2027年
  4. Virtualbox桥接网卡设置
  5. weblogic创建域后启动不了_摩托车淋雨后启动不了什么原因?如何解决?
  6. memcached mysql 性能测试_InnoDB memcached插件 vs 原生memcached对比性能测试
  7. BotVS开发基础—2.2 下限价单 交易
  8. Bootstrap模态框中再嵌套模态框导致第一个模态框的滚动条消失
  9. Dockerfile文件:使用脚本文件生成镜像
  10. Windows系统electron集成flash播放器(.swf文件在electron中Vue页面中播放)
  11. Linux下sopcast
  12. shell解析HTML
  13. 前端——使用JavaScript(jQuery)通过身份证号获取籍贯、生日、年龄、性别
  14. 7-20 表达式转换(中缀转后缀)
  15. 关于node版本16+ 安装依赖会出现error的问题
  16. 中国联通和中国电信如合并要抗衡中国移动需要时间
  17. 永远做一个有计划的人
  18. 面经 | bigo/联影/58同城20校招计算机视觉算法岗
  19. Adjust接入记录
  20. 编写book.java_Java集合框架上机练习题:编写一个Book类,该类至少有name和price两个属性。该类要实现Comparable接口,在接口的compareTo()方法........

热门文章

  1. cmaq安装教程linux,CMAQ编译和安装
  2. Centos7命令行方式安装DM
  3. Oracle备份与恢复
  4. STM32F1和F4的区别
  5. python编程好学吗-零基础可以学会python吗?python好学吗?
  6. org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction
  7. 选用pg的优点和缺点
  8. 【2019多校第一场补题 / HDU6578】2019多校第一场A题1001Blank——dp
  9. can收发器 rx_CANOpen系列教程03_CAN收发器功能、原理及作用
  10. 选好核心交换机六个关键指标有哪些?