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

背景

近年来随着国内二手车市场交易量逐年攀升,线上交易越来越受到二手车商与个人的关注,随着 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 高级开发工程师,负责估车价项目及深度学习项目的开发和工程化等工作。


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