机器学习在 58 二手车估价系统实践


本文地址:http://www.6aiq.com/article/1573491656197
知乎专栏 点击关注
本文版权归作者和AIQ共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出

背景

近年来随着国内二手车市场交易量逐年攀升,线上交易越来越受到二手车商与个人的关注,随着 58 二手车帖子量跨越式增长,更需要严格的线上发帖审核机制来防止低价帖吸引正常用户的流量,那么一车一况的精准估价成为重要问题。58 估车价是 58 集团二手车技术部自主研发车型价格预测系统。可用于信息审核、提供用户更透明的价格区间、车型保值率排行等多种业务场景,并提供 58 估车价 APP 方便用户扫车、识车、估价、撮合成交。估价系统的核心是提取车辆信息组合特征,输出该车对应的保值率 (取值范围 0 到 1)。

估价系统总体架构

整个估价系统结构分为四个部分:

a) 数据来源于 58 自有数据金融成交数据,人工审核数据等,另外增补很多第三方合作平台数据,丰富不同场景的交易价格数据,通过自有的车型匹配系统映射到 58 车型库,定期同步到 HDFS 中。

b) 利用 spark 进行车型数据补全及业务去噪,生成待训练的标准格式数据。

c) 使用标准数据进行算法去噪及特征处理,进行反复的模型训练,此处需要反复验证特征、超参、模型的合理性及准确性。最终生成模型,对模型进行线上数据评估。

d) 将模型部署到 58 自研的 RPC 服务框架,组合业务规则,提供稳定估价服务。

估价系统架构图

数据处理

**•**获取样本

进行模型训练,首先大量准确的样本是必不可少的,我们与其他平台合作,手中掌握市场上大量的成交数据与市面上大部分平台的展示数据。针对这些数据我们会进行的初步去噪并匹配车型库数据丰富特征。最后进行业务去噪处理,例如将一些雷同或均值类似的帖子进行去重,过滤一些价格里程上牌时间明显不合理的样本。

•去噪、预处理

在样本处理的过程中比较头痛的就是样本本身的准确性与波动性,原始样本整体平滑度较差,需要对其进行多步去噪以及预处理。

a) 规则去噪:主要是针对上牌时间与车型上市时间和下市时间的过滤规则

b) 统计去噪:这里采用箱线图去噪,估值这个场景的目标就是找到最常规的保值率,偏离整体的样本越少越对能提升模型的准确率,忽视异常值会严重影响模型效果。如下图五条线从上至下依次为上边缘,上四分位数 Q3,中位数,下四分位数 Q1,下边缘,上边缘与下边缘分别定义为 Q3 与 Q1 在 Q3-Q1 的基础上增加与减少的上限与下限,在外线以外的极端值视为异常值处理。

箱线图去噪

c) 规则去重:在对样本统计分析,根据其特点制定的规则,例如对相同车型、里程、价格的,取上牌时间更早的样本等。

d) 重置成本排序:根据重置成本法得到估价,按照这个估价对每个车型排序。

e) 滤波:对排好序的每个车型,将原始的 rate 做滤波,假设原始的 rate 顺序应该与排好序的一致,滤波的大小为 s,那么以当前点为中心的 s 个点区域内,如果当前点不是极值就跳过,是极值就取平均值。滤波大小和次数可以调。

f) 调整顺序序:根据重置成本法得到估价,按照该估价对每个车型排序。

利用滤波函数平滑样本

**•**获取样本特征处理

二手车最明显的特点是一车一况,不同工况、不同地区、不同的使用环境、经营性质甚至颜色都会影响一辆车的价格。在确定了目标之后,我们需要确定使用哪些数据来达到目标。需要先梳理哪些特征数据可能影响二手车的保值率。我们可以借鉴一些业务经验,另外可以采用一些特征选择、特征分析等方法来辅助挑选。

首先基于业务逻辑可以选取车型相关配置参数、里程、车龄、上市时间这些明显数据特征,再结合车型库基础信息 (例如车型类别、国别、动力形式、变速箱、座椅数、厢数等) 可以组合出几十个特征的样本数据。

这里首先可以观察到,车型这个维度对结果应该明显车型之间差异巨大,但车型根据现有车型库会有 40000 多个种类,所以我们将车型映射到了国别、价格、类别、动力方式等几个维度较低的属性上。再之后将各车型的上市时间年龄通过离散化映射到 5 个区间;对有无对应配置的属性进行二值化等。

之后可以尝试用一批样本测试信息增益率,其它维度还可以考虑如过滤覆盖率低的特征、利用单个特征训练模型得到 AUC 值作比较等方法进行特征选择。

这里要说一下为什么不保留所有特征或者组合的高维特征:1. 特征维度越高越容易产生过拟合;2. 随着特征或维度越来越多,可能会降低性能和精度,达到相同效果可能越需要更多的训练样本;3. 样本如果越多也会造成更大的训练时间与人力,并且特征不容易分析,需要权衡成本;



但是特征工程不是到此为止的,根据统计分析与业务规则,往往能得出一些在定量样本下模型无法学习到的特性。举个例子,车龄理论上讲是上牌时间到现在的时间,但在实际市场交易中上市时间与实际上牌时间可能会差距比较大,有延后上牌的情况,但交易中该车的出厂时间被定在买卖双方的潜意识里面,例如一辆 2014 年上市,2016 年上牌的奔驰 C 级,按交易时间 2019 年算车龄为 3 年,但实际上双方认为它的车龄应该在 4-5 年来评估最终的价格,所以我们将车龄与上市时间进行换算,如上例将车龄定义为 x= 上牌车龄 +(上牌时间 - 上市时间)*i,i 为调整延迟上牌系数,得出一个新的关于车龄的参数 x 来代替原本的车龄,这样产生的新模型可以明显改善这种 case 的预测准确性。

