Datawhale 零基础入门数据挖掘-Task2 数据分析
二、 EDA-数据探索性分析
Tip:此部分为零基础入门数据挖掘的 Task2 EDA-数据探索性分析 部分,带你来了解数据,熟悉数据,和数据做朋友,欢迎大家后续多多交流。
赛题:零基础入门数据挖掘 - 二手车交易价格预测
地址:https://tianchi.aliyun.com/competition/entrance/231784/introduction?spm=5176.12281957.1004.1.38b02448ausjSX
2.1 EDA目标
-
EDA的价值主要在于熟悉数据集,了解数据集,对数据集进行验证来确定所获得数据集可以用于接下来的机器学习或者深度学习使用。
-
当了解了数据集之后我们下一步就是要去了解变量间的相互关系以及变量与预测值之间的存在关系。
-
引导数据科学从业者进行数据处理以及特征工程的步骤,使数据集的结构和特征集让接下来的预测问题更加可靠。
-
完成对于数据的探索性分析,并对于数据进行一些图表或者文字总结并打卡。
2.2 内容介绍
- 载入各种数据科学以及可视化库:
- 数据科学库 pandas、numpy、scipy;
- 可视化库 matplotlib、seabon;
- 其他;
- 载入数据:
- 载入训练集和测试集;
- 简略观察数据(head()+shape)
-
- 数据总览:
- 通过describe()来熟悉数据的相关统计量
- 通过info()来熟悉数据类型
- 判断数据缺失和异常
- 查看每列的存在nan情况
- 异常值检测
- 了解预测值的分布
- 总体分布概况(无界约翰逊分布等)
- 查看skewness and kurtosis
- 查看预测值的具体频数
- 特征分为类别特征和数字特征,并对类别特征查看unique分布
- 数字特征分析
- 相关性分析
- 查看几个特征得 偏度和峰值
- 每个数字特征得分布可视化
- 数字特征相互之间的关系可视化
- 多变量互相回归关系可视化
- 类型特征分析
- unique分布
- 类别特征箱形图可视化
- 类别特征的小提琴图可视化
- 类别特征的柱形图可视化类别
- 特征的每个类别频数可视化(count_plot)
- 用pandas_profiling生成数据报告
2.3 代码示例
2.3.1 载入各种数据科学以及可视化库
#coding:utf-8
#导入warnings包,利用过滤器来实现忽略警告语句。
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
## 1) 载入训练集和测试集;
Train_data = pd.read_csv('data/used_car_train_20200313.csv', sep=' ')
Test_data = pd.read_csv('data/used_car_testA_20200313.csv', sep=' ')
## 2) 简略观察数据(head()+shape)
Train_data.head().append(Train_data.tail())
#通过shape()可以快速了解数据量和特征量
Train_data.shape
(5816, 31)
2.3.2 总览数据概况
(1)通过describe快速了解每列的统计量,个数count、平均值mean、
方差std、最小值min、中位数25% 50% 75% 、以及最大值,掌握数据大概的范围以及每个值的异常值的判断。(注意异常值有时候是9999或者-1)
Train_data.describe()
(2)info 通过info来了解数据每列的type,有助于了解是否存在除了nan
以外的特殊符号异常。
Train_data.info()
2.3.3 判断数据缺失和异常
## 1) 查看每列的存在nan情况
Train_data.isnull().sum()
# nan可视化
missing = Train_data.isnull().sum()
missing = missing[missing > 0]
missing.sort_values(inplace=True)
missing.plot.bar()
通过以上两句可以很直观的了解哪些列存在 “nan”, 并可以把nan的个数打印,主要的目的在于 nan存在的个数是否真的很大,如果很小一般选择填充,如果使用lgb等树模型可以直接空缺,让树自己去优化,但如果nan存在的过多、可以考虑删掉。
info中会发现notRepairedDamage为Object类型,进行下一步了解该特征。
Train_data['notRepairedDamage'].value_counts()
值为“-”的有949个,其实就是空值,可以将其替换为nan
Train_data['notRepairedDamage'].replace('-', np.nan, inplace=True)
Train_data["seller"].value_counts()
0 5816
Name: seller, dtype: int64
Train_data["offerType"].value_counts()
0 5816
Name: offerType, dtype: int64
进一步了解会发现seller、offerType两个特征数据倾斜严重,不具备代表性,可以删除。
2.3.5 了解预测值的分布
Train_data['price']
Train_data['price'].value_counts()
## 1) 总体分布概况(无界约翰逊分布等)
import scipy.stats as st
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)
由于价格不服从正太分布,需要进行转换,可以看出最佳拟合是无界约翰逊分布。
2) 查看skewness and kurtosis
sns.distplot(Train_data['price']);
print("Skewness: %f" % Train_data['price'].skew())
print("Kurtosis: %f" % Train_data['price'].kurt())
## 3) 查看预测值的具体频数
plt.hist(Train_data['price'], orientation = 'vertical',histtype = 'bar', color ='red')
plt.show()
这里可以考虑将过大的数据(实际频数少)当作异常值删除。
# 特征nunique分布
for cat_fea in categorical_features:
print(cat_fea + "的特征分布如下:")
print("{}特征有个{}不同的值".format(cat_fea, Test_data[cat_fea].nunique()))
print(Test_data[cat_fea].value_counts())
2.4 经验总结
初次学习数据挖掘,打破了以往对流程的认知,学习了在数据分析阶段各种工具以及了解了EDA的重要性。