机器学习入门之[读书笔记]机器学习:实用案例解析(9)
小标 2018-10-22 来源 : 阅读 1671 评论 0

摘要:本文主要向大家介绍了机器学习入门之[读书笔记]机器学习:实用案例解析(9),通过具体的内容向大家展现,希望对大家学习机器学习入门有所帮助。

本文主要向大家介绍了机器学习入门之[读书笔记]机器学习:实用案例解析(9),通过具体的内容向大家展现,希望对大家学习机器学习入门有所帮助。

第9章 MDS:可视化地研究参议员相似性

基于相似性聚类:本章的主旨是,对不同的观测记录,如何理解用距离的概念来阐明它们之间的相似性和相异性。
多维定标技术(multidimensional scaling, MDS),目的是基于观察值之间的距离度量进行聚类。只通过所有点之间的距离度量对数据进行可视化。
MDS处理过程:输入一个包含数据集中任意两点之间距离的距离矩阵,返回一个坐标集合,这个集合可以近似反映每对数据点之间的距离(维度低时信息会有缺失,只能说近似)
下面是一个简单的例子:

#距离度量与多维定标简介
#随机产生"用户"-"评分"矩阵
set.seed(851982)
ex.matrix <- matrix(sample(c(-1, 0, 1), 24, replace = TRUE), nrow = 4, ncol = 6)
row.names(ex.matrix) <- c(‘A‘, ‘B‘, ‘C‘, ‘D‘)
colnames(ex.matrix) <- c(‘P1‘, ‘P2‘, ‘P3‘, ‘P4‘, ‘P5‘, ‘P6‘)
#将矩阵与本身的转置相乘,得到"用户"与"用户"之间的差异矩阵
ex.mult <- ex.matrix %*% t(ex.matrix)
#数据点之间的距离矩阵
ex.dist <- dist(ex.mult)
#classical (Metric) Multidimensional Scaling
ex.mds <- cmdscale(ex.dist)
plot(ex.mds, type = ‘n‘)
text(ex.mds, c(‘A‘, ‘B‘, ‘C‘, ‘D‘))


  

 
通过记名投票记录对参议员进行聚类:
与上面思路一样,不同参议员之间对法案的赞成、反对、弃权进行分析,得到差异矩阵、距离矩阵、多维定标,进而可视化地展现出来。
加载数据:

library(foreign)
library(ggplot2)

data.dir <- "ML_for_Hackers/09-MDS/data/roll_call/"
data.files <- list.files(data.dir)
rollcall.data <- lapply(data.files, function(f) read.dta(paste(data.dir, f, sep = ""), convert.factors = FALSE))

#查看行数与列数
#dim(rollcall.data[[1]])


  
对数据进行简单的处理:删除投票数少的观测、简化投票情况:编码123简化为赞成票;编码456简化为反对票;编码7890简化为弃权票

rollcall.simplified <- function(df)
{
  #state编号为99是副总统,因为投票数少所以删除
  no.pres <- subset(df, state < 99)
  #编码1~3简化为赞成票;编码4~6简化为反对票;编码7890简化为弃权票
  for (i in 10:ncol(no.pres)) 
  {
    no.pres[, i] <-> 6, 0, no.pres[, i])
    no.pres[, i] <-> 0 & no.pres[, i] < 4, 1, no.pres[, i])
    no.pres[, i] <-> 1, -1, no.pres[, i])
  }
  return(as.matrix(no.pres[, 10:ncol(no.pres)]))
}
rollcall.simple <- lapply(rollcall.data, rollcall.simplified)


  
计算距离矩阵与多维定标:
多维定标时乘的(-1), 是为了直观,一般认为民主党为左派,共和党为右派

rollcall.dist <- lapply(rollcall.simple, function(m) dist(m %*% t(m)))
rollcall.mds <- lapply(rollcall.dist, function(d) as.data.frame((cmdscale(d, k = 2)) * -1))


  
对rollcall.mds进行简单的处理,方便后续作图

congresses <- 101:111
for (i in 1:length(rollcall.mds)) 
{
  names(rollcall.mds[[i]]) <- c("x", "y")
  congress <- subset(rollcall.data[[i]], state < 99)
  #为统一格式,name只取姓,存入congress.name中
  congress.names <- sapply(as.character(congress$name), function(n) strsplit(n, "[, ]")[[1]][1])
  #统一name,party转成因子变量,添加国会届数信息
  rollcall.mds[[i]] <- transform(rollcall.mds[[i]], name = congress.names, party = as.factor(congress$party), congress = congresses[i])
}


  
以第110届为例,对国会成员进行可视化处理:注意调用rollcall.mds时列表序号由1开始而不是0
这里先创建ggplot对象,存储了基本信息;后面画了两张图,一张是用点的形状表达,另一张用具体名字表达

cong.110 <- rollcall.mds[[10]]

base.110 <- ggplot(cong.110, aes(x = x, y = y)) + 
  scale_size(range = c(2,2), guide = "none") + scale_alpha(guide = "none") + theme_bw() + 
  theme(axis.ticks = element_blank(), axis.text.x = element_blank(), axis.text.y = element_blank(), panel.grid.major = element_blank()) + 
  ggtitle("Roll Call Vote MDS Clustering for 110th U.S. Senate") + 
  xlab("") + ylab("") + 
  scale_shape(name = "Party", breaks = c("100", "200", "328"), labels = c("Dem.", "Rep.", "Ind."), solid = FALSE) + 
  scale_color_manual(name = "Party", values = c("100" = "red", "200" = "blue", "328" = "black"), 
                     breaks = c("100", "200", "328"), labels = c("Dem.", "Rep.", "Ind."))
print(base.110 + geom_point(aes(shape = party, alpha = 0.75, size = 2)))
print(base.110 + geom_text(aes(color = party, alpha = 0.75, label = cong.110$name, size = 2)))


  

 

 
将所有届的图分别画出来,并放在一起比较(facet_wrap()函数可以根据congress将不同届的图分开来画)

all.mds <- do.call(rbind, rollcall.mds)
all.plot <- ggplot(all.mds, aes(x = x, y = y)) + 
  geom_point(aes(shape = party, alpha = 0.75, size = 2)) + 
  scale_size(range = c(2,2), guide = "none") + 
  scale_alpha(guide = "none") + theme_bw() + 
  theme(axis.ticks = element_blank(), axis.text.x = element_blank(), axis.text.y = element_blank(), 
        panel.grid.major = element_blank()) + 
  ggtitle("Roll Call Vote MDS Clustering for U.S. Senate (101st - 111th Congress)") + 
  xlab("") + ylab("") + 
  scale_shape(name = "Party", breaks = c("100", "200", "328"), labels = c("Dem.", "Rep.", "Ind."), solid = FALSE) + 
  facet_wrap(~ congress)
all.plot


 

需要注意的是,虽然上图中,101届看起来距离比较近,但是并不能说明两党之间是不分化的,因为相同符号的点(相同的党派)仍然是各自聚在一起而彼此分离的。"看起来比其他图要近"仅仅是因为坐标轴的问题,因为这11张图采用同一尺度的坐标轴。同时,图与图的这些差异也不足以说明101届分化程度较轻,因为这种情况很有可能是其他因素(比如观察值的数量等)影响的。

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标人工智能机器学习频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved