移动应用统计的基本原理及 UMID 方案解析

1. 基本概念

根据能否追踪到单个独立的设备, 可以将一个统计系统分为可区分统计(Discriminative Statistics)和不可区分统计(Non-Discriminative Statistics)。友盟提供的是可区分统计,也就是会利用一个身份标识符(Unique ID,以后简称 ID)长期追踪单个设备的数据。作为对比,早期的网站统计都是不可区分统计,例如页面访问次数,独立 IP 数等;现代的网站统计都是基于 Cookie 或硬件指纹的可区分统计。由于智能设备提供了足够多的硬件指纹和计算能力,友盟从第一天开始就专注于可区分统计。

大多数移动统计的 ID 都是通过系统 ID 生成的,包括但不限于 IMEI、MAC、Android ID。最著名的 ID 莫过于 UDID, 迫于隐私的压力,苹果最终废弃了 UDID 和 MAC 地址。

大多数网站统计都是基于 Cookie的,因此是暂态ID(Temporal ID)。OpenUDID 就是一个典型的暂态ID。

苹果的 IDFA 和 IDFV 都是系统ID,但是他们同时也是暂态ID。

由于可区分统计涉及到用户隐私,因此友盟在计算中使用的都不是系统 ID ,而是自己的 UMID。友盟不会向第三方[1]提供包含原始 ID 或 UMID 的数据,而是提供聚合后的结果。UMID 既不是系统ID也不是暂态ID,它是一个在不断演化的ID解决方案。本文将会解释友盟为什么要设计 UMID,又为何要不断地改进这个方案。

2. ID质量

进行可区分统计的基础是确立一个可靠的身份标识符,这看上去是一个很简单的事情,只需要选择一个ID,或者人为构造一个类Cookie ID,就可以完成独立用户量、留存等分析。但遗憾的是,除了苹果已经废除的UDID,几乎没有一个接近完美的ID。

为了方便讨论,首先忽略假数据的存在,假设每个设备都有一个真实的身份标识X。可区分统计的目标是选择一个合适的身份标识I,使得基于I的统计结果尽可能地和 X 一致。

首先,我们引入两个概念ID冲突(Collision)和ID漂移(Jitter)。

ID冲突

对于某个设备集合(Device Cohort),在某个时间段内,总是可以测量 X 和 I 的数量,用 Count(X) 和 Count (I) 来表示。如果在足够短的时间内

Count(X) > Count(I)

我们称 I 是一个存在冲突的 ID。

ID漂移

对于某个设备集合(Device Cohort),在某个时间段内,总是可以测量 X 和 I 的数量,用 Count(X) 和 Count (I) 来表示。如果在足够长的时间内

Count(X) < Count(I)

则我们称 I 是一个存在漂移的 ID。

Android 设备的IMEI 就是一个存在严重冲突的 ID,根据我们的估算,其冲突率大于 3%。这是因为很多山寨机的IMEI 是相同的。

Android 设备的 MAC 也是一个存在冲突的ID,因为很多山寨机的MAC也是相同的。此外,MAC还是一个典型的存在严重漂移的 ID,这是因为 Android 的源代码中有一段随机生成MAC  地址后24位的代码被滥用了(参考阅读: MAC地址漂移的问题)。

定性分析

接下来,我们可以定性分析一下ID冲突和漂移对统计数据的影响:

当一个ID仅存在冲突的时候,利用这个ID统计的DAU和安装都会被低估,但是有可能会高估留存。但是这些影响都是温和的,例如5% 的ID冲突仅仅会导致DAU至多被低估 5%,而对留存的影响几乎可以忽略。

当一个ID仅存在漂移的时候,利用这个ID统计的DAU和安装都会被高估,同时会影响留存。当漂移较大的时候,对统计指标的影响是剧烈的。例如,一个每日漂移为5%的ID,可能会造成DAU被高估2%,但是会每天造成5%的虚假安装(这是因为漂移会影响所有用户,包括不活跃用户),同时这些虚假安装的留存在短期内偏高,但是长期留存则偏低(短期内没有漂移的时候就会偏高,时间长了,漂移了就会偏低)。任何类Cookie的ID都会有类似的性质,因此传统的网站统计正在全面转向更为可靠的设备指纹。

当一个ID既存在冲突又存在漂移的时候,利用这个ID统计出来的DAU和安装是完全不可靠的。以MAC地址为例,存在漂移的这部分设备的MAC地址会频繁变化,因此会制造大量的虚假安装,同时留存率非常低。对于用户量不大的应用而言,选择存在这类ID的后果是灾难性的。

