:::: MENU ::::

TalkingData's Blog

现在开始,用数据说话。

Android 基于传感器数据进行实时行为识别的实现

  • 十一 22 / 2016
  • 0
Enterprise

Android 基于传感器数据进行实时行为识别的实现

作者:TalkingData 小辉

背景介绍

Google 在 I/O 2016 大会上正式向开发者介绍了 Awareness API:

A unified sensing platform enabling applications to be aware of multiple aspects of a users context, while managing battery and memory health.

Google 将 Google Play Service 中和用户场景识别相关的服务和功能整合在一个统一的 API 下,为开发者从兼顾内存占用和电量消耗方面提供更高效率的方案。

Google 定义的场景识别

Google 在 Awareness API 的文档中,对智能化所需的场景是 这样描述的:

实时识别的用户行为是场景识别中很重要的数据类型,可以被使用在很多领域:

- UBI(Usage Based Insurance),司机驾车时操控行为识别。
– Anti-Fraud,通过位置变化、应用使用情况、传感器数据(可判断手持状态、光照情况、行为等)建立的模型,能否识别出那些 App 的用户是真实用户。
– 运动 & 健身,通过在可穿戴设备上基于传感器数据的行为识别,为用户的运动和健身提供更好的记录和指导服务。
– Virtual Fence,通过使用不同场景数据建立虚拟围栏(耳机插入状态、跑步 10 分钟等),当特定情况被触发时提供相应的服务(Real Time Customer Engagement)。

基于移动设备传感器数据进行实时用户行为识别

通过上面的介绍我们可以看到实时用户行为识别结果是非常有意义的数据维度,移动设备,特别是我们日常随身使用的手机,搭载了越来越多、越来越精确的传感器,使用这些传感器的数据,应用机器学习的模型,我们就可以进行实时用户行为识别。

先来看一张广为流传的有监督学习的模型图:

我们需要做的事情和图片中描述的流程是一致的。

- 理解传感器数据及其坐标,Android 系统的订阅机制。
– 采集训练和测试数据集。
– 数据采集准备
– 特征抽取和选择
– 模型训练和调优
– 模型测试。
– 移植到 Android 平台

选择哪些传感器?

首先我们需要了解 Android 设备搭载的传感器类型,并且确定我们选择哪些传感器。下面这些传感器对于识别用户的行为很有用:

- 加速度传感器
– 陀螺仪
– 磁场传感器

为什么需要磁场传感器呢,因为我们需要它将基于机身坐标系的加速度数据转换到真实世界三维坐标系。原因在于

传感器数据基于机身坐标系,同一行为下,姿态不同的设备传感器数据是不同的,是否对每种行为都需要采集不同的设备姿态下传感器的数据?

同一行为不同姿态下的设备,传感器数据是不一样的。比如对于走路来说:

- 手机装在上衣口袋
– 手机装在裤子口袋
– 手机拿在手中,随手臂自然摆动
– 手机拿在手中,处于使用状态。还可分单手竖向握持以及双手横向握持。
– 手机随便放在随身包中。
– 等等

Google 在 Sensor Overview文档中对传感器机身坐标系的说明是这样的:

Figure 1. Coordinate system (relative to a device) that’s used by the Sensor API.

也就是说,当设备处于默认姿态(将设备正向竖立,面向屏幕)时:

- X 轴正向为水平向右
– Y 轴正向为垂直向上
– Z 轴正向为水平向外,垂直于屏幕

需要注意的是,这个坐标系是相对于机身不变的,而是随着机身的旋转而变化。下面这些传感器的数值是基于该坐标系的:

- Acceleration sensor
Gravity sensor
Gyroscope
Linear acceleration sensor
Geomagnetic field sensor

世界坐标系的定义为:

- X 轴正向指向贴着地面的东方
– Y 轴正向指向贴着地面的北方
– Z 轴正向指向垂直地面向上的方向。

通过 `getRotationMatrix`,传入加速度传感器三维数据和磁场数据,可以获得当前设备从机身坐标系到世界坐标系的旋转矩阵。
通过 `getOrientation()`,传入上面得到的旋转矩阵可以得到机身相对于世界坐标系,以弧度为单位的旋转角度。

- values[0]: *azimuth*, rotation around the -Z axis, i.e. the opposite direction of Z axis.

- values[1]: *pitch*, rotation around the -X axis, i.e the opposite direction of X axis.

- values[2]: *roll*, rotation around the Y axis.

现在的问题在于转换坐标系的准确性和一致性受磁场传感器准确率的影响,而磁场传感器的准确率受设备周围磁场环境的影响。其实,我们不需要世界坐标系很精确,只需要这个坐标系稳定,具备一定的一致性就可以。目前正在测试这个方案。如果可行,那么就可以极大减小数据采集的量级。

采用怎样的采样频率?采样时间窗口如何选择?

Android 文档中提到:

> The default data delay is suitable for monitoring typical screen orientation changes and uses a delay of 200,000 microseconds. You can specify other data delays, such as SENSOR_DELAY_GAME (20,000 microsecond delay), SENSOR_DELAY_UI (60,000 microsecond delay), or SENSOR_DELAY_FASTEST (0 microsecond delay). As of Android 3.0 (API Level 11) you can also specify the delay as an absolute value (in microseconds).

我们需要采用哪一种呢?自定义采样频率或者重新实现一个定时器去定时采样,上面的文章还提到:

> When you register a sensor with the registerListener() method, be sure you choose a delivery rate that is suitable for your application or use-case. Sensors can provide data at very high rates. Allowing the system to send extra data that you don’t need wastes system resources and uses battery power.

所以,用可以满足我们需要的频率(50 毫秒一次)去采集数据就可以了,采样频率越高就越耗电。采样时间窗口以 5 秒左右为宜,能较好地保留行为的周期性特征。

安卓设备多样性带来的挑战

由于 Android 设备的多样性,最终生产环境的算法模型需要尽可能多地覆盖市场占有率靠前的设备类型,但是不同设备上传感器灵敏度和精度不同是否会影响到算法模型的通用性和准确性?

测试 Nexus5X 和 红米 Note3 两部设备,完全相同的运动和设备姿态,采集到的加速度传感器数据如下:

从图中可以看到:

1. 两部设备传感器数据的 Pattern 基本一致。
2. 两部设备采集到的传感器数值绝对值存在差别,但是误差始终保持一致。

特征抽取和选择

经过测试,对于行为识别来说,下面这些特征能比较好地区别不同的行为:

- 采样时间窗口中采集数据(区分每个坐标轴的数据)的统计学特征计算:均值、峰值、标准差等。
– 每个坐标轴数据的频域特征,可通过快速傅立叶变换获得主频率。

特征抽取和特征选择是机器学习中非常重要的步骤,对不同的应用场景有不同的考虑,选择的结果会直接影响到识别结果的准确率和算法的泛化能力。

在测试阶段,可以尝试选择不同的特征组合进行识别,结合结果对特征采用不同的权重或者取舍,这部分工作可以在后端来做,最终在移动端进行实时用户行为识别时需要的,是训练好的模型参数。

分类算法的选择

Do we Need Hundreds of Classifiers to Solve Real World Classification Problems?是机器学习顶级期刊 JMLR 上发布的文章,在 UCI 的公开数据集上,比较了几乎全部流行的分类算法,最终得出的结论是随机森林在分类问题上的表现最好,所以我们也选择随机森林来做行为识别:

> 在机器学习中,随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。

Dice, 随即森林的一种高效实现

下面这张动图很好地解释了随即森林中单个决策树的工作原理:

实时用户行为识别是一个多分类问题,所以选用 CBRDT 模型。

/**
* The Random Decision Trees Model for multi-label classification prediction.
* CBRRDT is Calibrated Binary Relevance Random Decision Tree.
* In this model, it will predicate scores/probablities for each label,
* and the number of the positive labels for the given instance.
* The usage can of it can be found in dice.examples package.
* @author Xiatian Zhang
* @version 0.000
* @date 2011-5-21 09:37:46 p.m.
* @project Dice
*
*/
public class CBRRDTModel

根据选择的特征数量,我们定义好单个决策树的深度、随机选择的特征数量、分类个数以及限制分支生长的条件等参数,就可以创建随即森林模型:

TreeBuilder treeBuilder = new TreeBuilder(0, TreeBuilder.CBR_RDT);
treeBuilder.setInstances(trainInstances);
treeBuilder.setMaxDeep(maxTreeDepth);
treeBuilder.setMaxS(maxS);
treeBuilder.setClsSize(labelNum);
treeBuilder.init();
trees = treeBuilder.buildTrees(treeNum);

TalkingData Myna

TalkingData 开源 Android 平台使用机器学习进行进行实时用户行为识别的项目,已经基本完成代码清理和必要的文档,近期将上传到 Github,和大家一起继续讨论机器学习在移动端的应用场景。

- TalkingData/Myna

深度学习?

除了使用常见的机器学习的分类算法,我们还可以尝试使用最近比较流行的深度学习框架进行实时用户行为识别,比如 Tensorflow,下面这两个例子就是这样做的,将训练好的 Tensorflow 模型通过 NDK 移植到 Android 端,就可以在手机端运行了,只是目前可能会有一些性能和耗电方面的问题:

- Implementing a CNN for Human Activity Recognition in Tensorflow
LSTM-Human-Activity-Recognition

Leave a comment

随时欢迎您 联系我们