分类目录归档:数据获取与预处理

数据获取的途径方式及过滤清洗等

分析的前提—数据质量3

data-correcting  前面的两篇文章——分析的前提—数据质量1分析的前提—数据质量2分别介绍了通过Data Profiling的方法获取数据的统计信息,并使用Data Auditing来评估数据是否存在质量问题,数据的质量问题可以通过完整性、准确性和一致性三个方面进行审核。这篇文章介绍最后一块内容——数据修正(Data Correcting)

  数据审核帮助我们发现数据中存在的问题,而这些问题有时候可以利用一些方法就行修正,从而提升数据的整体质量,数据修正就是为了完成这个任务,可以从以下几个方面进行修正:

填补缺失值

  对于记录缺失的问题,最简单的办法就是数据回补。一般而言统计指标数据缺失可以从原始数据中重新统计获取,而原始数据缺失可以从抽取的数据源或者备份数据中回补。如果原始数据完全丢失,基本就回天无力了。

  对于字段值的缺失,很多资料都会介绍使用一些统计学的方法进行修补,其实就是对缺失值的预测或者估计,一般会使用平均数、众数、前后值取平均等方法,或者使用回归分析的方法拟合指标的变化趋势后进行预测。这些方法在缺失值无法使用其他途径找回或者重新统计计算,并且在缺失值有变化规律可循的前提下都是可取的,当某天的指标值丢失时可以通过这类方法根据前几天的数据来预估该天的数值。但很多时候网站分析中如果底层的日志存在缺失值,我们很难预测具体的缺失值,因为访问的细节几乎是无迹可寻的,所以对于访问记录存在缺失值并且这些字段的缺失会明显影响一些统计指标的计算时,最简单的方法就是舍弃该记录,但这种直接过滤掉缺失记录的方法一些只会用于访问日志等不需要非常精确的数据上,如果是网站的运营、交易等这些需要保证完全计算准确的数据绝对是不能直接舍弃的,而且对于访问日志中缺失或者异常记录的过滤也需要基于对这类数据的统计基础上,一般的原则是不太重要的字段如果缺失或者异常的记录占比小于1%或者5‰的情况下可以选择过滤这些记录,如果占比比较高,需要进一步排查日志记录是否存在问题。

删除重复记录

  数据集里面某些字段的值必然是唯一的,比如按天统计的指标值中的日期字段,用户信息表的用户ID等,这些需要保证唯一的规则可以对数据库设置唯一约束,但我们在做ETL处理时,有时为了保证数据加载全过程可以不因为违反唯一约束而中断(有时Load的过程需要较长的时间或处理成本,ETL需要有容错能力以保证整个过程不被中断)会先忽略重复记录,待整个ETL过程结束后再对需要保证唯一的字段进行去重处理。

  这些重复记录可以比对Data Profiling中数据统计信息的唯一值个数和记录总数是否一致进行审核,而进行修正的最简单办法就是重复记录仅保留一条,删除其他记录。这个需要根据现实情况,有时也可能使用把重复记录的统计量相加的方法进行去重。

转化不一致记录

  数据的转化是数据仓库抽取数据过程中最常见的处理,因为数据仓库“集成性”的特征,需要把来自多个数据源的数据集中存入数据仓库,而不同数据源对某些含义相同的字段的编码规则会存在差异,比如用户ID,虽然是相同的用户,但可能A系统的ID是u1001,B系统是1001,C系统是100100,来源于这三套系统的用户ID就需要统一,比如我们将A数据源的u前缀去除,C系统ID除100后统一成B系统的编码方式一起导入数据库;即使是来源于同一套日志,也可能存在记录的不一致,比如之前遇到较早发布的产品版本记录的日志中移动操作系统是Android,而版本更新后记录改成了android,新老版本的日志打到了一起,于是也会涉及数据的转化,但这种记录的不一致性无疑会增加ETL的处理成本。

  上面举例的转化规则是比较简单的,在数据仓库的ETL处理数据转化时可能会遇到一些很BT的规则,这个时候最关键的还是对数据源记录方式足够的熟悉,这样才能保证进入数据仓库的数据是一致的。最好的做法就是数据仓库的开发工程师与其他前台系统的开发人员能事先约定一套统一的数据记录和编码的方式,这样可以减少后期的协调沟通和转化处理成本。

处理异常数据

  异常数据大部分情况是很难修正的,比如字符编码等问题引起的乱码,字符被截断,异常的数值等,这些异常数据如果没有规律可循几乎不可能被还原,只能将其直接过滤。

  有些数据异常则可以被还原,比如原字符中参杂了一些其他的无用字符,可以使用取子串的方法,用trim函数可以去掉字符串前后的空格等;字符被截断的情况如果可以使用截断后字符推导出原完整字符串,那么也可以被还原,比如移动操作系统的记录一般包括Symbian、Android、iPhone、BlackBerry等,如果某些记录的是And,那么可以被还原成Android,因为其他的移动操作系统被截断不可能出现And这种记录。数值记录中存在异常大或者异常小的值是可以分析是否数值单位差异引起的,比如克和千克差了1000倍,美元和人民币存在汇率的差异,时间记录可能存在时区的差异,百分比用的是小于1的小数还是已经乘了100等等,这些数值的异常可以通过转化进行处理,数值单位的差异也可以认为是数据的不一致性,或者是某些数值被错误的放大或缩小,比如数值后面被多加了几个0导致了数据的异常。

  最后,总结一下数据可修正的前提:1) 数据质量的问题可以通过Data Auditing的过程被审核出来;2) 数据的问题必须有迹可循,可以通过趋势进行预测或者可以通过一些规则进行转换还原。否者,对于异常数据只能直接进行删除丢弃,但进行数据过滤之前必须评估异常记录的比例,当占比过高时需要重新审核原始数据的记录方式是否存在问题。

