您的位置:首页 > 职场人生

程序员看数据分析

2014-04-06 20:38 507 查看
“世上有三种谎言:谎言、该死的谎言和统计” ------这是一句著名的西方谚语,其中让统计有如此名声的非平均值莫属了,可见数据分析并不能只是简单地求和、求平均。 作为程序员现在也开始接触到大量数据,也需要有数据分析的工作。比如在发布前进行一系列的测试,对测试结果进行分析,以便决定能否正式上线。

本人不是学习统计的,这里只是总结一下工作中使用R进行数据可视化分析的经验。概括为三个步骤:
1. 相关性分析
2. 汇总分析及验证
3. 数据追踪

零. 数据准备

在有数据之前,一定有这个过程,包括目的的定义、指标的定义、代码实现和数据收集。

依不同的统计目的,要么是先有明确分析目标,可以准确的设定KPI。要么是设定一些汇总性的指标,先汇总再分析。数据准备可以依次从小批量数据开始,写完代码后,自行使用自动化的脚本操作程序运行一段时间,完成数据收集。如果数据经分析达到要求后再逐步扩大范围。

一.变量的相关性分析

拿到数据后,如果是上面有明确目标的统计指标,表示变量关系是清楚的,可以跳过这一步骤。

数据相关性分析主要找到哪些变量间具有相关性,即变量间存在着相互影响的联系。

我主要使用三种方式: 散点图、相关性矩阵(Correlation matrix)和簇分类:

散点图

下面两张散点图分别是网络延迟与请求结束时间(左图),以及与带宽的关系(右图), 可以看到明显左图显示出网络延迟与结束时间有正相关性,而与带宽基本没有关系。



相关性矩阵

当同时观察多个变量间的关系时,可以使用相关性矩阵。 在R里使用如下的语句:
library(corrgram)
corrgram(data,order=T,lower.panel=panel.shade,upper.panel=panel.pie,text.panel=panel.txt)

图中左下角颜色越蓝的表示越有正相关性,越红的则是有负相关性。右上角则以饼图的大小反应相关系数的大小。



**相关系数

下面这样可以查看实际相关系数的取值:
> cor(testingData[c('rt','finish','bandwidth')])
rt finish bandwidth
rt 1.0000000 0.73284276 -0.17238241
finish 0.7328428 1.00000000 -0.05703875
bandwidth -0.1723824 -0.05703875 1.00000000

在<<R in Action>>中还介绍了其它的方法,比如这个Scatter Plot Matrix:
pairs(~start+finish+rt+bandwidth,data=testingData,main='Scatter Plot Matrix')



以簇分类

这种方法我很少使用,可以参考使用<<几个有用的R小函数>>第10项。



二. 汇总分析

这个过程主要是对具体指标进行量化分析,包括汇总分析、数据分布、变化趋势之类的。而数据最核心的意义在于比较,所以需要多维度同时观察。

汇总时不单要看平均数,更要使用中位数+标准差来观察。中位数反应出数据集中在哪里,而标准差则反应出数据的发散程度。先以summary指令就可以看到中位数、平均数等信息。
summary(testingData$finish)
Min. 1st Qu. Median Mean 3rd Qu. Max.
38 1458 5172 7662 10450 30610

sd函数给出标准差:
sd(testingData$finish)
[1] 7964.377

标准差

如果需要将标准差可视化可以使用下面的代码:
library(aspace)
data2<-data[c('a','b')]
plot(data2, xlab="", ylab="", main="Connected", type="n")
calc_sde(id=1,points=data2);
plot_sde(plotnew=FALSE, plotcentre=TRUE, centre.col="red", centre.pch="*", sde.col="red",sde.lwd=1,titletxt="", plotpoints=TRUE,points.col="black")




箱形图

上面的数据以图形化来看就是一个箱形图 [R指令:boxplot(testingData$finish) ]:



上面的黑圈表示存在大量的'异常值",是不是异常需要进一步分析。

如果需要进行分组查看,比如以不同的bandwidth来观察,则像下面这样:
[R指令boxplot(testingData$dataSize~testingData$bandwidth)]