综上所述,当ID的漂移和冲突足够小的时候,他们对可区分统计的影响都是可以忽略的。当这些误差不可忽略的时候,ID的冲突造成的影响是温和的,而ID的漂移则会严重干扰安装和留存统计。

3. ID选择

iOS平台

随着苹果废弃UDID、MAC地址, 并且通过在iOS7上对剪贴板限制导致OpenUDID无法在不同应用间共享,标志着设备ID的控制权回到了苹果手中,也表明了苹果对用户隐私保护的决心。

在后iOS7时代,ID的选择是再清楚不过的,业内通用的ID主要是IDFA(即广告标示符,advertisingIdentifier)和IDFV(即vendor标示符,identifierForVendor)。IDFA适用于对外的广告推广、交叉推荐等跨应用的用户追踪;IDFV适用于用户在应用内的行为追踪。

当然,对于移动统计平台而言,必须要保证统计的兼容性和容错性。这也是为什么我们一直强调的是使用一个不断优化的UMID解决方案,而不是任何一个具体的ID。

Android平台

对于Android平台,由于系统生态的开放性,ID的选择也一直是一个头疼的问题。

(1)单一ID

如前文所述,IMEI和MAC都不是最好的ID。特别是MAC地址,几乎是一个不可用的ID。

(2)组合ID

有些开发者会选择使用多个ID合并成一个组合ID,例如

CID = MD5( imei+mac+android_id)

利用前面的分析不难得出,组合ID将会极大地降低冲突,但是会放大漂移。对于组合ID而言,任何一个源ID的漂移都会造成它的漂移。

开发者应该尽量避免CID,一定要使用也需要避免使用MAC地址。如果已经在使用CID,那么请确保在下一个版本把CID当作一个Cookie ID持久化,只有在Cookie丢失的情况下才重新生成CID。这样的策略可以尽量保证ID的延续性,同时缓解漂移造成的影响。

4. 友盟的ID方案

UMID

由于UMID还在演化之中,这里只能简单地解释UMID的生命周期。UMID是一个极度保守的ID,当一个设备被分配了某个UMID以后,友盟会尽量保证这个UMID不会发生变化。因此,UMID的生成策略受到了友盟历史数据的限制,最重要的设计目标是确保稳定性和数据一致性。友盟会持续地监控冲突和漂移,并且会尽量降低漂移,将冲突控制在合理的范围内。正如世界上没有永动机一样,UMID并不是一个完美的ID。

Prime Radiant

为进一步的提高ID质量,友盟推出了全新的SDK。这个版本的SDK从设计到发布用了差不多一年,内部代号是 Prime Radiant,来自阿西莫夫的科幻小说。通过Prime Radiant提供的新特性,友盟将能更好地监控ID信号源的质量,并且能够根据实际的数据来调整策略,充分利用设备ID和暂态ID的优势和劣势。Prime Radiant 还充分利用了智能设备的计算能力,利用密码学手段来提高数据质量和可靠性。

正是得益于Prime Radiant 测试阶段的数据,友盟才能精确地对各类ID的质量进行定量分析。本文的很多结论都离不开这些数据。对于关心数据质量和数据安全的开发者,建议升级友盟新版SDK 进行体验、测评。

新版本SDK的下载地址:

iOS 统计SDK

Android统计SDK



[1]只有在广告对账、数据校准的时候,友盟和第三方会交换包含 ID 的数据。

移动应用统计的基本原理及 UMID 方案解析

时间: 2024-08-29 08:06:51

移动应用统计的基本原理及 UMID 方案解析的相关文章

DNS基本原理及正反向解析

1.DNS基本原理 DNS:Domain Name Service,域名解析服务 监听端口:udp/53,tcp/53 应用程序:bind www.magedu.com.: FQDN Full Qualified Domain Name 完全合格域名/全称域名 名称解析:主机名解析 把一种名称转换为另一种名称的过程 名称:字串.数字 解析库:某种存储 username <--> uid 某种存储: 文本文件 关系型数据库 LDAP:Lightweight Directory Access Pr

Android逆向之旅---应用的&quot;反调试&quot;方案解析(附加修改IDA调试端口和修改内核信息)

一.前言 在前一篇文章中详细介绍了Android现阶段可以采用的几种反调试方案策略,我们在破解逆向应用的时候,一般现在第一步都回去解决反调试,不然后续步骤无法进行,当然如果你是静态分析的话获取就没必要了.但是有时候必须要借助动态调试方可破解,就需要进行操作了.现阶段反调试策略主要包括以下几种方式: 第一.自己附加进程,先占坑,ptrace(PTRACE_TRACEME, 0, 0, 0)!第二.签名校验不可或缺的一个选择,本地校验和服务端校验双管齐下!第三.借助系统api判断应用调试状态和调试属