分析的前提—数据质量2

  前一篇文章介绍了数据质量的一些基本概念,数据质量控制作为数据仓库的基础环节,是保障上层数据应用的基础。数据质量保证主要包括数据概要分析(Data Profiling)数据审核(Data Auditing)数据修正(Data Correcting)三个部分,前一篇文章介绍了Data Profiling的相关内容,从Data Profiling的过程中获得了数据的概要统计信息,所以下面就要用这些数据统计信息来审核数据的质量,检查数据中是否存在脏数据,所以这一篇主要介绍数据审核(Data Auditing)的内容。

数据质量的基本要素

  首先,如何评估数据的质量,或者说怎么样的数据才是符合要求的数据?可以从4个方面去考虑,这4个方面共同构成了数据质量的4个基本要素。

data-quality-elements

完整性

  数据的记录和信息是否完整,是否存在缺失的情况。

  数据的缺失主要有记录的缺失和记录中某个字段信息的缺失,两者都会造成统计结果的不准确,所以完整性是数据质量最基础的保障,而对完整性的评估相对比较容易。

一致性

  数据的记录是否符合规范,是否与前后及其他数据集合保持统一。

  数据的一致性主要包括数据记录的规范和数据逻辑的一致性。数据记录的规范主要是数据编码和格式的问题,比如网站的用户ID是15位的数字、商品ID是10位数字,商品包括20个类目、IP地址一定是用”.”分隔的4个0-255的数字组成,及一些定义的数据约束,比如完整性的非空约束、唯一值约束等;数据逻辑性主要是指标统计和计算的一致性,比如PV>=UV,新用户比例在0-1之间等。数据的一致性审核是数据质量审核中比较重要也是比较复杂的一块。

准确性

  数据中记录的信息和数据是否准确,是否存在异常或者错误的信息。

  导致一致性问题的原因可能是数据记录的规则不一,但不一定存在错误;而准确性关注的是数据记录中存在的错误,比如字符型数据的乱码现象也应该归到准确性的考核范畴,另外就是异常的数值,异常大或者异常小的数值,不符合有效性要求的数值,如访问量Visits一定是整数、年龄一般在1-100之间、转化率一定是介于0到1的值等。对数据准确性的审核有时会遇到困难,因为对于没有明显异常的错误值我们很难发现。

及时性

  数据从产生到可以查看的时间间隔,也叫数据的延时时长。

  虽然说分析型数据的实时性要求并不是太高,但并不意味了就没有要求,分析师可以接受当天的数据要第二天才能查看,但如果数据要延时两三天才能出来,或者每周的数据分析报告要两周后才能出来,那么分析的结论可能已经失去时效性,分析师的工作只是徒劳;同时,某些实时分析和决策需要用到小时或者分钟级的数据,这些需求对数据的时效性要求极高。所以及时性也是数据质量的组成要素之一。

Data Auditing

data-auditing  基于数据质量的4个要素,可以对数据进行审核,以评估数据是否满足完整性、一致性、准确性和及时性这4方面的要求,其中数据的及时性主要跟数据的同步和处理过程的效率相关,更多的是通过监控ETL任务的方式来保证数据的及时性,所以这里的数据审核主要指的是评估数据的完整性、一致性和准确性。

完整性

  我们从Data Profiling得到的数据统计信息里面看看哪些可以用来审核数据的完整性。首先是记录的完整性,一般使用统计的记录数和唯一值个数。比如网站每天的日志记录数是相对恒定的,大概在1000万上下波动,如果某天的日志记录数下降到了只有100万,那很有可能记录缺失了;或者网站的访问记录应该在一天的24小时均有分布,如果某个整点完全没有用户访问记录,那么很有可能网站在当时出了问题或者那个时刻的日志记录传输出现了问题;再如统计访客的地域分布时,一般会包括全国的32个省份直辖市,如果统计的省份唯一值个数少于32,那么很有可能数据也存在缺失。

  完整性的另一方面,记录中某个字段的数据缺失,可以使用统计信息中的空值(NULL)的个数进行审核。如果某个字段的信息理论上必然存在,比如访问的页面地址、购买的商品ID等,那么这些字段的空值个数的统计就应该是0,这些字段我们可以使用非空(NOT NULL)约束来保证数据的完整性;对于某些允许空的字段,比如用户的cookie信息不一定存在(用户禁用cookie),但空值的占比基本恒定,比如cookie为空的用户比例通常在2%-3%,我们同样可以使用统计的空值个数来计算空值占比,如果空值的占比明显增大,很有可能这个字段的记录出现了问题,信息出现缺失。