可以看到随着带宽的增加,加载的数据量有上升的趋势。
*这里同样注意那些异常点并不是真的异常点,一定要从数据分布的角度来判断。但不并影响从中位数及标准差对数据进行判断。

数据在整体中的占比

观察数据在整体中的占比使用饼形图是最为直观了,在R中也很简单,为了方便,我封装了一个函数:
showPieChart<-function(slices,labels,title){
  slices<-asNumeric(slices)
  pct <- round(slices/sum(slices)*100)
  lbls <- paste(labels, pct) 
  lbls <- paste(lbls,"%",sep="") 
  pie(slices, labels = lbls, main=title)
}

asNumeric <- function(x) as.numeric(as.character(x))




数据分布

数据分布中典型使用的是density distribution和累积分布(CDF), 在R里最简单就是通过plot(density(data$field))或者hist就可以绘制出数据的density或frequency distribution了,比如
hist(all_data$dataSize,breaks=50,freq=T,col='green',main='Histogram') #freq=T表示显示的是频率分布,为F则为密度(density)分布:




breaks参数很灵活,既可以直接指数分段的数量,也可以自定义一个数据段,可以试一下这段代码:
customBreaks = c(100,500,1000,2000,5000,max(data))
hist(data,breaks=customBreaks,xaxt='n',col='green',main='Histogram with customized breaks')
axis(1,labels=customBreaks,at=customBreaks,las=2)
效果:



下面这个是使用sm包的sm.density.compare函数,针对不同的线程,绘制其数据量的分布,可以看到各个线程被平均分配了,所以下载的数据量变化不大。



R代码如下:
library(sm)
sm.density.compare(data$dataSize,data$threads,xlab='datasize vs. threads')

累积分布

累积分布可以方便的看出低于某个值时的总体占比,比如我们说99%的用户只访问过5次,表示访问次数小于等于5的占比为99%,如果使用上面的图,岂不要累加一下。
下图就是一个累积分布:



为了方便,我特别加了几处占比的输出。代码在这里:<<几个有用的R小函数>>

数据对比

在进行对比时,可以灵活地使用R的表达式,比如在数据一栏改为data$A~data$B, 就是要看data中A数据相对于B的关系,这在箱形图上已经应用了一次。 也可以使用<<几个有用的R小函数>>第9项目说明的方法在柱形图中同示显示多笔数据。



下面这个更为常用:
plot(0,type='n',xlim=c(0,10),ylim=c(0,10)) # 新建一个空白绘图, type='n'表示不绘制
points(data1$a) #绘制a
lines(data1$a) #继续在上面绘制连线
points(data2$a,col='red') #继续绘制b点
lines(data2$a,col='red')

这样绘制data1及data2的代码可以抽成函数完成了。

下面效果:



使用SQL语句

如果习惯了SQL语句,可能会觉得R里的分类汇总太麻烦,这样可以选择使用sqldf包,一样能用SQL语句操作一个data frame. 比如:
library(sqldf)
sqldf('select avg(size) as avg_size, category from data group by category')

*在R里的aggregate也可以达到这个效果:
aggregate(data$size,list(data$category),FUN=mean) 有同样的效果。

三. 数据追踪

数据之间的对比可以用来追踪数据的变化,及时发现异常问题。 如果将数据分析的脚本同数据采集的接口结合起来就可以达成这一点。

R语言可以使用RScript在终端下执行脚本,文字输出没有问题,绘图也可以直接输出到图片文件中。比如:
png('monitor.png')
plot(…..)
dev.off()

这样就会将图形化结果输出到monitor.png中保存。

同时可以接受不同的参数,如:
args <- commandArgs(trailingOnly = TRUE)
if(length(args)<1) {
print("Wrong parameters!",quote = F)
} else {
#do something
}

数据分析的结果一定要有验证,数据本身虽然没有态度,但负责数据生成以及分析的人却是有态度的,所以要慎重。

转载请注明出处: http://blog.csdn.net/horkychen
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: