原作者: Chun-Chen Kuo, Livia Yanez和Jeffrey Yun 翻译:欧高炎
高质量的地图数据为Uber旅行体验的许多方面提供了动力。搜索、路由和预计到达时间(ETA)预测等服务都要依靠准确的地图数据为乘客、司机、食客和投递伙伴提供安全、便捷和高效的体验。然而,地图数据会随着时间的推移而过时,从而降低其质量。
作为一家顾客至上的企业,Uber会评估和处理并解决乘客、司机、食客和投递伙伴通过Uber平台提交的顾客支持票据的反馈。其中部分票据会提出定位问题,为我们提供了一种识别和修复地图数据错误的方法。
我们每天服务的行程数量超过1500万次,因此即便只有很低比例的行程中包括客户支持票据,我们也能获得大量的票据。人工浏览这些票据以发现地图数据中的错误显然不是一个可扩展性的办法。因此,我们使用机器学习和大数据处理来自动化这项工作流程。
我们构建了一个自然语言处理平台来进行大规模票据分析,以找出票据文本中反映出的地图数据相关的问题。该平台可以指出票据中反映的地图数据的特定类型,便于我们对应的团队评估问题并确定解决方案。
一、利用我们的客户支持平台
客户支持平台允许客户选择票据类型。这些类型往往是为满足客户需求设计的,通常不够具体。例如“我遇到了交通事故”,“查看我的票价或费用”或“我丢了订单”。在客户支持平台中详细列出地图数据类型又不太合适,因为这些分类过于细粒度了。
由于缺乏前期分类,我们需要处理自由格式的文本并检测与地图数据类别相关的信号。人们在提交票据时会用多种不同的短语来表达同一件事。例如,一个人可能会写一个位置是“错误的”,而另一个人可能会将其描述为“不正确”或“关闭”。这种理解人们用多种方式表达相同的事物的问题,十分适合使用自然语言处理(NLP)方法来解决。
二、NLP和ML算法
检测地图数据类型中的错误的要求可以被建模为机器学习中的分类问题。分类模型通过从训练数据的学习来预测票据与地图数据类型中的错误相关的概率。我们使用逻辑回归(或Softmax)建立我们版本1算法。
逻辑回归接收数值向量作为输入。因此,我们需要将票据(包括文本和联系类别)编码为数字向量。对于文本,一种简单的方法是使用预定义的词典来按词频进行编码。这种方法将得到稀疏向量并需要更多的训练数据来有效地训练分类模型,在大多数情况下是不可行的。因此,我们希望将票据文本嵌入(映射)到稠密向量,使得在映射空间中,相似的票据之间的距离也相近使得在映射空间中相似的票据的向量之间的距离也相近。
对于版本1算法,我们使用Word2Vec来学习词嵌入向量。模型设置为给定某一个词,预测其上下文(即附近的词)。这样在嵌入空间中,语义上相似的词将会彼此接近。得到词向量后,票据文本的向量为文本中包含的词的向量的平均值。每一种了联系类别都有一个唯一的UUID,我们使用OneHot编码方法来对票据类型进行编码。票据的最终向量是票据文本向量和联系类型OnoHot向量的拼接。为了消除噪音,在将票据文本输入给神经网络模型之前,我们对其进行删除HTML标记、标点符号和停用词等预处理操作。算法流程如图1中所示。
图1:机器学习算法首先确定票据联系类型和文本内容,得到文本词向量和类型OneHot向量,然后在拼接向量空间上应用逻辑回归模型。
我们可以将逻辑回归的输出解释为票据与地图数据类型错误相关的概率,并根据精度召回率的权衡来设置阈值。我们将正类定义为概率大于或等于阈值的票据。
机器学习算法的主要挑战是构造训练数据的代价。由于不是每一个地图数据类型都有联系类型,需要手动进行票据样本标注。通常,一个人在3-6个月能够标注1万到2万个票据。
幸运的是,训练词向量是无监督的,我们使用抽样的一百万条票据数据集训练Word2Vec词向量。我们尝试过Wikipedia数据上预训练的GloVe词向量,但发现使用客户票据训练的词向量的性能更好,可能是因为模型学习了特定领域的语言特征。
我们版本1的算法有其缺点。首先,我们使用平均值方法将词向量组合成票据文本向量。这种方法对票据中所有的词一视同仁,没有重要词的权重。其次,用无监督学习方法训练后,词向量便固定了,无法通过优化分类任务来调整。为了克服这些缺点,我们开始深度学习模型,例如WordCNN和LSTM。
图2:为克服版本1算法的缺点,我们考虑将WordCNN和LSTM应用于票据分类问题。
下表显示了在一种地图数据类型中进行二分类的模型性能。模型运行10次,每次将数据集划分成训练集/验证集/测试集来进行优化。在每一种模型中,词向量分别使用以下三种方法生成:使用Word2Vec训练;直接使用GloVe在Wikipedia上预训练的词向量;随机生成词向量。词向量也有两种模式,第一种为固定,第二种为允许微调。这些词向量要么保持固定,要么允许微调(trainable = “yes”)。性能评测的主要指标包括ROC曲线下面积AUC_ROC,精度召回率曲线下面积AUC_PR和recall@ precision = 0.5(更直观地了解模型在给定精度水平下的灵敏度)。
图3:模型性能可视化,可以明显看到 WordCNN的效果最好。
可以看到,使用WordCNN和Word2Vec初始化的允许微调的词向量模式下,模型取得了最好的效果。这个结果是有道理的,WordCNN能够更好地建模关键词聚焦和激活,而LSTM能够更好地建模语言模型和序列生成。我们的应用场景更加类似于关键词聚焦和激活。换句话说,我们更关心某些短语的存在和词的顺序。因此,我们决定使用WordCNN作为我们的版本2算法。
三、词向量可视化
每个单词都映射到300维度的向量。我们使用t-SNE和PCA等降维方法将词向量降低为3维以便对其进行可视化。然后我们可以在三维图中验证语义上相似的词是否彼此接近。此外,我们可以找到每一个词的同义词,例如用余弦距离或者欧几里得距离找到某一个词向量最近的那个词。TensorBoard是可视化词向量和进行距离计算的工具。
另外一种理解学习到的词向量含义的方法是找到其同义词。给定一个词,在向量空间中使用欧几里得距离或余弦距离找到离它最近的N个词。我们可以通过分析来验证词的语义是否与常识相吻合,从而确保词向量被恰当的训练。
下表展示了我们的词向量模型学习到的一些同义词的样例。
四、系统设计和架构
图4:使用逻辑回归的版本1算法和使用WordCNN的版本2算法均用端到端的Spark流水线方式实现。
Uber拥有一个大数据生态系统,产品团队能够在该系统利用Spark和Hive存储和查询来自Hive表的数据,并在Uber集群上运行Spark流水线任务。我们将机器学习算法实现为端到端Spark流水线任务。在流水线中,首先使用SparkSQL查询票据Hive表(包括ticket_id和联系类型)和票据文本Hive表(包括ticket_id,ticket_content和trip_id)。然后将这两个表进行连接的结果输入给预处理阶段。
在预处理之后,我们使用NLP模型(联系类型索引,联系类型OneHot编码,Word2Vec模型和逻辑回归模型(使用Spark流水线进行训练和保存)。Spark的ML管道范例帮助我们编写简洁且可维护的代码。对于版本2算法,我们使用TensorFlow离线训练WordCNN模型并将其保存为检查点。然后,我们将训练好的模型导出为TensorFlow的SavedModelBuilder格式。在生产系统中,我们与Uber的Michelangelo团队合作,将SavedModel文件包装为Spark流水线模型,并在端到端的Spark流水线中无缝地提供服务。整个流程如图5所示。
图5:我们将TensorFlow WordCNN模型包装为Spark流水线。
当乘客提交票据时,它会自动与行程(乘客请求或旅行的上车点到下车点的路径)相关联。一些地图实体也与行程相关联。为了进一步提高可信度,我们可以通过行程,将正类票据和地图实体进行连接,将同一个地图实体上的票据进行聚合,然后对地图实体进行打分,最后通过一个排序模型对地图实体进行排序。排名模型的简单实现方法为:将同一个实体关联的所有票据的概率进行求和,最后使用票据数量进行归一化。
图6:如果我们可以将地图实体与我们数据库中的行程ID相关联,我们可以将其与正类票据进行连接并汇总票据,从而获得更高置信度的结果。
我们并不需要手动触发Spark流水线,而是使用Uber的工作流管理系统每周调度运行。编辑地图数据类型的服务会自动使用流水线结果并生成手动编辑任务。
五、未来的工作
项目的未来有两个方向,纵向扩展和横向扩展。对于纵向扩展,我们将探索更先进的模型来提高精度和召回率。对于横向扩展,我们将扩展到更多语言和地图数据类型。