1. 首页
  2. R语言

【深度教程】数据的获取、分析与表达

【深度教程】数据的获取、分析与表达

上周果说组织了一次线下研讨沙龙,主要讨论了数据获取、分析与表达,这里将分三次在果说微信中与大家分享相关内容,虽然技术性强点,但对于高年级本科生,研究生应该还是有些价值的。

毕竟上周刚开的苹果WWDC14上也说么:Write the code, Change the world.

这一篇主要讲涉及到数据获取、分析和表达的目标,工具(及学习材料),和简单方法,后两篇会有比较多的例子。首先,让我们从三个词开始:

技术、问题与系统 —— 写在前面

技术(Technique)

研究时间越长,技术占的重要性越低。我的理解是这样:随着研究的进行,研究者可以学会更多的技术,当你掌握了一项技术后,它就变成了一个工具,对于研究来说,技术的重要性体现在“工具”层面。

但是前提是要“掌握技术”,而且技术(相对于问题和系统)比较好教,好学,好分享。

问题(Question)

研究领域的选择,未来方向的确定,是提问题提出来的。但提问题不是随随便便的问题,而是要想Big Question。

Perhaps the most important single step in the research process is choosing a question to investigate. What most distinguishes scientists noted by posterity is not their technical skill, but they chose interesting problems. — Tim Hunt. 2011

系统(System)

一个人永远学不完新东西,所以更重要的是要有自己的研究体系,如果没有自己的研究体系,只能要么看别人做什么跟着做什么,或者自己会什么就做什么,东打一枪、西放一炮,很难有系统发现。对于体系的培养,施老师觉得学习本学科领域的科学史(不是泛的科学史)非常重要,看科学发展的过程,会让人对所在领域有个 全局观,能培养一种思维方式。

——上述三点来自施一公老师的报告,后面的内容笔者会针对以上每个要点进行引申与理解。

1.1 目标 | Target

Step1 一个想要研究的问题 -> Step2 将问题抽象成可以科学研究的对象 -> Step3 找对应数据 -> Step4 分析 -> Step5 返回问题

前两步非常非常重要,但对不同个体,不同研究方向差异很大,所以我们在这里重点关注Step3 Step4。

如果非常认真,一到两个学期(6-12个月,500-1000小时,按大学一门3学分的课是100小时左右的话,相当于5-10门三学分的课),可以掌握用于自身研究的最基本技能。

1.2 软件及相关资料 | Python & R

Software:

对数据处理、画图有比较多需求的同学可以学R,对应的软件是Canopy(Python的集成开发环境);对计算机仿真、互联网数据抓取、机器学习有比较多需求的同学可以试试Python,对应的开发软件是RStuidio(R的集成开发环境)

Packages:

开源软件的好处就是可以有不同的人贡献各种“包”,极大方便我们的生活。与本节讨论内容相关的包:Python (Beautiful Soup, csv, urllib2, json); R (ggplot2, ggmap, maps[内置了一些地图,但无中国], mapdata[有中国地图,但比较老,重庆和四川还没有分开])

Books:

  • Learn Python the Hard Way (作者提供免费版)

  • 《用Python做科学计算》(HYRY Studio,与数值分析、模拟有关)

  • R in Action (R的入门读物)

  • Visualize This (教很多可视化的操作)

  • 数学之美 (数学及模型思想)

【深度教程】数据的获取、分析与表达

【深度教程】数据的获取、分析与表达

【深度教程】数据的获取、分析与表达

MOOC(在线课程):

Coursera

Data Science[基于R语言的系列课程,约翰霍普金斯大学]一共有九门课,其中1,2,3,4,6,7都比较适合看:

  1. The Data Scientist’s Toolbox

  2. R Programming

  3. Getting and Cleaning Data

  4. Exploratory Data Analysis

  5. Reproducible Research

  6. Statistical Inference

  7. Regression Models

  8. Practical Machine Learning

  9. Developing Data Products.

Model Thinking[用模型思考问题,密歇根大学]

Maps and Geospatial Revolution[简单的地理学介绍及其于ESRI在线平台的地图制作,PennState]

1.3 过程 | Process:

如何找数据? | Where’s the data?

  1. 公开数据集(中国的数据可以在这里找到:知网、新浪爱问、人大经济论坛、政府公开数据网站:http://data.stats.gov.cn/、Beijing City Lab 等)

  2. 申请政务公开(统计局网站有联系方式,可查经普、人口普查、统计年鉴等)

  3. 互联网数据抓取(意识到有系统误差的存在,这是由抽样方式造成的,比如微博数据只是针对使用微博的用户)

互联网数据抓取过程,以地理信息为例:

  1. geocoding

  2. web crawling

  3. data clean (structured data vs. unstructured data)

  4. analysis

  5. visualize

geocoding-api

Geocoding API包括地址解析和逆地址解析功能。

http://developer.baidu.com/map/geocoding-api.htm

地址解析是指,根据地址获取坐标。例如:“北京市海淀区中关村南大街27号”地址解析的结果是“lng:116.31985,lat:39.959836”。

http://api.map.baidu.com/geocoder?address=地址&output=输出格式类型&key=用户密钥&city=城市名

逆地址解析是指,根据坐标获取地址。例如:“lat:31.325152,lng:120.558957”逆地址解析的结果是“江苏省苏州市虎丘区塔园路318号”。

http://api.map.baidu.com/geocoder?location=纬度,经度&output=输出格式类型&key=用户密钥

我们在这里给出几个比较简单的例子,主要是基于R和相应的几个包。用到的工具介绍和学习资料请参考上一篇推送—数据的获取、分析与表达(1)。

1.4 Examples | 例子

Example 1:不需要编程的数据可视化表达

【深度教程】数据的获取、分析与表达

基础资料:

0)数据,因人而异;

1)矢量中国地图(搜索引擎很容易找到);

2)配色方案,可参考一个提供配色选择方案的网站ColorBrewer;

3)软件工具:AI(illustrator)

