欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

天池二手车交易价格预测— 赛题理解 + 数据分析

程序员文章站 2022-05-16 21:00:47
...

1、 赛题理解

1.1 学习目标

赛题以二手车市场为背景,要求选手预测二手汽车的交易价格,这是一个典型的回归问题。通过这道赛题来引导大家走进AI数据竞赛的世界,主要针对于于竞赛新人进行自我练习、自我提高。

1.2 了解赛题

- 赛题概况
- 数据概况
- 预测指标
- 分析赛题

1.2.1 赛题概况

比赛要求参赛选手根据给定的数据集,建立模型,二手汽车的交易价格。

来自 Ebay Kleinanzeigen 报废的二手车,数量超过 370,000,包含 20 列变量信息,为了保证
比赛的公平性,将会从中抽取 10 万条作为训练集,5 万条作为测试集 A,5 万条作为测试集
B。同时会对名称、车辆类型、变速箱、model、燃油类型、品牌、公里数、价格等信息进行
脱敏。

通过这道赛题来引导大家走进 AI 数据竞赛的世界,主要针对于于竞赛新人进行自我练
习、自我提高。

1.2.2 数据概况


一般而言,对于数据在比赛界面都有对应的数据概况介绍(匿名特征除外),说明列的性质特征。了解列的性质会有助于我们对于数据的理解和后续分析。
Tip:匿名特征,就是未告知数据列所属的性质的特征列。


train.csv

  • name - 汽车编码
  • regDate - 汽车注册时间
  • model - 车型编码
  • brand - 品牌
  • bodyType - 车身类型
  • fuelType - 燃油类型
  • gearbox - 变速箱
  • power - 汽车功率
  • kilometer - 汽车行驶公里
  • notRepairedDamage - 汽车有尚未修复的损坏
  • regionCode - 看车地区编码
  • seller - 销售方
  • offerType - 报价类型
  • creatDate - 广告发布时间
  • price - 汽车价格
  • v_0’, ‘v_1’, ‘v_2’, ‘v_3’, ‘v_4’, ‘v_5’, ‘v_6’, ‘v_7’, ‘v_8’, ‘v_9’, ‘v_10’, ‘v_11’, ‘v_12’, ‘v_13’,‘v_14’(根据汽车的评论、标签等大量信息得到的embedding向量)【人工构造 匿名特征】

数字全都脱敏处理,都为label encoding形式,即数字形式

1.2.3 预测指标


本赛题的评价标准为MAE(Mean Absolute Error):

MAE=i=1nyiy^in MAE=\frac{\sum_{i=1}^{n}\left|y_{i}-\hat{y}_{i}\right|}{n}
其中yiy_{i}代表第ii个样本的真实值,其中y^i\hat{y}_{i}代表第ii个样本的预测值。


一般问题评价指标说明:

什么是评估指标:

评估指标即是我们对于一个模型效果的数值型量化。(有点类似与对于一个商品评价打分,而这是针对于模型效果和理想效果之间的一个打分)

一般来说分类和回归问题的评价指标有如下一些形式:

分类算法常见的评估指标如下:

  • 对于二类分类器/分类算法,评价指标主要有accuracy, [Precision,Recall,F-score,Pr曲线],ROC-AUC曲线。
  • 对于多类分类器/分类算法,评价指标主要有accuracy, [宏平均和微平均,F-score]。

对于回归预测类常见的评估指标如下:

  • 平均绝对误差(Mean Absolute Error,MAE),均方误差(Mean Squared Error,MSE),平均绝对百分误差(Mean Absolute Percentage Error,MAPE),均方根误差(Root Mean Squared Error), R2(R-Square)

平均绝对误差
平均绝对误差(Mean Absolute Error,MAE):平均绝对误差,其能更好地反映预测值与真实值误差的实际情况,其计算公式如下:
MAE=1Ni=1Nyiy^i MAE=\frac{1}{N} \sum_{i=1}^{N}\left|y_{i}-\hat{y}_{i}\right|

均方误差
均方误差(Mean Squared Error,MSE),均方误差,其计算公式为:
MSE=1Ni=1N(yiy^i)2 MSE=\frac{1}{N} \sum_{i=1}^{N}\left(y_{i}-\hat{y}_{i}\right)^{2}

R2(R-Square)的公式为
残差平方和:
SSres=(yiy^i)2 SS_{res}=\sum\left(y_{i}-\hat{y}_{i}\right)^{2}
总平均值:
SStot=(yiyi)2 SS_{tot}=\sum\left(y_{i}-\overline{y}_{i}\right)^{2}

其中y\overline{y}表示yy的平均值
得到R2R^2表达式为:
R2=1SSresSStot=1(yiy^i)2(yiy)2 R^{2}=1-\frac{SS_{res}}{SS_{tot}}=1-\frac{\sum\left(y_{i}-\hat{y}_{i}\right)^{2}}{\sum\left(y_{i}-\overline{y}\right)^{2}}
R2R^2用于度量因变量的变异中可由自变量解释部分所占的比例,取值范围是 0~1,R2R^2越接近1,表明回归平方和占总平方和的比例越大,回归线与各观测点越接近,用x的变化来解释y值变化的部分就越多,回归的拟合程度就越好。所以R2R^2也称为拟合优度(Goodness of Fit)的统计量。

yiy_{i}表示真实值,y^i\hat{y}_{i}表示预测值,yi\overline{y}_{i}表示样本均值。得分越高拟合效果越好。

1.2.4. 分析赛题

  1. 此题为传统的数据挖掘问题,通过数据科学以及机器学习深度学习的办法来进行建模得到结果。
  2. 此题是一个典型的回归问题。
  3. 主要应用xgb、lgb、catboost,以及pandas、numpy、matplotlib、seabon、sklearn、keras等等数据挖掘常用库或者框架来进行数据挖掘任务。
  4. 通过EDA来挖掘数据的联系和自我熟悉数据。

2、数据分析

2.1 导入相关函数工具箱

## 基础工具
import numpy as np
import pandas as pd
import warnings
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.special import jn
from IPython.display import display, clear_output
import time
## 导入warnings包,利用过滤器来实现忽略警告语句。
warnings.filterwarnings('ignore')

## 模型预测的
from sklearn import linear_model
from sklearn import preprocessing
from sklearn.svm import SVR
from sklearn.ensemble import RandomForestRegressor,GradientBoostingRegressor
## 数据降维处理的
from sklearn.decomposition import PCA,FastICA,FactorAnalysis,SparsePCA
import lightgbm as lgb
import xgboost as xgb
## 参数搜索和评价的
from sklearn.model_selection import GridSearchCV,cross_val_score,StratifiedKFold,train_test_split
from sklearn.metrics import mean_squared_error, mean_absolute_error

2.2 读取数据

## 通过Pandas对于数据进行读取 (pandas是一个很友好的数据读取函数库)
Traindata = pd.read_csv('datalab/231784/used_car_train_20200313.csv', sep=' ')
Testdata = pd.read_csv('datalab/231784/used_car_testA_20200313.csv', sep=' ')
## 输出数据的大小信息
print('Train data shape:',Traindata.shape)
print('Test data shape:',Testdata.shape)

2.3 数据浏览

## 通过.head() 简要浏览读取数据的形式
Traindata.head()

天池二手车交易价格预测— 赛题理解 + 数据分析

## 通过 .info() 简要可以看到对应一些数据列名,以及NAN缺失信息
Traindata.info()

天池二手车交易价格预测— 赛题理解 + 数据分析

Testdata.info()

天池二手车交易价格预测— 赛题理解 + 数据分析

2.4 相关字符对应含义

天池二手车交易价格预测— 赛题理解 + 数据分析

2.5 观察数据概况