【JavaScript】新浪微博ajax请求后改变地址栏url,但页面不跳转的方案解析

新浪微博当你弹出一个视频的时候再点下一页时,原视频还在,而且地址栏的url的页数变了.对于这种网上讨论最多的方案有以下几种: 一.通过锚点Hash实现在这方面其实国内很早就有做了,比如淘宝画报,通过的是在地址栏后面加#锚点实现的,浏览器是可以识别锚点为单位的历史记录的.但不 是说页面本身有这个锚点,锚点的Hash只是起到一个引导浏览器将这次的记录推入历史记录栈顶的作用. 二.通过HTML5加强型的History对象实现(类Pjax)可以通过window.history.pushState这个方法

Android中so使用知识和问题总结以及插件开发过程中加载so的方案解析

一.前言 Android中有时候为了效率以及平台开发库的支持,难免会用到NDK开发,那么都会产生一个so文件,通过native方法进行调用,开发和调用步骤很简单,这里就不多说了,本文主要来介绍,我们在使用so的时候总是会出现一些常见的问题,而现在插件化开发也很普遍了,有时候插件中也会包含一些so文件,需要加载,这时候也会出现一些问题.本文就来详细总结一下这些问题出现的原因,以及解决方法,主要还是通过源码来分析. 二.涉及到的源码类 因为本文主要通过分析源码来分析so使用的知识点和问题总结,所以涉

分布式之数据库和缓存双写一致性方案解析

引言 为什么写这篇文章? 首先,缓存由于其高并发和高性能的特性,已经在项目中被广泛使用.在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作. 但是在更新缓存方面,对于更新完数据库,是更新缓存呢,还是删除缓存.又或者是先删除缓存,再更新数据库,其实大家存在很大的争议.目前没有一篇全面的博客,对这几种方案进行解析.于是博主战战兢兢,顶着被大家喷的风险,写了这篇文章. 正文 先做一个说明,从理论上来说,给缓存设置过期时间,是保证最终一致性的解决方案.这种方案下,我们可以对存入缓存的数据设置

布式之数据库和缓存双写一致性方案解析(转)

引言 为什么写这篇文章? 首先,缓存由于其高并发和高性能的特性,已经在项目中被广泛使用.在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作.但是在更新缓存方面,对于更新完数据库,是更新缓存呢,还是删除缓存.又或者是先删除缓存,再更新数据库,其实大家存在很大的争议.目前没有一篇全面的博客,对这几种方案进行解析.于是博主战战兢兢,顶着被大家喷的风险,写了这篇文章. 文章结构 本文由以下三个部分组成1.讲解缓存更新策略2.对每种策略进行缺点分析3.针对缺点给出改进方案 正文 先做一个说明,

Redis与Mysql双写一致性方案解析

一 前言 首先,缓存由于其高并发和高性能的特性,已经在项目中被广泛使用.在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作 但是在更新缓存方面,对于更新完数据库,是更新缓存呢,还是删除缓存.又或者是先删除缓存,再更新数据库,其实大家存在很大的争议 本文由以下三个部分组成 1.讲解缓存更新策略 2.对每种策略进行缺点分析 3.针对缺点给出改进方案 二 一致性方案 先做一个说明,从理论上来说,给缓存设置过期时间,是保证最终一致性的解决方案.这种方案下,我们可以对存入缓存的数据设置过期时间

分布式之延时任务方案解析

引言 在开发中,往往会遇到一些关于延时任务的需求.例如 生成订单30分钟未支付,则自动取消 生成订单60秒后,给用户发短信 对上述的任务,我们给一个专业的名字来形容,那就是延时任务.那么这里就会产生一个问题,这个延时任务和定时任务的区别究竟在哪里呢?一共有如下几点区别 定时任务有明确的触发时间,延时任务没有 定时任务有执行周期,而延时任务在某事件触发后一段时间内执行,没有执行周期 定时任务一般执行的是批处理操作是多个任务,而延时任务一般是单个任务 下面,我们以判断订单是否超时为例,进行方案分析

【转】分布式之数据库和缓存双写一致性方案解析

转自:https://www.cnblogs.com/rjzheng/p/9041659.html 引言 为什么写这篇文章? 首先,缓存由于其高并发和高性能的特性,已经在项目中被广泛使用.在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作.但是在更新缓存方面,对于更新完数据库,是更新缓存呢,还是删除缓存.又或者是先删除缓存,再更新数据库,其实大家存在很大的争议.目前没有一篇全面的博客,对这几种方案进行解析.于是博主战战兢兢,顶着被大家喷的风险,写了这篇文章. 文章结构 本文由以下三个