再例如二手车在其他条件相同的情况下,总里程数对保值率的影响不是线性增长的,新车影响比较大,但随着里程数越来越高,对最终的价格影响越来越小,而且会发现,车龄越高的车影响会更小,但这样的样本其实市场上并不多,模型也很难学到,所以我们需要对特征进行处理,我们对里程进行取对数,利用斜率随 x 增大而减小的特性进行系数λ调整,得到一个效果更好的新特征。

mile_future = ln (λ / use_year * mile_per_year + 1)

利用对数函数导数特性

模型训练

**•**算法选择

估价问题是一个回归问题,从最初的折算建模到现在的机器学习模型,我们的目标都是不断的提升输出结果的准确率,直观的评估标准是与测试集相比的偏差率 =(实际值 - 理论值)/ 理论值 x100%,以及方差。

在多种回归算法中,例如 LR,随机森林,GBDT,xgboost 等,经过理论筛选与实际训练评测结果中我们选取了基于决策树的 xgboost 与 lightGBM 作为模型进行尝试。xgboost 所用的算法就是 gradient boosting decision tree 既可以用于分类也可以用于回归。其优点有很多,例如:xgboost 对代价函数进行了二阶泰勒展开,同时用到一阶和二阶导数;xgboost 在代价函数里加入了正则项,控制模型复杂度;对于特征的值有缺失的样本,可以自动学习出它的分裂方向,方便对样本进行特征处理;并且 xgboost 由于对数据进行预排序,支持在节点分裂计算特征信息增益时使用排序结构进行并行计算,提高计算速度。

lightGBM 模型 (下文简称 lgb 模型) 又针对 xgboost 的一些痛点进行了优化,例如:

xgboost 内存与 cache 占用过大,lgb 通过基于直方图的决策树算法代替预排序,减少遍历整个训练数据次数。

xgboost 在预排序后,特征对梯度的访问是一种随机访问,并且不同的特征访问的顺序不一样,对 cache 访问不友好,lgb 模型进行了 cache 命中率优化。

lgb 模型还进行了带深度限制的 Leaf-wise 的叶子生长策略,可以降低更多的误差,得到更好的精度。并进行了多线程优化, 大幅提升训练及执行时间,最终选择 lgb 模型为基础模型。

lightGBM 在效率上有优势

**•**模型调参

最后是进行训练调参,基于决策树模型参数调整一般需要如下步骤:

a) 首先选择较高的学习率 learning_rate,加快收敛的速度;

b) 对决策树基本参数调参,这里比较重要的是 max_depth :设置树深度,深度越大可能过拟合;num_leaves:因为 leaf-wise 的算法,因此在调节树的复杂程度时,使用的是 num_leaves 而不是 max_depth。换算关系一般为 num_leaves = 2(max_depth),但是它的值的设置应该小于 2(max_depth),否则可能会导致过拟合。

c)正则化参数调参,reg_alpha 与 reg_lambda,降低过拟合的,两者分别对应 l1 正则化和 l2 正则化。最简单的方式可以通过 sklearn 里的 GridSearchCV() 函数进行搜索穷举,找到合适的组合;

d) 最后降低学习率,提高准确率。这里还尝试了对 n_estimators 参数进行调整,

一般来说 n_estimators 太小容易欠拟合,n_estimators 太大又容易过拟合,增加 n_estimators 可以降低 mae,但是预测时间也会成倍增加,权衡 mae 的减少程度和预测时间的增加程度可知,单独增加 n_estimators 不再是一个有效的迭代方式。

调整 n_estimators 结果,time 损失较多

``lgb_big_params = {}``lgb_big_params['learning_rate'] = 0.3``lgb_big_params['max_depth'] = 11``lgb_big_params['n_estimators'] = 300``lgb_big_params['boosting_type'] = 'gbdt'``lgb_big_params['reg_lambda'] = 10.``lgb_big_params['reg_alpha'] = 1.``lgb_big_params['colsample_bytree'] = 0.8``lgb_big_params['num_leaves'] = 255``lgb_big_params['max_bin'] = 127``lgb_big_params['min_child_samples'] = 20``lgb_model = LGBMRegressor(**lgb_big_params)``

调参结果

不同的项目不同样本参数调整都有可能不同,需要多加尝试权衡找到最适合的参数值。

总结与规划

以上是针对该模型特征选取、去噪、训练的整个流程,由于数据量问题 (例如越老的车,市场占有量越小,越难以学习到特征) 不能完整支撑所有 case,所以之后我们还尝试了模型融合、不同类型 (轿车、新能源等) 车分成不同模型、不同车龄阶段分模型、以及指导价区间分模型训练等等,来完善线上预测的多种 case。现有估价模型与市面上其他估价平台效果对比如下。

58 估价总体效果最佳

我们将继续丰富样本量与特征维度,并深入挖掘各种模型的潜力以及样本特征间的关系,持续提升效果精准估算 B2C、C2B 等交易环节中涉及到的多种价格,将 58 估车价打造成为二手车行业内准确度的标杆,同时在语义和图像等深度学习方面发力,用技术持续为业务赋能。

作者简介

关鹏  58 同城 ABG 资深研发工程师,负责 58 估车价项目及深度学习相关项目在二手车业务中的实践与应用。

赏宇  58 同城 ABG 高级开发工程师,负责估车价项目及深度学习项目的开发和工程化等工作。


本文地址:http://www.6aiq.com/article/1573491656197
知乎专栏 点击关注
本文版权归作者和AIQ共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出