## 通过 .describe() 可以查看数值特征列的一些统计信息
Traindata.describe()

天池二手车交易价格预测— 赛题理解 + 数据分析

Testdata.describe()

天池二手车交易价格预测— 赛题理解 + 数据分析

#观察除匿名特征外的数据概况
Traindata.describe().iloc[:,:15]

发现表格中offerType特征中数据全为0,很可能是一项无用的特征。seller中均值很小,而且第三分位点和最大值不同,说明存在一定数据倾斜。power中出现异常值。

天池二手车交易价格预测— 赛题理解 + 数据分析

2.6 判断数据缺失—查看每列的存在nan情况

Traindata.isnull().sum()

天池二手车交易价格预测— 赛题理解 + 数据分析

Testdata.isnull().sum()

天池二手车交易价格预测— 赛题理解 + 数据分析

2.7 可视化

missing = Traindata.isnull().sum()
missing = missing[missing > 0]#筛选出有缺失值的数据行
missing.sort_values(inplace=True)#排序
missing.plot.bar()#柱状图

天池二手车交易价格预测— 赛题理解 + 数据分析

msno.matrix(Testdata.sample(250))#可看到每个变量的缺失情况

天池二手车交易价格预测— 赛题理解 + 数据分析

2.8 判断数据异常

由info方法输出数据类型中发现除了notRepairedDamage 为object类型,其他都为数字,这里把这列的的不同值显示。

Traindata['notRepairedDamage'].value_counts()
Testdata['notRepairedDamage'].value_counts()
Traindata['notRepairedDamage'].replace('-', np.nan, inplace=True)
Testdata['notRepairedDamage'].replace('-', np.nan, inplace=True)
Traindata["seller"].value_counts()
Traindata["offerType"].value_counts()

0 150000
Name: offerType, dtype: int64
由于两个类别特征严重倾斜,一般不会对预测有什么帮助,故删掉。

del Traindata["seller"]
del Traindata["offerType"]
del Testdata["seller"]
del Testdata["offerType"]

2.9 了解预测值的分布

1)总体分布概况(*约翰逊分布等)

import scipy.stats as st
y = Traindata['price']
plt.figure(1); plt.title('Johnson SU')
sns.distplot(y, kde=False, fit=st.johnsonsu)
plt.figure(2); plt.title('Normal')
sns.distplot(y, kde=False, fit=st.norm)
plt.figure(3); plt.title('Log Normal')
sns.distplot(y, kde=False, fit=st.lognorm)

天池二手车交易价格预测— 赛题理解 + 数据分析由于价格不服从正态分布,因此在进行回归之前,它必须进行转换。虽然对数变换做得很好,但最佳拟合是*约翰逊分布。

2)查看数据的偏度和峰度

sns.distplot(Traindata['price']);
print("Skewness: %f" % Traindata['price'].skew())
print("Kurtosis: %f" % Traindata['price'].kurt())

天池二手车交易价格预测— 赛题理解 + 数据分析
Skewness > 0 ,正偏差数值较大,为正偏或右偏。长尾巴拖在右边,数据右端有较多的极端值。Kurtosis>0 比正态分布的高峰更加陡峭——尖顶峰。

3)查看预测值的具体频数

plt.hist(Traindata['price'], orientation = 'vertical',histtype = 'bar', color ='red')
plt.show()

天池二手车交易价格预测— 赛题理解 + 数据分析查看频数, 发现大于20000得值极少,即将这些当作特殊得值(异常值)直接用填充或者删掉。

4) log变换之后的分布较均匀,可以进行log变换进行预测

plt.hist(np.log(Traindata['price']), orientation = 'vertical',histtype = 'bar', color ='red') 
plt.show()

天池二手车交易价格预测— 赛题理解 + 数据分析

2.10 特征分为类别特征和数字特征

对类别特征查看unique分布

