Task2:数据的探索性分析(EDA)
- 什么是EDA
- EDA目标
- 主要工作
- 导入、观察数据
- 数据总览
- 相关统计量
- 数据类型
- 数据检测
- 缺失值检测
- 异常值检测
- 预测分布
- 总体分布概况(无界约翰逊分布等)
- 查看偏度和峰度
- 查看预测值的具体频数
- 特征分析
- 类别特征
- unique分布
- 可视化
- 箱型图
- 小提琴图
- 柱形图
- 可视化每个类别特征频数
- 数字特征
- 相关性分析
- 特征的偏度和峰值
- 数字特征分布可视化
- 数字特征相互关系可视化
- 多变量互相回归关系可视化
什么是EDA
探索性数据分析(Exploratory Data Analysis,简称EDA),是指对已有的数据(特别是调查或观察得来的原始数据)在尽量少的先验假定下进行探索,通过作图、制表、方程拟合、计算特征量等手段探索数据的结构和规律的一种数据分析方法。特别是当我们面对各种杂乱的“脏数据”,往往不知所措,不知道从哪里开始了解目前拿到手上的数据时候,探索性数据分析就非常有效。探索性数据分析是上世纪六十年代提出,其方法有美国统计学家John Tukey提出的。
- 定性数据:描述性质
a) 定类:按名称分类——血型、城市
b) 定序:有序分类——成绩(A B C) - 定量数据:描述数量
a) 定距:可以加减——温度、日期
b) 定比:可以乘除——价格、重量
查看天池文档,观看数据的现实意义.
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个匿名特征 |
EDA目标
1.了解数据集,初步分析;
2.了解比数据集中各变量间的关系;
3.数据处理/特征工程;
4.对数据集进行图文总结, 分析特征和label的关联性。
探索性分析的步骤
- 形成假设,确定主题去探索
- 清理数据,处理脏数据
- 评价数据质量,可以对不同质量的数据作权重处理
- 数据报表
- 探索分析每个变量
- 探索每个自变量与因变量之间的关系
- 探索每个自变量之间的相关性
- 从不同的维度来分析数据
主要工作
导入、观察数据
导入相关的库
import warnings
warnings.filterwarnings('ignore')
# 避免出现:代码正常运行,但提示警告
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import missingno as msno
## 通过Pandas载入数据
Train_data = pd.read_csv('datalab/231784/used_car_train_20200313.csv', sep=' ')
Test_data = pd.read_csv('datalab/231784/used_car_testA_20200313.csv', sep=' ')
# 源文件指定为' '分隔符,以防报错
Train_data.head(3).append(Train_data.tail(3))
# 查看训练集前3行和后3行的数据,结果略
Train_data.shape # 输出:(150000, 31)
Test_data.shape # 输出:(50000, 30)
# 训练集比测试集多1列:'price'
Train_data.describe()
# 通过describe查看相关统计量,掌握数据的大概范围以及对异常值的判断
Train_data.info()
# 熟悉数据类型,其中'notRepairedDamage'是object类型,其余都是数值
Train_data.isnull().sum()
# 查看每个字段的缺失情况(汇总)
关于缺失值:
1.缺失值个数如果很小一般选择填充;
2.如果使用lgb等树模型可以直接空缺,让树自己去优化;
3.如果nan存在的过多,可以删掉。
Train_data['notRepairedDamage'].value_counts()
# 对'notRepairedDamage'的值类型进行计数
# 输出:0.0 111361
# - 24324
# 1.0 14315
Train_data['notRepairedDamage'].replace('-', np.nan, inplace=True)
# 将‘ - ’替换成nan
其中我们发现,"seller"和"offerType"特征严重倾斜,一般不会对预测有帮助,故先删掉:
Train_data["seller"].value_counts()
Train_data["offerType"].value_counts()
查看预测值‘price’的分布:
# 查看偏度和峰度
sns.distplot(Train_data['price']);
print("Skewness: %f" % Train_data['price'].skew())
print("Kurtosis: %f" % Train_data['price'].kurt())
# 输出:Skewness: 3.346487
# Kurtosis: 18.995183
绘制训练集各变量偏度、峰度的概率分布:
sns.distplot(Train_data.skew(),color='blue',axlabel ='Skewness')
sns.distplot(Train_data.kurt(),color='orange',axlabel ='Kurtness')
# 查看预测值price的具体频数
plt.hist(Train_data['price'], orientation = 'vertical',histtype = 'bar', color ='red')
plt.title( 'price')
plt.show()
对数变换之后的分布较均匀:
plt.hist(np.log(Train_data['price']), orientation = 'vertical',histtype = 'bar', color ='red')
plt.title( 'log-price')
plt.show()
1.类别特征
categorical_features = ['name', 'model', 'brand', 'bodyType', 'fuelType', 'gearbox', 'notRepairedDamage', 'regionCode',]
2.数字特征
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' ]
3.特征nunique分布
# 特征nunique分布
for cat_fea in categorical_features:
print(cat_fea + "的特征分布如下:")
print("{}特征有{}个不同的值".format(cat_fea, Train_data[cat_fea].nunique()))
print(Train_data[cat_fea].value_counts())
结果:
name特征有99662个不同的值
model特征有248个不同的值
brand特征有40个不同的值
bodyType特征有8个不同的值
fuelType特征有7个不同的值
gearbox特征有2个不同的值
notRepairedDamage特征有2个不同的值
regionCode特征有7905个不同的值
查看训练集的类别特征分布:
for cat_fea in categorical_features:
print(cat_fea + "的特征分布如下:")
print("{}特征有个{}不同的值".format(cat_fea, Train_data[cat_fea].nunique()))
print(Train_data[cat_fea].value_counts())
相关性可视化:
price_numeric = Train_data[numeric_features]
correlation = price_numeric.corr()
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)
各数字特征分布的可视化:
f = pd.melt(Train_data, value_vars=numeric_features)
g = sns.FacetGrid(f, col="variable", col_wrap=2, sharex=False, sharey=False)
g = g.map(sns.distplot, "value")
各数字特征关系的可视化:
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()
生成一份数据预览报告:
用pandas_profiling生成数据报告
用pandas_profiling生成一个较为全面的可视化和数据报告(较为简单、方便) 最终打开html文件即可
import pandas_profiling
pfr = pandas_profiling.ProfileReport(Train_data)
pfr.to_file("./example.html")