想要看更加舒服的排版、更加准时的推送
关注公众号“不太灵光的程序员”
干货推送,微信随时解答你的疑问 ????????????

数据挖掘前我们要去熟悉数据,了解变量间的相互关系以及变量与预测值之间的存在关系,借助可视化工具帮助我们更好的进行分析。
在这里插入图片描述
根据赛题代码要求创建了目录,下载数据我们可以发现,已经区分了训练集和测试集。

下面我们一起来分析二手车交易数据。

1. 载入各种数据科学以及可视化库

  1. 数据科学库 pandas、numpy、scipy;
  2. 可视化库 matplotlib、seabon;

没有安装的 使用 pip install 安装

# coding=gbk
import numpy as np
import pandas as pd
# 绘图函数库
import matplotlib.pyplot as plt
import seaborn as sns
import missingno as msno

# 展示完整数据集
pd.set_option('display.expand_frame_repr', False)

2. 载入数据

二手车的训练数据集数据有15W个样本,该数据集一共包含31个变量,其中15个匿名特征变量。

price 二手车交易价格(预测目标)

CSV_FILE_PATH = '../data/used_car_train_20200313.csv'
# 读取csv, 文件分隔符是空格
df = pd.read_csv(CSV_FILE_PATH, sep=' ')

2.1. 特征集

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.2. 简略观察数据

要养成看数据集的head()以及shape的习惯,这会让你每一步更放心,导致接下里的连串的错误, 如果对自己的pandas等操作不放心,建议执行一步看一下,这样会有效的方便你进行理解函数并进行操作。

# 数据集前后50条数据
print(df.head(50))
print(df.tail(50))

# 数据列名
print(df.columns.values)

# 获取数据的 总行数 和 列数
print(df.shape)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.数据总览

3.1. 通过describe()对于特征进行一些统计描述

describe种有每列的统计量,个数count、平均值mean、方差std、最小值min、中位数25% 50% 75% 、以及最大值。

看这个信息主要是瞬间掌握数据的大概的范围以及每个值的异常值的判断, 比如有的时候会发现999 9999 -1 等值这些其实都是nan的另外一种表达方式,有的时候需要注意下。

3.2. 通过info()来熟悉数据类型

info()函数用于提供一个数据集的基本信息(或者总结)。

通常在读取一个数据表后,我们可以使用该函数来查看数据表的一些基本信息。

info 通过info来了解数据每列的type,有助于了解是否存在除了nan以外的特殊符号异常。

  1. <class ‘pandas.core.frame.DataFrame’>: 是说数据类型为DataFrame
    RangeIndex: 32 entries, 0 to 31: 有32条数据(32行),索引为0-31
  2. Data columns (total 12 columns): 该数据帧有12列
  3. column: 每列数据的列名
  4. Non-Null count: 每列数据的数据个数,缺失值NaN不作计算。可以看出上面disp和drat两列数据都有缺失值
  5. Dtype: 数据的类型
# 通过describe()对于特征进行一些统计描述
print(df.describe())

在这里插入图片描述

# 通过info()来熟悉数据类型
print(df.info())

在这里插入图片描述

4. 判断数据缺失和异常

通过以上两句可以很直观的了解哪些列存在 nan, 并可以把nan的个数打印,主要的目的在于 nan存在的个数是否真的很大。

如果很小一般选择填充,如果使用lgb等树模型可以直接空缺,让树自己去优化,但如果nan存在的过多、可以考虑删掉。

4.1. 查看每列的存在nan情况

# 查看每列的存在nan情况
print(pd.isnull(df))
# 查看每列的存在nan值的记录数
print(df.isnull().sum())

# nan可视化
missing = df.isnull().sum()
missing = missing[missing > 0]
missing.sort_values(inplace=True)
missing.plot.bar()
plt.show()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.2. 查看缺失值的分布情况

# 可视化看下缺省值
# 缺失值的分布情况
msno.matrix(df.sample(150000))
plt.show()

在这里插入图片描述

4.3. 查看有效值的占比情况

可视化有四列有缺省model、bodyType、fuelType、notRepairedDamage, notRepairedDamage缺省得最多

# 有效值的占比情况
msno.bar(df.sample(150000))
plt.show()

在这里插入图片描述

4.4. 异常值处理

可以发现除了notRepairedDamage为object类型,是数据格式不一致,这里我们使用value_counts查看notRepairedDamage几个不同值的情况。

可以看出来’-'也为空缺值,因为很多模型对nan有直接的处理,这里我们先不做处理,先替换成nan。

print(df['notRepairedDamage'].value_counts())
df['notRepairedDamage'].replace('-', np.nan, inplace=True)
print(df['notRepairedDamage'].value_counts())

处理前
在这里插入图片描述
处理后
在这里插入图片描述

4.5. 无效数据处理

以下两个类别(seller、offerType)特征严重倾斜,一般不会对预测有什么帮助,故这边先删掉,当然你也可以继续挖掘,但是一般意义不大。

# 分别查看一下每个特征的数据分布情况
for columns in df.columns.values:
    print(f"{columns} 的数值分布情况")
    print(df[columns].value_counts())

del df["seller"]
del df["offerType"]

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5. 了解预测值的分布

5.1. 总体分布概况

价格不服从正态分布,所以在进行回归之前,它必须进行转换。

虽然对数变换做得很好,但最佳拟合是无界约翰逊分布

# print(df['price'])
import scipy.stats as st

# 总体分布概况
y = df['price']
# 无界约翰逊分布 johnsonsu
plt.figure(1)
plt.title('Johnson SU')
sns.distplot(y, kde=False, fit=st.johnsonsu)

# 正态分布norm
plt.figure(2)
plt.title('Normal')
sns.distplot(y, kde=False, fit=st.norm)

# 对数正态分布 lognorm
plt.figure(3)
plt.title('Log Normal')
sns.distplot(y, kde=False, fit=st.lognorm)
plt.show()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.2. 查看skewness and kurtosis

偏度(Skewness)

Skewness 偏度是描述数据分布形态的统计量,其描述的是某总体取值分布的对称性,简单来说就是数据的不对称程度。。

偏度是三阶中心距计算出来的。
(1)Skewness = 0 ,分布形态与正态分布偏度相同。
(2)Skewness > 0 ,正偏差数值较大,为正偏或右偏。长尾巴拖在右边,数据右端有较多的极端值。
(3)Skewness < 0 ,负偏差数值较大,为负偏或左偏。长尾巴拖在左边,数据左端有较多的极端值。
(4)数值的绝对值越大,表明数据分布越不对称,偏斜程度大。

峰度(Kurtosis)

Kurtosis峰度是描述某变量所有取值分布形态陡缓程度的统计量,简单来说就是数据分布顶的尖锐程度。
峰度是四阶标准矩计算出来的。
(1)Kurtosis=0 与正态分布的陡缓程度相同。
(2)Kurtosis>0 比正态分布的高峰更加陡峭——尖顶峰
(3)Kurtosis<0 比正态分布的高峰来得平台——平顶峰

# 查看skewness
print("Skewness: %f" % df['price'].skew())

# 查看Kurtosis
print("Kurtosis: %f" % df['price'].kurt())
sns.distplot(df['price'])
plt.show()

sns.distplot(df.skew(), color='blue', axlabel='Skewness')
plt.show()
sns.distplot(df.kurt(), color='orange', axlabel='Kurtness')
plt.show()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.3. 查看预测值的具体频数

# 特征与标签组合的散点可视化 没有意义
df = df[["price", "fuelType", "gearbox", "power"]]
sns.pairplot(data=df, diag_kind='hist', hue='price')
plt.show()

# 查看预测值的具体频数
plt.hist(df['price'], orientation='vertical', histtype='bar', color='red')
plt.show()

查看频数, 大于20000得值极少,其实这里也可以把这些当作特殊得值(异常值)直接用填充或者删掉,再前面进行。

在这里插入图片描述

5.4. log变换

log变换 z之后的分布较均匀,可以进行log变换进行预测,这也是预测问题常用的trick。

对于一些标签和特征来说,分布不一定符合正态分布,而在实际的运算过程中则需要数据能够符合正态分布。

因此我们需要对特征进行log变化,使得数据在一定程度上可以符合正态分布。

进行log变化,就是对数据使用np.log(data+1) 加上1的目的是为了防止数据等于0,而不能进行log变化。

fig, ax = plt.subplots()
plt.hist(np.log(df['price']), orientation='vertical', bins=30, histtype='bar', color='#A9C5D3')
# 对log收入特征做直方图,标出中位数线的位置,即均值
plt.axvline(np.log(df['price']).quantile(), color='red', label='quantile line')
plt.legend(fontsize=18, loc='best')
plt.show()

在这里插入图片描述