numeric_features = ['power', 'kilometer', 'v_0', 'v_1', 'v_2', 'v_3', 'v_4', 'v_5', 'v_6', 'v_7', 'v_8', 'v_9', 'v_10', 'v_11', 'v_12', 'v_13','v_14' ]
categorical_features = ['name', 'model', 'brand', 'bodyType', 'fuelType', 'gearbox', 'notRepairedDamage', 'regionCode']
# 特征nunique分布
for cat_fea in categorical_features:
    print(cat_fea + "的特征分布如下:")
    print("{}特征有个{}不同的值".format(cat_fea, Traindata[cat_fea].nunique()))
    print(Traindata[cat_fea].value_counts())

name的特征分布如下:
name特征有个99662不同的值
708 282
387 282
55 280
1541 263
203 233
53 221
713 217
290 197
1186 184
911 182
2044 176
1513 160
1180 158
631 157
893 153
2765 147
473 141
1139 137
1108 132
444 129
306 127
2866 123
2402 116
533 114
1479 113
422 113
4635 110
725 110
964 109
1373 104

89083 1
95230 1
164864 1
173060 1
179207 1
181256 1
185354 1
25564 1
19417 1
189324 1
162719 1
191373 1
193422 1
136082 1
140180 1
144278 1
146327 1
148376 1
158621 1
1404 1
15319 1
46022 1
64463 1
976 1
3025 1
5074 1
7123 1
11221 1
13270 1
174485 1
Name: name, Length: 99662, dtype: int64
model的特征分布如下:
model特征有个248不同的值
0.0 11762
19.0 9573
4.0 8445
1.0 6038
29.0 5186
48.0 5052
40.0 4502
26.0 4496
8.0 4391
31.0 3827
13.0 3762
17.0 3121
65.0 2730
49.0 2608
46.0 2454
30.0 2342
44.0 2195
5.0 2063
10.0 2004
21.0 1872
73.0 1789
11.0 1775
23.0 1696
22.0 1524
69.0 1522
63.0 1469
7.0 1460
16.0 1349
88.0 1309
66.0 1250

141.0 37
133.0 35
216.0 30
202.0 28
151.0 26
226.0 26
231.0 23
234.0 23
233.0 20
198.0 18
224.0 18
227.0 17
237.0 17
220.0 16
230.0 16
239.0 14
223.0 13
236.0 11
241.0 10
232.0 10
229.0 10
235.0 7
246.0 7
243.0 4
244.0 3
245.0 2
209.0 2
240.0 2
242.0 2
247.0 1
Name: model, Length: 248, dtype: int64
brand的特征分布如下:
brand特征有个40不同的值
0 31480
4 16737
14 16089
10 14249
1 13794
6 10217
9 7306
5 4665
13 3817
11 2945
3 2461
7 2361
16 2223
8 2077
25 2064
27 2053
21 1547
15 1458
19 1388
20 1236
12 1109
22 1085
26 966
30 940
17 913
24 772
28 649
32 592
29 406
37 333
2 321
31 318
18 316
36 228
34 227
33 218
23 186
35 180
38 65
39 9
Name: brand, dtype: int64
bodyType的特征分布如下:
bodyType特征有个8不同的值
0.0 41420
1.0 35272
2.0 30324
3.0 13491
4.0 9609
5.0 7607
6.0 6482
7.0 1289
Name: bodyType, dtype: int64
fuelType的特征分布如下:
fuelType特征有个7不同的值
0.0 91656
1.0 46991
2.0 2212
3.0 262
4.0 118
5.0 45
6.0 36
Name: fuelType, dtype: int64
gearbox的特征分布如下:
gearbox特征有个2不同的值
0.0 111623
1.0 32396
Name: gearbox, dtype: int64
notRepairedDamage的特征分布如下:
notRepairedDamage特征有个2不同的值
0.0 111361
1.0 14315
Name: notRepairedDamage, dtype: int64
regionCode的特征分布如下:
regionCode特征有个7905不同的值
419 369
764 258
125 137
176 136
462 134
428 132
24 130
1184 130
122 129
828 126
70 125
827 120
207 118
1222 117
2418 117
85 116
2615 115
2222 113
759 112
188 111
1757 110
1157 109
2401 107
1069 107
3545 107
424 107
272 107
451 106
450 105
129 105

