数据导入
巧妇难为无米之炊,首先将数据导入,用pandas中的head函数对数据进行初步的分析,可以看到数据拥有的特征。
train_data = pd.read_csv(r'C:\Users\klh\Desktop\datawhale\used_car_train_20200313.csv', sep=' ')
test_data = pd.read_csv(r'C:\Users\klh\Desktop\datawhale\used_car_testA_20200313.csv', sep=' ')
train_data.head()
数据整体信息
print(train_data.info())
train_data.describe()
结果如下所示,可以看到数据特征的类型(数值型和object型)以及数据的统计分布(个数,平均值,中位数,方差,均值等),同时可以看到有些特征数据有缺失值,后面可以根据describe函数给出的统计分布数值对这些缺失值进行填充。
Data columns (total 31 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 SaleID 150000 non-null int64
1 name 150000 non-null int64
2 regDate 150000 non-null int64
3 model 149999 non-null float64
4 brand 150000 non-null int64
5 bodyType 145494 non-null float64
6 fuelType 141320 non-null float64
7 gearbox 144019 non-null float64
8 power 150000 non-null int64
9 kilometer 150000 non-null float64
10 notRepairedDamage 150000 non-null object
11 regionCode 150000 non-null int64
12 seller 150000 non-null int64
13 offerType 150000 non-null int64
14 creatDate 150000 non-null int64
15 price 150000 non-null int64
16 v_0 150000 non-null float64
17 v_1 150000 non-null float64
18 v_2 150000 non-null float64
19 v_3 150000 non-null float64
20 v_4 150000 non-null float64
21 v_5 150000 non-null float64
22 v_6 150000 non-null float64
23 v_7 150000 non-null float64
24 v_8 150000 non-null float64
25 v_9 150000 non-null float64
26 v_10 150000 non-null float64
27 v_11 150000 non-null float64
28 v_12 150000 non-null float64
29 v_13 150000 non-null float64
30 v_14 150000 non-null float64
缺失值分析
前面经过info函数可以看到有些特征缺少一部分值。训练集中fuelType,gearbox,body Type,model存在缺失值,而测试集model不存在缺失值。由于训练集model缺失值占比过小,可以忽略不计。其他缺失值则可以用均值或极大似然估计进行填充。
def missing_values(df):
data_na = pd.DataFrame(df.isnull().sum(), columns={'missing'})
data_na['exist'] = len(df) - data_na['missing']
data_na['sum'] = len(df)
data_na['mRatio'] = data_na['missing'] / len(df) * 100
data_na['dtype'] = df.dtypes
data_na = data_na[data_na['missing'] > 0].reset_index().sort_values(by=['missing', 'index'], ascending=[False, True])
data_na.set_index('index', inplace=True)
return data_na
missing_values(train_data)
missing_values(test_data)
Label分布
y = train_data['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)
从上图可以看出label拟合效果最好的是johnson分布,这种分布是正态分布的一种转变,Johnson分布已经被用在质量控制过程中来描述非正态过程,然后可被转换成正态分布用在标准试验中。
log变换
plt.hist(np.log(train_data['price']), orientation = 'vertical',histtype = 'bar', color ='red')
plt.show()
可以看出log变换后拟合正态分布。
数字特征
unique特征
categorical_feas = ['name', 'model', 'brand', 'bodyType', 'fuelType', 'gearbox', 'notRepairedDamage', 'regionCode',]
for feature in categorical_feas:
print(feature + "的特征分布如下:")
print(train_data[feature].value_counts())
if feature != 'price':
plt.hist(data_all[feature], bins=3)
plt.show()
数字特征相关性
numeric_feas = ['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' ,'price']
price_numeric = train_data[numeric_feas]
correlation = price_numeric.corr()
print(correlation['price'].sort_values(ascending = False),'\n')
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)
sns.set()
columns = ['price', 'v_12', 'v_8' , 'v_0', 'power', 'v_5', 'v_2', 'v_6', 'v_1', 'v_14']
sns.pairplot(train_data[columns],size = 2 ,kind ='scatter',diag_kind='kde')
plt.show()
上图反映了label与各个特征之间相关性强弱,后续对特征选择有一定的帮助。
总结
EDA处理是对比赛数据产生一定的了解,方便后续特征工程的进行和模型的构建,要想获得好的分数,EDA不可或缺。本文从数据本身和数据之间进行分析,对于label需要拟合正态分布,是因为特征正态分布。分析特征与label的相关性强弱,可以获得对label影响占比大的特征,从而可以省去弱相关性的特征。
参考
https://tianchi.aliyun.com/notebook-ai/detail?spm=5176.12281897.0.0.36ae39a9H87DkC&postId=95457