一致性

  如果数据记录格式有标准的编码规则,那么对数据记录的一致性检验比较简单,只要验证所有的记录是否满足这个编码规则就可以,最简单的就是使用字段的长度、唯一值个数这些统计量。比如对用户ID的编码是15位数字,那么字段的最长和最短字符数都应该是15;或者商品ID是P开始后面跟10位数字,可以用同样的方法检验;如果字段必须保证唯一,那么字段的唯一值个数跟记录数应该是一致的,比如用户的注册邮箱;再如地域的省份直辖市一定是统一编码的,记录的一定是“上海”而不是“上海市”、“浙江”而不是“浙江省”,可以把这些唯一值映射到有效的32个省市的列表,如果无法映射,那么字段通不过一致性检验。

  一致性中逻辑规则的验证相对比较复杂,很多时候指标的统计逻辑的一致性需要底层数据质量的保证,同时也要有非常规范和标准的统计逻辑的定义,所有指标的计算规则必须保证一致。我们经常犯的错误就是汇总数据和细分数据加起来的结果对不上,导致这个问题很有可能的原因就是数据在细分的时候把那些无法明确归到某个细分项的数据给排除了,比如在细分访问来源的时候,如果我们无法将某些非直接进入的来源明确地归到外部链接、搜索引擎、广告等这些既定的来源分类,但也不应该直接过滤掉这些数据,而应该给一个“未知来源”的分类,以保证根据来源细分之后的数据加起来还是可以与总体的数据保持一致。如果需要审核这些数据逻辑的一致性,我们可以建立一些“有效性规则”,比如A>=B,如果C=B/A,那么C的值应该在[0,1]的范围内等,数据无法满足这些规则就无法通过一致性检验。

准确性

  数据的准确性可能存在于个别记录,也可能存在于整个数据集。如果整个数据集的某个字段的数据存在错误,比如常见的数量级的记录错误,这种错误很容易发现,利用Data Profiling的平均数和中位数也可以发现这类问题。当数据集中存在个别的异常值时,可以使用最大值和最小值的统计量去审核,或者使用箱线图也可以让异常记录一目了然。

  还有几个准确性的审核问题,字符乱码的问题或者字符被截断的问题,可以使用分布来发现这类问题,一般的数据记录基本符合正态分布或者类正态分布,那么那些占比异常小的数据项很可能存在问题,比如某个字符记录占总体的占比只有0.1%,而其他的占比都在3%以上,那么很有可能这个字符记录有异常,一些ETL工具的数据质量审核会标识出这类占比异常小的记录值。对于数值范围既定的数据,也可以有效性的限制,超过数据有效的值域定义数据记录就是错误的。

  如果数据并没有显著异常,但仍然可能记录的值是错误的,只是这些值与正常的值比较接近而已,这类准确性检验最困难,一般只能与其他来源或者统计结果进行比对来发现问题,如果使用超过一套数据收集系统或者网站分析工具,那么通过不同数据来源的数据比对可以发现一些数据记录的准确性问题。

  上面已经从Data Profiling的统计信息中,通过Data Auditing发现了数据质量上存在的一些问题,那么接下来就要针对这些问题对数据进行清洗和修正,也就是下一篇文章中要介绍的内容——Data Correcting,数据修正。

分析的前提—数据质量1

data-profiling  数据质量(Data Quality)是数据分析结论有效性和准确性的基础也是最重要的前提和保障。数据质量保证(Data Quality Assurance)是数据仓库架构中的重要环节,也是ETL的重要组成部分。

  我们通常通过数据清洗(Data cleansing)来过滤脏数据,保证底层数据的有效性和准确性,数据清洗一般是数据进入数据仓库的前置环节,一般来说数据一旦进入数据仓库,那么必须保证这些数据都是有效的,上层的统计聚合都会以这批数据作为基础数据集,上层不会再去做任何的校验和过滤,同时使用稳定的底层基础数据集也是为了保证所有上层的汇总和多维聚合的结果是严格一致的。但当前我们在构建数据仓库的时候一般不会把所有的数据清洗步骤放在入库之前,一般会把部分数据清洗的工作放在入库以后来执行,主要由于数据仓库对数据处理方面有自身的优势,部分的清洗工作在仓库中进行会更加的简单高效,而且只要数据清洗发生在数据的统计和聚合之前,我们仍然可以保证使用的是清洗之后保留在数据仓库的最终“干净”的基础数据。

  前段时间刚好跟同事讨论数据质量保证的问题,之前做数据仓库相关工作的时候也接触过相关的内容,所以这里准备系统地整理一下。之前构建数据仓库基于Oracle,所以选择的是Oracle提供的数据仓库构建工具——OWB(Oracle Warehouse Builder),里面提供了比较完整的保证数据质量的操作流程,主要包括三块:

  1. Data Profiling
  2. Data Auditing
  3. Data Correcting

Data Profiling

  Data Profiling,其实目前还没找到非常恰当的翻译,Oracle里面用的是“数据概要分析”,但其实“Profiling”这个词用概要分析无法体现它的意境,看过美剧Criminal Minds(犯罪心理)的同学应该都知道FBI的犯罪行为分析小组(BAU)每集都会对罪犯做一个Criminal Profiling,以分析罪犯的身份背景、行为模式、心理状态等,所以Profiling更多的是一个剖析的过程。维基百科对Data Profiling的解释如下:

Data profiling is the process of examining the data available in an existing data source and collecting statistics and information about that data.

  这里我们看到Data Profiling需要一个收集统计信息的过程(这也是犯罪心理中Garcia干的活),那么如何让获取数据的统计信息呢?

  熟悉数据库的同学应该知道数据库会对每张表做Analyze,一方面是为了让优化器可以选择合适的执行计划,另一方面对于一些查询可以直接使用分析得到的统计信息返回结果,比如COUNT(*)。这个其实就是简单的Data Profiling,Oracle数据仓库构建工具OWB中提供的Data Profiling的统计信息更加全面,针对建立Data Profile的表中的每个字段都有完整的统计信息,包括:

  记录数、最大值、最小值、最大长度、最小长度、唯一值个数、NULL值个数、平均数和中位数,另外OWB还提供了six-sigma值,取值1-6,越高数据质量越好,当six-sigma的值为7的时候可以认为数据质量近乎是完美的。同时针对字段的唯一值,统计信息中给出了每个唯一值的分布频率,这个对发现一些异常数据是非常有用的,后面会详细介绍。

  看到上面这些Data Profile的统计信息,我们可能会联想到统计学上面的统计描述,统计学上会使用一些统计量来描述一些数据集或者样本集的特征,如果我们没有类似OWB的这类ETL工具,我们同样可以借助统计学的这些知识来对数据进行简单的Profiling,这里不得不提一个非常实用的图表工具——箱形图(Box plot),也叫箱线图、盒状图。我们可以尝试用箱形图来表现数据的分布特征:

box-plot

  箱线图有很多种表现形式,上面图中的是比较常见的一种箱线图。一般中间矩形箱的上下两边分别为数据集的上四分位数(75%,Q3)和下四分位数(25%,Q1),中间的横线代表数据集的中位数(50%,Media,Q2),同时有些箱线图会用“+”来表示数据集的均值。箱形的上下分别延伸出两条线,这两条线的末端(也叫“触须”)一般是距离箱形1.5个IQR(Q3-Q1,即箱形的长度),所以上端的触须应该是Q3+1.5IQR,下端的触须是Q1-1.5IQR;如果数据集的最小值大于Q1-1.5IQR,我们就会使用最小值替换Q1-1.5IQR作为下方延伸线末端,同样如果最大值小于Q3+1.5IQR,用最大值作为上方延伸线的末端,如果最大或者最小值超出了Q1-1.5IQR到Q3+1.5IQR这个范围,我们将这些超出的数据称为离群点(Outlier),在图中打印出来,即图中在上方触须之外的点。另外,有时候我们也会使用基于数据集的标准差σ,选择上下3σ的范围,或者使用置信水平为95%的置信区间来确定上下边界的末端值。

  其实箱线图没有展现数据集的全貌,但通过对数据集几个关键统计量的图形化表现,可以让我们看清数据的整体分布和离散情况。

  既然我们通过Data profiling已经可以得到如上的数据统计信息,那么如何利用这些统计信息来审核数据的质量,发现数据可能存在的异常和问题,并对数据进行有效的修正,或者清洗,进而得到“干净”的数据,这些内容就放到下一篇文章吧。

NoJS的网站数据统计

No JavaScript  目前主流的网站分析工具都是通过JavaScript来实现数据的获取的,如Google Analytics就是通过在网页中嵌入一段JS代码,当该网页被浏览时,JS代码被加载,就会向Google Analytics的数据收集服务器发送用户浏览该网页的相应数据,包括时间、IP、页面URL、Session、Cookie等信息,Google Analytics后台通过处理和计算这些收集到的数据,将每天的网站统计结果展示在WEB报表上。

  但是不是所有的页面都支持JS的,让我开始关注到这个问题的原因就是博客的Feed页面。我发现我的博客在AWstats上统计到的数据显示我的Feed页面是我的博客中PV最高的页面,如下图:

AWStats-Feed

  但是在Google Analytics的Content统计中却找不到Feed页面的任何数据,当然AWStats是通过网站日志实现统计的,包括搜索引擎爬虫和RSS订阅器的抓取记录,PV偏高也可以理解;但除了搜索引擎爬虫和RSS订阅器外,用户也会浏览Feed页面,GA即使无法统计到网络爬虫,但没有Feed页面的任何统计数据也是不正常的,最后终于找到了问题所在,也许大家都已经想到了,Feed页面其实是以XML的形式存在的,其中无法嵌入JS代码,于是GA上无法统计到相关的数据。也许我们在其他地方也会遇到此类无法加载JS代码的统计情况,于是我开始寻找不使用JavaScript实现使用Google Analytics实现统计的方法……

  Google Analytics without Javascript(简称 NoJSStats)是一款使用 Google Analytics 的第三方统计工具,部署在Google App Engine上授权免费使用,通过在页面嵌入一个1像素的图片来统计页面流量,主要用于在不支持 Javascript 的环境下使用 Google Analytics 统计服务。

NoJSStats的用途

  • 统计不支持JS的手机浏览器的访问;
  • 统计“禁用JS”功能的浏览器的访问;
  • 统计第三方平台上的访问流量,如非独立博客、淘宝店铺、论坛等;
  • 统计博客的 Feed 访问;
  • 统计 Email 的打开和浏览情况(这个对掌握直邮营销的效果很有用)。

NoJSStats的使用

  如果你喜欢翻墙,可以直接参考上面的NoJSStats页面链接。NoJSStats的使用十分简单,就是在你想要统计的页面或者模块中嵌入一个1像素的透明图片即可,不会影响正常的页面展现和浏览。图片的URL链接地址是:

http://nojsstats.appspot.com/你的GoogleAnalytics账号/网站主页URL

  比如我的博客的图片获取链接是:

http://nojsstats.appspot.com/UA-13232982-1/webdataanalysis.net

  你可以在想要获得统计数据的地方嵌入该图片,如:

网页HTML:<img src=”http://nojsstats.appspot.com/UA-123456/mywebsite.com” />

论坛:[img]http://nojsstats.appspot.com/UA-123456/mywebsite.com[/img]

CSS:body{ background: url(“http://nojsstats.appspot.com/UA-123456/mywebsite.com”); }

  如果你的网站使用SSL加密,那么请使用以下的图片链接:

httpS://nojsstats.appspot.com/UA-123456/yourwebsite.com

  使用NoJSStats可以统计博客Feed的文章被浏览的情况,只要修改Wordpress的主题目录下的functions.php的文件,加入如下代码:

<?php
add_filter('the_content', 'google_analytics_for_feed',99);
function google_analytics_for_feed($content){
    if (is_feed()) {   //只在feed输出中嵌入图片
        $content.= '<img src="http://nojsstats.appspot.com/UA-13232982-1/webdataanalysis.net" alt="" />';
    }
    return $content;
}
?>

  我们可以在Google Analytics的报表上面看到Feed页面的相关统计数据了:

NoJS-GA-FeedStat

  这里需要注意的是上面这段代码实现了在Feed中的每篇文章内容的最后添加了透明图片,所以当任何一篇文章被展示时,Google Analytics上面就会增加一个Pageview,所以这里的Pageview不能认为是页面被浏览次数,而是浏览的文章总数。当一个页面或某个RSS阅读器中显示5篇Feed模板上的文章时,那么该页面被浏览一次其实Pageviews就会加5。同时网络爬虫和RSS的抓取不会发送图片请求,所以不会被统计在内,所以通过NoJSStats统计得到的数据基本可以认为是用户的浏览行为,并且包括用户从RSS阅读器阅读文章或其他网站从Feed上转载文章的浏览情况,这些数据对于博客而言都是十分具有参考价值的。

NoJSStats的实现机制

  通过上面的介绍和使用,也许大家已经意识到了NoJSStats的实现机制就是网站分析中点击流数据获取的方式之一——Web Beacons,即在页面中嵌入一个1像素的透明图片,当该页面被浏览时,图片就会被请求加载,于是在后端的服务器日志中就会记录该图片的请求日志,如打开我的博客首页,右上角的Logo图片就会被请求,这样就可以获得如下的日志记录:

60.216.235.23 – - [09/May/2010:15:09:12 +0800] “GET /wp-content/themes/cordobo-green-park-2/img/logo.png HTTP/1.1″ 200 35715 “http://webdataanalysis.net/” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; TheWorld)”

  请求类型是GET,请求的资源就是该图片的URI,而后面的referrer中记录了我的博客的首页URL,即用户浏览的页面(关于网站日志格式的相关资料可以参考我之前的一篇文章——WEB日志格式),所以只要统计出现这类图片请求的日志记录就能获得嵌入图片的各页面被浏览的情况,Web Beacons就是通过这种方式来获取用户的浏览数据的。需要注意的是,Web Beacons方式是无法获取浏览的来源页面信息的,除非在图片的URI请求中带上referrer的参数,类似.gif?ref=www.google.com。

  而NoJSStats还有一点让我比较迷惑的就是既然没有JS的支持,同时referrer字段又被浏览的当前页面占据,那么就无法区分用户浏览的session,也就是无法实现Visits的统计,但直接打开http://nojsstats.appspot.com/UA-13232982-1/webdataanalysis.net这个链接(很奇怪,这个没有被屏蔽),发现Google使用了URL重写,实际的请求地址是:

src=http://www.google-analytics.com/__utm.gif?utmwv=1&amp;utmn=80790672&amp;utmsr=-&amp;utmsc=-&amp;utmul=-&amp;utmje=0&amp;utmfl=-&amp;utmdt=-&amp;utmhn=webdataanalysis.net&amp;utmr=&amp;utmp=&amp;utmac=UA-13232982-1&amp;utmcc=__utma%3D82610576.209757388.1273508397.1273508397.1273586810.2%3B%2B__utmb%3D82610576%3B%2B__utmc%3D82610576%3B%2B__utmz%3D82610576.1273586810.2.2.utmccn%3D(direct)%7Cutmcsr%3D(direct)%7Cutmcmd%3D(none)%3B%2B__utmv%3D82610576.122.234.62.66%3B

  后面带了一大堆的参数,不知道这里面有没有将session和Cookie的信息写进去,希望对这方面有所研究的朋友能够解答我的疑问。

网站分析的数据来源

Data-Center   Avinash Kaushik在他的《Web Analytics》一书中将数据的来源分为4部分:点击流数据(Clickstream)、运营数据(Outcomes)、调研数据(Research/Qualitative)和竞争对手数据(Competitive Data)。点击流数据主要指的是用户浏览网站时产生的数据;Outcomes我更习惯叫做运营数据,主要指用户在网站中应用服务或者购买产品时记录下来的数据;调研数据主要是网站通过某些用户调研手段(线上问卷或者线下调研)获取的一些定性数据;Competitive Data直译为竞争对手数据可能不太合适,因为根据Avinash Kaushik的阐述,更像是跟网站有业务关系或竞争关系或存在某种利益影响的一切网站的可能的数据来源。

  在获取上述几类数据的同时,也许我们还可以从其他方面获取一些更为丰富的数据。下面是我对网站分析数据获取途径的整理:

网站内部数据

  网站内部数据是网站最容易获取到的数据,它们往往就存放在网站的文件系统或数据库中,也是与网站本身最为密切相关的数据,是网站分析最常见的数据来源,我们需要好好利用这部分数据。

服务器日志

  随着网站应用的不断扩张,网站日志不再局限于点击流的日志数据,如果你的网站提供上传下载、视频音乐、网页游戏等服务,那么很明显,你的网站服务器产生的绝不仅有用户浏览点击网页的日志,也不只有标准的apache日志格式日志,更多的W3C、JSON或自定义格式的输出日志也给网站分析提供了新的方向。

  网站分析不再局限于网页浏览的PV、UV,转化流失等,基于事件(Events)的分析将会越来越普遍,将会更多的关注用户在接受网站服务的整个流程的情况:上传下载是否完成,速度如何;用户是否观看的整部视频,视频的加载情况;及用户在玩网页游戏时的操作和体验分析等。Google Analytics已经支持了基于事件的分析——Event Tracking,通过JS的动作响应获取数据,但是还存在着一定的局限性。

网站分析工具

  当然,通过网站分析工具获得数据是一个最为简便快捷的方式,从原先的基于网站日志的AWStats、webalizer,到目前非常流行的基于JS Tags的Google Analytics、Omniture的SiteCatalyst,及JS和网站日志通吃的WebTrends。通过网站分析工具获得的数据一般都已经经过特殊计算,较为规范,如PV、UV、Exit Rate、Bounce Rate等,再配上一些趋势图或比例图,通过细分、排序等方法让结果更为直观。

  但通过网站分析工具得到数据也不远只这些,上面的这些数据也一样可以通过统计网站日志获得,但网站分析工具的优势在于其能通过一些嵌入页面的JS代码获得一些有趣的结果,如Google Analytics上的Overlay或者也叫Click Density——网站点击密度分布,及一些其它的网站分析工具提供的点击热图,甚至鼠标移动轨迹图。这些分析结果往往对网站优化和用户行为分析更为有效。

数据库数据

  对于一般的网站来说,存放于数据库中的数据可以大致分为3个部分:

  • 网站用户信息,一般提供注册服务的网站都会将用户的注册账号和填写的基本信息存放在数据库里面;
  • 网站应用或产品数据,就像电子商务的商品详细信息或者博客的文章信息,如商品信息会包含商品名称、库存数量、价格、特征描述等;
  • 用户在应用服务或购买产品时产生的数据,最简单的例子就是博客上用户的评论和电子商务网站的用户购买数据,购买时间、购买的用户、购买的商品、购买数量、支付的金额等。

  当然,这一部分数据的具体形式会根据网站的运营模式存在较大差异,一些业务范围很广,提供多样服务的网站其数据库中数据的组合会相当复杂。

其它

Customer-Service

  其它一切网站运营过程中产生的数据,有可能是用户创造,也有可能是网站内部创造,其中有一大部分我们可以称其为“线下数据(Offline Data)”。如用户的反馈和抱怨,可能通过网站的交流论坛,也有可能通过网站时公布的客服电话、即时通讯工具等,如果你相信“客户中心论”,那么显然对于这些数据的分析必不可少;另外一部分来源就是网站开展的线下活动,促销或推广,衡量它们开展的效果或投入产出,以便于之后更好地开展类似的线下推广。

外部数据

  网站分析除了可以从网站内部获取数据以外,通过互联网这个开放的环境,从网站外部捕获一些数据可以让分析的结果更加全面。

互联网环境数据

  即使你的网站只是一个很小的网站,但如果想让你的网站变得更好,或者不至于落后于互联网的前进脚步,那么建议你关注一下互联网的发展趋势。可以上Alexa查一下互联网中顶级网站的访问量趋势;看看comScore发布的数据或者艾瑞的数据分析报告;如果经营电子商务网站,那么刚刚上线的淘宝数据中心也许会让你感兴趣。

竞争对手数据

  时刻关注竞争对手的情况可以让你的网站不至于在竞争中落伍。除了在Alexa及一些其他的网站数据查询平台以外,直接从竞争对手网站上获取数据也是另外一条有效的途径,一般网站会出于某些原因(信息透明、数据展示等)将自己的部分统计信息展现在网站上,看看那些数据对于掌握你的竞争对手的情况是否有帮助。

合作伙伴数据

  如果你有合作的网站或者你经营的是一个电子商务网站,也许你会有相关的产品提供商、物流供应商等合作伙伴,看看他们能为你提供些什么数据。

用户数据

  尝试跟踪用户的脚步去看看他们是怎么评价你的网站的。如果你的网站已经小有名气,那么尝试在搜索引擎看看用户是怎么评价你的网站,或者通过Twitter、新浪微博等看看用户正在上面发表什么关于你的网站的言论。

  当然通过用户调研获取数据是另外一个不错的途径,通过网站上的调查问卷或者线下的用户回访,电话、IM调查,可用性实验测试等方式可以获取一些用户对网站的直观感受和真实评价,这些数据往往是十分有价值的,也是普通的网站分析工具所获取不到的。

  在分析网站的外部数据的时候,需要注意的是不要过于相信数据,外部数据相比内部数据不确定性会比较高。网站内部数据即使也不准确,但我们至少能知道数据的误差大概会有多大,是什么原因造成了数据存在误差。而外部数据一般都是有其他网站或机构公布的,每个公司,无论是数据平台、咨询公司还是合作伙伴都可能会为了某些利益而使其公布的数据更加可信或更具一定的偏向性,所以我们在分析外部数据是需要更加严格的验证和深入的分析。而对于用户调研中获取的数据,我们一般会通过统计学的方法检验数据是否可以被接受,或者是否满足一定的置信区间,这是进行数据分析前必须完成的一步。

从WEB日志到点击流

  我们平常在看网站分析相关文章的时候,时常会看到“点击流(Clickstream)”这个词,点击流数据是网站分析的主要来源。那么究竟什么是点击流数据,它又来源于何处,为什么它是网站分析的基础数据?关于这些问题的系统解释,推荐阅读《点击流数据仓库》这本书,这里先对这几个问题做下简单的回答。

  首先,点击流来源于何处?可能从文章标题就可以看出来了,点击流数据来源于网站日志,其实就是用户日常浏览你的网站时产生的日志信息(关于WEB日志,可以参阅这篇文章——WEB日志格式)。那为什么不直接叫网站浏览日志,而叫点击流数据呢?可以先看一下下面这张图:

clickstream

  从图上可以看出点击流这个概念更注重用户浏览网站的整个流程,网站日志中记录的用户点击就像是图上的“点”,而点击流更像是将这些“点”串起来形成的“线”。也可以把“点”认为是网站的Page,而“线”则是访问网站的Session。所以点击流数据是由网站日志中整理得到的,它可以比网站日志包含更多的信息,从而使基于点击流数据统计得到的结果更加丰富和高效。

  那么点击流数据是如何从WEB日志中扩展出来的呢?其实很简单,只要有Sessionid和站内Referrers就可以将这些“点”串联起来。其中Sessionid唯一地标识一条点击流,再通过Referrers确定这个Session中页面被依次访问的顺序,那么这条线就可以轻松地画出来了。

  通常我们会分两张表(数据库中)或两种格式的文件(文件系统中)来记录点击流数据,一张记录“点”的信息,另一张记录“线”的信息:

  线(Session)的信息:Sessionid(唯一标识符)、访问来源(Referrers)、进入页面(Entrance)、离开页面(Exit)、开始时间(Begin Time)、结束时间(End Time)、访问时长(Time on Site)、访问页面数(Depth of Visit)、访问用户(Cookie)……

  有没有发现,当你拥有这些信息时,很多网站分析度量的计算变简单了:来源(Sources)、进入页面(Entrances)、离开页面(Exits)可以直接获得,平均访问时间和平均浏览页面数也可以通过简单计算得到,连Bounce Rate的计算也变得简单了,只要选择那些访问页面数为1的“线”就行。

  点(Page)的信息:URL、点击时间(Hit Time)、页面停留时间(Time on Page)、位于Session的第几步(Step),Sessionid(在关系数据库中可以用于跟Session表的外键关联)……

track

  其实点的信息被简化了,当然你可以添加更多的信息,比如页面响应状态码,冗余访问用户的Cookie等。但是这里多了一个有意思的信息——Step,这个是基于Session的,通过Step你可以发现其实你已经追踪到了用户的访问足迹,这个信息在梳理网站的流程、计算转化率(Conversion Rate)的时候非常有用,也可以基于它做用户行为分析。

  其实这就是点击流,并没有那么复杂,但是可以注意到,当WEB日志转化成点击流数据的时候,很多网站分析度量的计算变得简单了,这就是点击流的“魔力”所在。基于点击流数据我们可以统计出许多常见的网站分析度量——网站分析的基本度量

WEB日志的作用和缺陷

log-file  Avinash Kaushik将点击流数据的获取方式分为4种:log files、web beacons、JavaScript tags和packet sniffers,其中包嗅探器(packet sniffers)比较不常见,最传统的获取方式是通过WEB日志文件(log files);而beacons和JavaScript是目前较为流行的方式,Google Analytics目前就是采用beacons+JavaScript来获取数据的,我们可以来简单看一下传统的网站日志和beacons+JavaScript方式各自的优缺点:

WEB日志文件

  优势:简单方便,不需要修改网页代码,可以自定义日志格式;较多的现成的日志分析工具的支持(AWStats、Webalizer等);获取网络爬虫数据的唯一途径;可以收集底层数据供反复的分析。

  缺陷:数据的质量较低,网站日志包含所有日志数据,包括CSS、图片、脚本文件的请求信息,所以过滤和预处理来提升数据质量必不可少;页面缓存导致浏览无日志记录,这个是比较致命的。

beacons+JavaScript

  优势:只需要在页面代码中操作,不需要配置服务器;数据的获取有较高的可控性,可以只在需要统计的页面植入代码;能够获取点击、响应等数据;不需要担心缓存等的影响,数据的准确度较高;可用第三方cookie实现多网站跟踪比较。

  缺陷:当浏览器禁止接收图片或者禁用JS时,都可能导致数据获取的失败;只在应用服务层操作,无法获取后台的数据;对图片、文件等请求信息的获取难度相对较大;过多地JS可能导致页面性能的下降,虽然这方面的影响一般可以忽略。

无论通过何种方式,最终数据都是通过日志文件来记录的,只是通过JS可以更容易控制想要获取的数据,并通过在URL带参数的方式记录到日志文件中共解析和统计。所以底层的数据形式无非就是记录在日志文件中的那几项,在WEB日志格式一文中,已经对网站日志的类型和组成做了基本的介绍,这里就再来解析下WEB日志中各项对网站数据分析的作用,以及存在的不确定性和缺陷。

WEB日志中各项的作用

  根据WEB日志的组成,下面来介绍下各项在网站数据统计和分析中的作用。其中IP一般在为记录cookie的情况下被用于识别唯一用户的标准,标识符和授权用户一般情况下都为空,而日期时间标识日志生成的时间戳,是一个必备信息。

请求(request)

  请求类型比较少会被用于统计,只有少数的统计表单提交情况是会被用到,而版本号对统计来书基本是无用的。

  请求的资源一般跟域名(domain,一般在包含子域名需要分开统计,或者多个站点的日志被收集到同一日志服务器是,会在网站日志里面自定义加入域名信息以区分)一起决定本次请求的具体资源,页面点击、图片获取或者其他。当然在URL后面加入一些自定义的参数可以获得一些特殊的统计数据,Google Analytics就是通过这种方式实现session和cookie的定义和获取的。

状态码(status)

   状态码比较常被用于一些请求响应状态的监控,301页面重定向或者404错误,统计这些信息可以有效地改进页面的设计,提高用户体验。

传输字节数(bytes)

  也比较少被用到,可以判断页面是否被完全打开,文件是否已被读取,操作是否被中断。但在动态页面无法判断。

来源页面(referrer)

  referer涉及的统计较为常见,一般是统计访问的来源类型、搜索引擎、搜索关键字等;同时也是点击流中串连用户访问足迹的依据。

用户代理(agent)

  识别网络爬虫;统计用户的系统、浏览器类型、版本等信息,为网站开发提供建议,分析各类浏览器的使用情况和出错概率等。

session和cookie

  关于session和cookie,可以参考session和cookie的辨析。session被用于标识一个连续的访问,用户统计visits这个度量;而cookie主要用于用户识别,也是统计Unique Visitor的依据。

  另外还有一种特殊的网站日志,即记录服务器的提示、警告及错误信息,这类日志可以被用于分析用户的错误。

日志的不准确性

  WEB日志在技术层面的获取方式及各类外部因素的影响使基于网站日志的数据分析会存在许多的不准确性,下面来介绍下WEB日志中那些项目可能造成数据的不准确,以及造成这些缺陷的原因。

客户端的控制和限制

  由于一些浏览网站的用户信息都是有客户端发送的,所以用户的IP、Agent都是可以人为设置的;另外cookie可以被清理,浏览器出于安全的设置,用户的可以在访问过程中限制cookie、referrer的发送。这些都会导致用户访问数据的丢失或者数据的不准确,而这类问题目前很难得到解决。

缓存

  浏览器缓存、服务器缓存、后退按钮操作等都会导致页面点击日志的丢失及referrer的丢失,目前主要的处理方法是保持页面信息的不断更新,可以在页面中添加随机数。当然如果你使用的JavaScript的方法,那么就不需要担心缓存的问题。

跳转

  一些跳转导致referrer信息的丢失,致使用户的访问足迹中断无法跟踪。解决方法是将referer通过URL重写,作为URL参数带入下一页面,不过这样会是页面的URL显得混乱。

代理IP、动态IP、局域网(家庭)公用IP

  IP其实准确性并不高,现在不止存在伪IP,而且局域网共享同一公网IP、代理的使用及动态IP分配方式,都可能使IP地址并不是与某个用户绑定的,所以如果有更好的方法,尽量不要使用IP来识别用户。

session的定义与多cookie

  不同的网站对session的定义和获取方法可能差异,比如非活动状态session的失效时间、多进程同时浏览时sessionid的共享等,所以同一个网站中session的定义标准必须统一才能保证统计数据的准确。cookie的不准确一方面是由于某些情况下cookie无法获取,另一方面是由于一个客户端可以有多个cookie,诸如chrome、Firefox等浏览器的cookie存放路径都会与IE的cookie存放路径分开,所以如果你是用不同的浏览器浏览同一网站,很有可能你的cookie就是不同的。

停留时间

  停留时间并不是直接获取的,而是通过底层日志中的数据计算得到的,因为所有日志中的时间都是时刻的概念,即点击的时间点。这里不得不提的是一个session的最后一个页面的停留时间是无法计算得到的,可以来看一下停留时间的计算过程:

  假设一个用户在一个session里面依次点击了A->B->C这3个页面,并在点完C之后关闭了浏览器,或者长时间的禁止导致了session的中断。那么我们可以从日志中获得的数据为3个页面的点击时间(HitTime),假设A、B、C点击时间分别为HTA、HTB、HTC,那么A和B页面的停留时间(StayTime)就可以通过计算得到:STA= HTB-HTA,STB= HTC- HTB,而因为我们无法获取session结束的时间,所以STC是无法通过计算得到的,所以一般session最后页面的停留时间是0,而session得停留时间,即一次访问的时间(Time on site)是HTC- HTA,其实是从打开第一个页面到打开最后一个页面的时间间隔,也是不准确的。

  另外,我们也无法获知用户在浏览一个页面的时候到底做了什么,是不是一直在阅读博客上的文章或者浏览网站上展示的商品,用户也有可能在期间上了个厕所、接了通电话或者放空的片刻,所以计算得到的停留时间并不能说明用户一直处于Engagement的状态。