6324 1
7372 1
7500 1
8107 1
2453 1
7942 1
5135 1
6760 1
8070 1
7220 1
8041 1
8012 1
5965 1
823 1
7401 1
8106 1
5224 1
8117 1
7507 1
7989 1
6505 1
6377 1
8042 1
7763 1
7786 1
6414 1
7063 1
4239 1
5931 1
7267 1
Name: regionCode, Length: 7905, dtype: int64

2.11 数字特征分析

1)相关性分析

numeric_features.append('price')
price_numeric = Traindata[numeric_features]
correlation = price_numeric.corr()
print(correlation['price'].sort_values(ascending = False),'\n')#输出各个变量与价格的相关性

price 1.000000
v_12 0.692823
v_8 0.685798
v_0 0.628397
power 0.219834
v_5 0.164317
v_2 0.085322
v_6 0.068970
v_1 0.060914
v_14 0.035911
v_13 -0.013993
v_7 -0.053024
v_4 -0.147085
v_9 -0.206205
v_10 -0.246175
v_11 -0.275320
kilometer -0.440519
v_3 -0.730946
Name: price, dtype: float64

f , ax = plt.subplots(figsize = (7, 7))

plt.title('Correlation of Numeric Features with Price',y=1,size=16)

sns.heatmap(correlation,square = True,  vmax=0.8)

天池二手车交易价格预测— 赛题理解 + 数据分析
2)查看几个特征的偏度和峰值

for col in numeric_features:
    print('{:15}'.format(col), 
          'Skewness: {:05.2f}'.format(Traindata[col].skew()) , 
          '   ' ,
          'Kurtosis: {:06.2f}'.format(Traindata[col].kurt())  
         )

power Skewness: 65.86 Kurtosis: 5733.45
kilometer Skewness: -1.53 Kurtosis: 001.14
v_0 Skewness: -1.32 Kurtosis: 003.99
v_1 Skewness: 00.36 Kurtosis: -01.75
v_2 Skewness: 04.84 Kurtosis: 023.86
v_3 Skewness: 00.11 Kurtosis: -00.42
v_4 Skewness: 00.37 Kurtosis: -00.20
v_5 Skewness: -4.74 Kurtosis: 022.93
v_6 Skewness: 00.37 Kurtosis: -01.74
v_7 Skewness: 05.13 Kurtosis: 025.85
v_8 Skewness: 00.20 Kurtosis: -00.64
v_9 Skewness: 00.42 Kurtosis: -00.32
v_10 Skewness: 00.03 Kurtosis: -00.58
v_11 Skewness: 03.03 Kurtosis: 012.57
v_12 Skewness: 00.37 Kurtosis: 000.27
v_13 Skewness: 00.27 Kurtosis: -00.44
v_14 Skewness: -1.19 Kurtosis: 002.39
price Skewness: 03.35 Kurtosis: 019.00

3)每个数字特征分布可视化

f = pd.melt(Traindata, value_vars=numeric_features)
g = sns.FacetGrid(f, col="variable",  col_wrap=2, sharex=False, sharey=False)
g = g.map(sns.distplot, "value")

天池二手车交易价格预测— 赛题理解 + 数据分析
从 上图中可以看出匿名特征相对分布均匀。

4)数字特征相互之间的关系可视化

sns.set()
columns = ['price', 'v_12', 'v_8' , 'v_0', 'power', 'v_5',  'v_2', 'v_6', 'v_1', 'v_14']
sns.pairplot(Traindata[columns],size = 2 ,kind ='scatter',diag_kind='kde')
plt.show()

天池二手车交易价格预测— 赛题理解 + 数据分析

相关标签: 数据挖掘