二手车交易价格预测-天池比赛
1. 问题背景与研究思路
1.1 问题背景
选题来自天池比赛,通过挖掘二手车交易信息实现二手车的交易价格的预测。
1.2 研究思路
二手车交易价格的预测问题可通过回归模型对数据进行拟合,从而建立二手车交易价格的预测模型。由于数据集中可能存在部分属性对于二手车交易价格影响较小,因此可选择关联度高的属性进行回归与预测,尽量减少模型的规模。为此,需对数据集进行预处理与可视化,以选取合适的属性。
本报告内容安排如下:第2章介绍数据的获取与预处理过程,第3章分别对标称属性和数值属性的数据进行分析与可视化,第4章介绍回归模型的选取并展示价格的预测结果,最后介绍本项目的分工情况。
2. 数据获取及预处理
2.1 数据来源
该项目为天池官方比赛,表格数据从天池比赛官方下载(https://tianchi.aliyun.com/competition/entrance/231784/information)。数据来自某交易平台的二手车交易记录,总数据量超过40w,包含31列变量信息,其中15列为匿名变量。由于部分属性涉及了部分商业信息,因此数据集对name、model、brand和regionCode等信息进行了脱敏。
2.2 数据说明
下面为训练集数据信息。共有150000条数据,有31列变量信息。包括名称、品牌、公里数、价格等。v_0 ~v_14为匿名变量。
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 150000 entries, 0 to 149999
Data columns (total 32 columns):
Unnamed: 0.1 150000 non-null int64
SaleID 150000 non-null int64
name 150000 non-null int64
regDate 150000 non-null int64
model 149999 non-null float64
brand 150000 non-null int64
bodyType 145494 non-null float64
fuelType 141320 non-null float64
gearbox 144019 non-null float64
power 150000 non-null int64
kilometer 150000 non-null float64
notRepairedDamage 125676 non-null float64
regionCode 150000 non-null int64
seller 150000 non-null int64
offerType 150000 non-null int64
creatDate 150000 non-null int64
price 150000 non-null int64
v_0 150000 non-null float64
v_1 150000 non-null float64
v_2 150000 non-null float64
v_3 150000 non-null float64
v_4 150000 non-null float64
v_5 150000 non-null float64
v_6 150000 non-null float64
v_7 150000 non-null float64
v_8 150000 non-null float64
v_9 150000 non-null float64
v_10 150000 non-null float64
v_11 150000 non-null float64
v_12 150000 non-null float64
v_13 150000 non-null float64
v_14 150000 non-null float64
dtypes: float64(21), int64(11)
memory usage: 36.6 MB
缺失数据及个数:
Unnamed: 0.1 0
SaleID 0
name 0
regDate 0
model 1
brand 0
bodyType 4506
fuelType 8680
gearbox 5981
power 0
kilometer 0
notRepairedDamage 24324
regionCode 0
seller 0
offerType 0
creatDate 0
price 0
v_0 0
v_1 0
v_2 0
v_3 0
v_4 0
v_5 0
v_6 0
v_7 0
v_8 0
v_9 0
v_10 0
v_11 0
v_12 0
v_13 0
v_14 0
dtype: int64
各属性说明如下:
Field | Description |
---|---|
SaleID | 交易ID,唯一编码 |
name | 汽车交易名称,已脱敏 |
regDate | 汽车注册日期,例如20160101,2016年01月01日 |
model | 车型编码,已脱敏 |
brand | 汽车品牌,已脱敏 |
bodyType | 车身类型:豪华轿车:0,微型车:1,厢型车:2,大巴车:3,敞篷车:4,双门汽车:5,商务车:6,搅拌车:7 |
fuelType | 燃油类型:汽油:0,柴油:1,液化石油气:2,天然气:3,混合动力:4,其他:5,电动:6 |
gearbox | 变速箱:手动:0,自动:1 |
power | 发动机功率:范围 [ 0, 600 ] |
kilometer | 汽车已行驶公里,单位万km |
notRepairedDamage | 汽车有尚未修复的损坏:是:0,否:1 |
regionCode | 地区编码,已脱敏 |
seller | 销售方:个体:0,非个体:1 |
offerType | 报价类型:提供:0,请求:1 |
creatDate | 汽车上线时间,即开始售卖时间 |
price | 二手车交易价格(预测目标) |
v系列特征 | 匿名特征,包含v0-14在内15个匿名特征 |
2.3 数据预处理
上述数据信息显示存在缺失值,利用属性的相关关系来填补。选择拉格朗日插值方法——最近邻插值法对缺失值进行填补。下面展示存在缺失值属性的填补前后可视化对比:
车身类型:
before
count 145494.000000
mean 1.792369
std 1.760640
min 0.000000
25% 0.000000
50% 1.000000
75% 3.000000
max 7.000000
Name: bodyType, dtype: float64
after
count 150000.000000
mean 1.791493
std 1.760303
min 0.000000
25% 0.000000
50% 1.000000
75% 3.000000
max 7.000000
Name: bodyType, dtype: float64
燃料类型:
before
count 141320.000000
mean 0.375842
std 0.548677
min 0.000000
25% 0.000000
50% 0.000000
75% 1.000000
max 6.000000
Name: fuelType, dtype: float64
after
count 150000.000000
mean 0.375767
std 0.548581
min 0.000000
25% 0.000000
50% 0.000000
75% 1.000000
max 6.000000
Name: fuelType, dtype: float64
变速箱类型:
before
count 144019.000000
mean 0.224943
std 0.417546
min 0.000000
25% 0.000000
50% 0.000000
75% 0.000000
max 1.000000
Name: gearbox, dtype: float64
after
count 150000.000000
mean 0.225213
std 0.417724
min 0.000000
25% 0.000000
50% 0.000000
75% 0.000000
max 1.000000
Name: gearbox, dtype: float64
是否有未修复损伤:
before
count 125676.000000
mean 0.113904
std 0.317696
min 0.000000
25% 0.000000
50% 0.000000
75% 0.000000
max 1.000000
Name: notRepairedDamage, dtype: float64
after
count 150000.000000
mean 0.114247
std 0.318112
min 0.000000
25% 0.000000
50% 0.000000
75% 0.000000
max 1.000000
Name: notRepairedDamage, dtype: float64
缺失值填补后,对数据进行探索性分析。
3. 数据分析与可视化
对不同列数据进行统计分析并可视化:
3.1 标称属性
分别对model、brand、bodyType、fuelType、gearbox、notRepairedDamage、regionCode、seller、offerType进行柱状图可视化:
对于model属性,其不同标签数量分布较为分散,其按从多到少排列的柱状图构成的曲线与反比例函数相似。
对于brand属性,其不同标签数量分布较为分散,但总体集中于标签0、4、14、10、1 。其中数量最多的品牌标签为0,数量约为第二名的两倍。
对于bodyType属性,数量最多的三种类型为豪华轿车:0、微型车:1、厢型车:2。搅拌车:7交易数量最少
对于fuelType属性,可见汽油(标签0)数目最多、柴油(标签1)其次、其余类型数目较少。
对于gearbox属性,其为二值属性且以手动(0标签)为主,自动(1)标签为辅。
对于notRepairedDamage属性,其为二值属性且以0标签为主。大多数二手车在交易时存在未修复的车损。
对于regionCode属性,除数量最多的地区419和次多的地区764外,其余各地区数量分布较为均匀。
对于seller属性,几乎全部为个体(标签0),存在个别车辆的卖家为非个体(标签1)。
对于offerType属性,均为提供类型(标签0),无请求类型(标签1)。
3.2 数值属性
分别对regDate、power、kilometer、createDate、price 通过绘制盒图、散点图和直方图来可视化数据:
以上为regDate属性的盒图、散点图和直方图。由直方图走势可看出二手车注册量自1990年至2000年呈递增态势,2000至2005年呈谷形,自2005年之后注册量走低。
观察盒图可以发现power存在较多异常点,因此删除数值较小或者数值较大的异常点,删除后再重新绘制盒图、散点图以及直方图。结果如下:
可以观察到散点图和直方图的数据较为分散。发动机功率主要分布在中低功率区间。
以上为kilometer属性的盒图、散点图和直方图。从散点图和直方图可看出公里数分布呈离散型,从盒图和直方图可看出汽车行驶公里数多位于12-15万公里间。
以上为createDate属性的盒图、散点图和直方图。可以看出汽车上线时间主要集中于2016年初,一些汽车的上线时间集中于2015年初。
以上为price属性的盒图、散点图和直方图。从三图中可共同看出数据集中于0值,从直方图走势可看出价格由低到高交易数量逐渐减少,人们比较倾向于选择较低价格的二手车。
3.3 特征选择
对属性进行特征选择,发现属性中存在两个日期,一个是销售日期,一个是注册日期,这两个日期单独来看与价格的相关性不大,但是根据这两个属性可以计算得出汽车的使用时间,汽车的新旧程度对价格的影响会很大。
并且汽车的车型也与汽车的价格有着密切的关系。因此需要计算每种车型的销售数量、平均价格、最高价格、最低价格以及中间价格,并作为属性加入每一条销售记录中。
最后备选的属性有’usedTime’,’power’, ‘kilometer’, ‘bodyTypeAmount’, ‘bodyTypePriceMax’, ‘bodyTypePriceMin’, ‘bodyTypePriceAverage’这7个属性,分别计算它们与价格属性之间的相似度。观察到’usedTime’,’power’, ‘kilometer’, ‘bodyTypePriceMin’,’bodyTypePriceAverage’这几个属性与price之间的相似度的绝对值均大于0.3。因此可以考虑选择作为属性去训练模型。
Correlation of Numeric Features with Price
name correlation
usedTime -0.7536022453192838
power 0.5773425426332196
kilometer -0.4097783640876424
bodyTypeAmount -0.1977078836415173
bodyTypePriceMax -0.1095324062658541
bodyTypePriceMin 0.34554823124408146
bodyTypePriceAverage 0.3524069606523509
或者我们可以把属性之间的关系绘制成编码矩阵。
4. 回归与预测
4.1 模型选取
本选题要求预测二手汽车的交易价格。该问题可通过对训练集数据进行回归来构建预测模型,并将测试集作为输入进行预测。
首先,依据属性特点与现实意义,选择’usedTime’,’power’, ‘kilometer’, ‘bodyTypePriceMin’,’bodyTypePriceAverage’五个属性以及匿名的 ‘v_0’~ ‘v_14’属性作为输入。然后分别使用目前广为使用的XGBoost回归算法和LightGBM回归算法对输入与价格进行回归,得到价格预测模型。
XGBoost是在 Gradient Boosting 框架下实现机器学习算法,可以快速准确地解决许多数据科学问题;而LightGBM算法则相比于XGBoost要更加快速且准确。为了进一步提升预测准确度,将此两种模型进行加权融合,得到最终的预测模型。
最后,对模型进行评价与预测。
4.2 预测结果与评价
本选题要求预测二手汽车的交易价格。该问题可通过对训练集数据进行回归来构建预测模型,并将测试集作为输入进行预测。
模型的评价标准为MAE:
利用xgb进行五折交叉验证查看模型的参数效果:
## xgb-Model
xgr = xgb.XGBRegressor(n_estimators=120, learning_rate=0.1, gamma=0, subsample=0.8,\
colsample_bytree=0.9, max_depth=7) #,objective ='reg:squarederror'
scores_train = []
scores = []
## 5折交叉验证方式
sk=StratifiedKFold(n_splits=5,shuffle=True,random_state=0)
for train_ind,val_ind in sk.split(X_data,Y_data):
train_x=X_data.iloc[train_ind].values
train_y=Y_data.iloc[train_ind]
val_x=X_data.iloc[val_ind].values
val_y=Y_data.iloc[val_ind]
xgr.fit(train_x,train_y)
pred_train_xgb=xgr.predict(train_x)
pred_xgb=xgr.predict(val_x)
score_train = mean_absolute_error(train_y,pred_train_xgb)
scores_train.append(score_train)
score = mean_absolute_error(val_y,pred_xgb)
scores.append(score)
print('Train mae:',np.mean(score_train))
print('Val mae',np.mean(scores))
训练集和验证集的MAE分别为:
Train mae: 628.7640032655389
Val mae 714.982737201206
分别定义xgb和lgb模型函数:
def build_model_xgb(x_train,y_train):
model = xgb.XGBRegressor(n_estimators=150, learning_rate=0.1, gamma=0, subsample=0.8,\
colsample_bytree=0.9, max_depth=7) #, objective ='reg:squarederror'
model.fit(x_train, y_train)
return model
def build_model_lgb(x_train,y_train):
estimator = lgb.LGBMRegressor(num_leaves=127,n_estimators = 150)
param_grid = {
'learning_rate': [0.01, 0.05, 0.1, 0.2],
}
gbm = GridSearchCV(estimator, param_grid)
gbm.fit(x_train, y_train)
return gbm
切分数据集(Train,Val)进行模型训练,评价和预测:
## Split data with val
x_train,x_val,y_train,y_val = train_test_split(X_data,Y_data,test_size=0.3)
print('Train lgb...')
model_lgb = build_model_lgb(x_train,y_train)
val_lgb = model_lgb.predict(x_val)
MAE_lgb = mean_absolute_error(y_val,val_lgb)
print('MAE of val with lgb:',MAE_lgb)
print('Predict lgb...')
model_lgb_pre = build_model_lgb(X_data,Y_data)
subA_lgb = model_lgb_pre.predict(X_test)
print('Sta of Predict lgb:')
Sta_inf(subA_lgb)
lgb预测结果的MAE以及预测数据的统计特征如下:
MAE of val with lgb: 690.5215735944785
Sta of Predict lgb:
_min -1339.23962259458
_max: 91324.72689961622
_mean 5909.949573700309
_ptp 92663.9665222108
_std 7352.61037521163
_var 54060879.3296697
同理,xgb预测结果的MAE和预测数据的统计特征如下:
MAE of val with xgb: 712.259832479318
Sta of Predict xgb:
_min -378.67053
_max: 91137.12
_mean 5909.634
_ptp 91515.79
_std 7343.3955
_var 53925460.0
由此可见lgb的预测准确度更高。下面对两个模型的结果进行加权融合:
## 这里我们采取了简单的加权融合的方式
val_Weighted = (1-MAE_lgb/(MAE_xgb+MAE_lgb))*val_lgb+(1-MAE_xgb/(MAE_xgb+MAE_lgb))*val_xgb
val_Weighted[val_Weighted<0]=10 # 由于我们发现预测的最小值有负数,而真实情况下,price为负是不存在的,由此我们进行对应的后修正
print('MAE of val with Weighted ensemble:',mean_absolute_error(y_val,val_Weighted))
sub_Weighted = (1-MAE_lgb/(MAE_xgb+MAE_lgb))*subA_lgb+(1-MAE_xgb/(MAE_xgb+MAE_lgb))*subA_xgb
## 查看预测值的统计进行
plt.hist(Y_data)
plt.show()
plt.close()
此图为预测的价格分布(橙)和训练集价格分布(蓝),该结果显示对测试集各项输入属性的预测价格普遍在10000以下,且数量随价格升高而降低,这一趋势与训练集数据的价格趋势是一致的。
融合后模型的MAE如下:
MAE score:674.3673
该值小于lgb和xgb的结果,由此可见加权融合后的预测模型更为准确。
5. 任务分配
- 王宇彬,于明菲:数据的收集和预处理,数据分析,数据可视化,协助完成模型设计与实现;
- 韩秉峰,赵柏翔:算法实现,模型设计;
- 孙心桐:结果分析与汇总,文档编写;