推荐经常看一看《经济学人》杂志和《纽约时报》的图表,我认为是所有出版物中做的比较好的。(比如http://www.economist.com/content/chinese_equivalents)

如何搞定中国的地图,请看:

《终于搞定了中国分省市地图》(http://yihui.name/cn/2007/09/china-map-at-province-level/)

《用R软件绘制中国分省市地图》(http://cos.name/2009/07/drawing-china-map-using-r/)

Example 2:坐标获取、距离测量和地图获取

R的一个软件包ggmap

(1)运用geocode功能获取经纬度坐标

输入

geocode("China")

返回

lon lat

1 104.1954 35.86166

即为中国的经纬度坐标。

(2)运用mapdist进行距离测量

输入

mapdist(‘Tsinghua University’, ‘Beijing University’, ‘walking’)

返回

from to m km miles seconds

1 Tsinghua University Beijing University 3329 3.329 2.068641 2458

minutes hours

1 40.96667 0.6827778

从清华到北大竟然3.3公理,要41分钟,估计是从东门算的吧。

(3)运用get_map获取地图

library(ggmap)

library(mapproj)

map <- get_map(location = ‘Beijing’, zoom = 8) #以北京为中心,zoom代表类似放大倍数.

【深度教程】数据的获取、分析与表达

京津冀地区出现了。GOOGLE地图本身就是个大的GIS系统,如果在上面一行代码里加上 maptype = ‘roadmap’就可以得到北京的路网图。

map <- get_map(location = ‘Beijing’, zoom = 10, maptype = ‘roadmap’) #北京路网

更重要的是基于GOOGLE地图我们可以叠加各种自己处理过的信息,比如很火的航班数据可视化,在Mapping the World’s Biggest Airlines里有详细描述,但不是基于GOOGLE地图。在中国国内航线信息的可视化中,有一个简化的作法。我也简单画了一个,有时间会再研究下那个比较FANCY的夜景航线图是怎么做出来的。

【深度教程】数据的获取、分析与表达

参考:http://donglei.name/2013/10/map-data-with-r/

Example 3:制作世界范围的数据表达图

【深度教程】数据的获取、分析与表达

需要在地图上表达《2008年联合国人类发展报告》中未成年人生育率按国家分布的情况(每1000名15-19岁女性中生育数量)。

library(maps) #载入maps

fertility <- read.csv("http://book.flowingdata.com/ch08/points/adol-fertility.csv")

map(‘world’, fill = FALSE, col = "#cccccc") #选择世界地图,不填充,底图为灰色

symbols(fertility$longitude, fertility$latitude,

circles = sqrt(fertility$ad_fert_rate), add = TRUE,

inches = 0.1, bg = "#93ceef", fg = "#ffffff") #圆圈的大小(面积而非半径)由生育率决定

即可得到如上所示的世界未成年人生育率按国家的分布情况图。

这次继续给出两个稍微复杂点的例子,后面我们还会推送一些作者总结的相关学习资源,还有关于GIS的相关文章,敬请期待。

Example 4: Beijing House Price

Step 1. Get Data (Python爬虫)

import urllib2 #Python中常用的爬取库

import time

link_start = ” #此处为解析到的爬取网站url

link_end = ” # 如需要原始url地址可以联系公共号

rawdata = ” #存取原始数据

#这一段代表要爬取的经纬度范围,及网格大小

lat = 39.55

for i in range(30):

print i

lat += 0.025

lng = 116.05

for j in range(35):

print j

lng += 0.025

#抓取相关内容

link = link_start + str(lat) + ‘,’ + str(lat+0.1) + ‘,’ + str(lng) + ‘,’ + str(lng+0.1) + link_end

time.sleep(3) #不要过于频繁,这里一次抓取尝试停顿3秒

response = urllib2.urlopen(link)

html = response.read()

#数据清理

index = html.find(‘],"props’)

if index > 10:

myItem = html[10:index] + ‘,’

print myItem

rawdata += myItem

target = open(‘center.txt’, ‘w’)

target.truncate()

target.write(rawdata)

target.close()

Step 2. Visualize (R的ggplot2)

library(ggplot2)

library(ggmap)

#读入文件

price <- read.csv("HousePrice2013.csv")

#将价格分组

price$ID <- (price$Price %/% 20000 + 1)

price$ID[price$ID > 5] <- 5

price$ID <- as.factor(price$ID)

#设置要画图的经纬度范围

price1 <- price[price$Lng < 116.8 & price$Lng > 116.0,]

price2 <- price1[price1$Lat < 40.2 & price1$Lat > 39.6,]

#用ggmap载入北京底图

map <- get_map(location = "beijing", zoom = 10, messaging = FALSE, color = "bw",maptype = ‘toner’, source="stamen")

g <- ggmap(map)

#画点,设置点的大小、透明度等

p <-g + geom_point(data=price2, aes(x=price2$Lng, y=price2$Lat, colour=price2$ID), size=3, alpha=0.5)

#设置颜色、图例等

p <- p + scale_colour_manual(name="House Price(RMB)",

values=c("#f1eef6", "#d7b5d8", "#df65b0", "#dd1c77", "#980043"),

labels=c("0-20,000","20,000-40,000","40,000-60,000","60,000-80,000", "80,000+"))

print(p)

Step 3. Analysis

根据不同分析问题进行具体分析。

Example 5: 美国失业率地图 (整理自Visualize This一书)

这是美国2010年8月失业情况按县域的分布,红色越深表示失业率越高,下次我记得加比例尺。数据可以在这里下载。和文章一开始提到的地图放到一个文件夹下。

这张图比前之前的复杂些,其于Python而不是R完成,思路就是找到地图中不同区域,然后让数据中表示的区域与地图表示的一一对就,再用失业率分成几种颜色向对应区域填充,主要分为三步:

1.载入数据和地图,这里SVG地图是矢量地图,可用文本编辑,这也是可用Python处理的基础。

2.用各自的“地址”对应区域,需要将失业率数据中的地址做些小处理以和SVG图中的匹配。

3.填充颜色,这组颜色由ColorBrewer生成,其实可以选择任何自己喜欢又能表达充分的色系。

# -*- coding: utf-8 -*-

import csv

from bs4 import BeautifulSoup #bs4之后导入的方法与书中的老版本不一样

# Read in unemployment rates

reader = csv.reader(open(‘unemployment-aug2010.txt’, ‘r’), delimiter=",") #文件名用数据的名字,如果直接下载,则为unemployment-aug2010.txt

# Load the SVG map

svg = open(‘counties.svg’, ‘r’).read() #文件名为SVG地图的名字

#SVG里每条路径都有唯一ID,正好是其所属州+所属县,失业数据里也有州和县的代码,不过是分开的。如,阿拉巴马州Autauga县的州码是01,县码是001,在SVG图中路径ID就是01001

unemployment = {}

rates_only = [] # To calculate quartiles

min_value = 100; max_value = 0; past_header = False

for row in reader:

if not past_header:

past_header = True

continue

try:

full_fips = row[1] + row[2]

#将州码和县码合成一个数字,在Python规则里数列从第0个开始,[1]代表数列里的第二个数

rate = float( row[5].strip() )

unemployment[full_fips] = rate

rates_only.append(rate)

except:

pass

# Load into Beautiful Soup

soup = BeautifulSoup(svg) #bs4不需要再定义空标签.构造方法的 selfClosingTags 参数已经不再使用.

# Find counties

paths = soup.findAll(‘path’)

# Map colors,Red-purple

colors = ["#F1EEF6", "#D4B9DA", "#C994C7", "#DF65B0", "#DD1C77", "#980043"]

# County style , fill在代码最后,值为空,由各县失业率来定

path_style = ‘font-size:12px;fill-rule:nonzero;stroke:#FFFFFF;stroke-opacity:1;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-linecap:butt;marker-start:none;stroke-linejoin:bevel;fill:’

# Color the counties based on unemployment rate

for p in paths:

if p[‘id’] not in ["State_Lines", "separator"]:

# pass

try:

rate = unemployment[p[‘id’]]

except:

continue

# Linear scale

if rate > 10:

color_class = 5

elif rate > 8:

color_class = 4

elif rate > 6:

color_class = 3

elif rate > 4:

color_class = 2

elif rate > 2:

color_class = 1

else:

color_class = 0

color = colors[color_class]

p[‘style’] = path_style + color

print soup.prettify()

把上面的文件保存在与地图、失业率数据相同的文件夹下,然后在Terminal(Mac)中打开对应的存储路径,再输入:

python colorize_svg.py > us_unemployment_map.svg

怎么样,顺利完成后还是很开心的。SVG可以在illustrator中随意编辑,发挥去吧,少年:)

前面我们介绍了一些数据获取、分析与表达的方法,这里面的内容非常广阔,主页菌也只是了解一点点,更多的内容有待大家在实践中挖掘。作为这个系列的最后一篇,我们在这里说一下数据分析过程中可能需要注意的点,另外提供一些扩展阅读资源。

1.5 Tips | 一些可能需要注意的点:

Scale | 尺度问题:

不同的问题在不同尺度上分析,得到的结论可能是不同的。

Mapping Totals vs. Mapping Rates

注意在地图上要表达的是总量概念还是比率概念。总量概念往往有population dependence。(哪儿人多反应的现象总是多的。)

【深度教程】数据的获取、分析与表达

【深度教程】数据的获取、分析与表达

(例如,上面两个图分别是住房空置数量,和住房空置率,两张图反应的问题是很不相同的。Photo Credit: Anthony C. Robinson

Correlation vs. Causation

相关和因果是两回事,相关并不代表因果,很有可能有“伪相关”变量的存在。

Population Dependence:

Cause maps of raw values to always highlight heavily populated places

编码问题

尽量用csv格式而不是xls, 另外,中文汉字可能存在编码问题,注意编码格式。

1.6 进一步学习 | Reference:

Data:

OpenStreetMap: http://www.openstreetmap.org/

哥伦比亚大学Socioeconomic data and applications center (SEDAC): http://sedac.ciesin.columbia.edu/data/sets/browse

国家统计局:http://www.stats.gov.cn/

香港数据: http://www.gov.hk/en/theme/psi/datasets/

United Nations http://data.un.org/

美国数据:http://www.data.gov/ http://www.census.gov/

芝加哥数据:http://thechangelog.com/the-city-of-chicago-is-on-github/

英国数据:http://data.gov.uk/

伦敦数据:http://data.london.gov.uk/

法国数据:http://data.gouv.fr/

德国数据:http://www.govdata.de/

澳大利亚数据:http://data.gov.au/

日本数据:http://www.data.go.jp/

Ghana: http://data.gov.gh

其它国家: http://www.data.gov/opendatasites

历史地理:复旦哈佛数据集(禹贡) http://www.fas.harvard.edu/~chgis/data/chgis/downloads/v4/datasets/index.html

人口面板数据:北大,西南财经的家庭跟踪调查数据

Collections by data scientists

Hilary Mason http://bitly.com/bundles/hmason/1

Peter Skomoroch https://delicious.com/pskomoroch/dataset

Jeff Hammerbacher http://www.quora.com/Jeff-Hammerbacher/Introduction-to-Data-Science-Data-Sets

Gregory Piatetsky-Shapiro http://www.kdnuggets.com/gps.html

http://blog.mortardata.com/post/67652898761/6-dataset-lists-curated-by-data-scientists

More specialized collections (http://jtleek.com/modules/03_GettingData/04_05_dataResources/#1)

Maps:

Home

Spatial.ly http://spatial.ly/r/

http://axismaps.com/portfolio.php

http://www.qgis.org/en/site/

http://developers.cartodb.com/tutorials.html

Code:

http://www.pythonchallenge.com/

http://www.codecademy.com/tracks/python

原文始发于微信公众号(PPV课数据科学社区):【深度教程】数据的获取、分析与表达

原创文章,作者:ppvke,如若转载,请注明出处:http://www.ppvke.com/archives/30954

联系我们

4000-51-9191

在线咨询:点击这里给我发消息

工作时间:周一至周五,9:30-18:30,节假日休息