EDA数据分析
数据挖掘学习任务二是对数据进行EDA–数据性探索分析。
EDA定义:
探索性数据分析(Exploratory Data Analysis,简称EDA),是指对已有的数据(特别是调查或观察得来的原始数据)在尽量少的先验假定下进行探索,通过作图、制表、方程拟合、计算特征量等手段探索数据的结构和规律的一种数据分析方法。
通过EDA,我们可以更好的了解和熟悉数据集,方便接下来的机器学习或深度学习使用。
EDA一般步骤:
加载数据(必要时可以对列名重命名)
查看数据整体概况
检测缺失值、异常值、重复值问题
了解预测值的分布概况
4.1 总体概况(无界约翰逊分布等)
4.2 查看skewness 和 kurtosis
4.3 查看预测值的具体频数特征分析
5.1 特征分类
5.2 按照不同类别的方法进行分析
(1)单变量分析(与预测值的相关性等)
(2)多变量分析(变量间的关系等)总结分析(数据报告)
以下以train_data数据集为样例进行数据分析分析学习。导入模块numpy、 pandas、 matplotlib、seaborn、missingno。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import missingno as msno
- missingno:缺失值可视化包
- Seaborn是基于matplotlib的Python可视化库。
2.1 数据加载
path = ""
Train_data = pd.read_csv(path+"used_car_train_20200313.csv", sep=' ')
2.2 查看数据概况
Train_data.shape # 数据集形状
Train_data.head().append(Train_data.tail()) # 显示前5条数据(head())和后5条数据(tail())
Train_data.describe() # 查看数据值列的汇总统计 可返回变量和观测的数量、缺失值和唯一值的数目、平均值、分位数等相关信息
Train_data.info() # 显示有关DataFrame的信息,包括索引dtype和列dtype,非空值和内存使用情况。
- df.info()结果:
2.3 检测缺失值、异常值、重复值
2.3.1 缺失值判断
Train_data.isnull().sum() # 将列中的空值情况统计出来
- df.isnull()
元素级别的判断,把对应的所有元素的位置都列出来,元素为空或者NA就显示True,否则就是False
结果:
2.3.2 缺失值可视化
# 缺失值可视化
is_missing = Train_data.isnull().sum()
missing = is_missing[is_missing>0] # 获取具有空值的列
missing.sort_values(inplace=True) # 排序
missing.plot.bar()
- sort_values(self,by,axis = 0,ascending = True,inplace = False,kind =’ quicksort ',na_position =‘last’,ignore_index = False )沿任一轴的值排序。
missingno矩阵查看缺失值
msno.matrix(Train_data.sample(250))
missingno条形图查看缺失值
msno.bar(Train_data.sample(1000))
2.3.3异常值检测
我们回过头看info()函数的结果,发现有一个object类型的数据。我们需要将它展开
Train_data["notRepairedDamage"].value_counts() # 统计唯一值
结果:
我们发现有 ‘-’ 这样的异常值,我们将其替换为缺失值:
Train_data["notRepairedDamage"].replace('-', np.nan, inplace=True) # 将数据中的'-'值替换为np.nan
倾斜值检测
for c in Train_data.columns:
print(c)
print(Train_data[c].value_counts())
print()
结果:
可以看到seller 和 offerType的数据十分不平衡,我们可以选择删除掉。
del Train_data["seller"]
del Train_data["offerType"]
2.4 查看预测值分布
import scipy.stats as st
Y_train = Train_data['price'] # 分离预测值
Y_train.value_counts()
# 总体分布概况可视化
y = Train_data['price']
plt.figure(1); plt.title('Johnson SU')
sns.distplot(y, kde=False, fit=st.johnsonsu) # kde是否绘制高斯核密度估计图
plt.figure(2); plt.title('Norm')
sns.distplot(y, kde=False, fit=st.norm)
plt.figure(3); plt.title('Log Normal')
sns.distplot(y, kde=False, fit=st.lognorm)
- scipy.stats 包含许多函数分布的库
- seaborn.displot 单变量观测值分布图
- scipy.stats所有可用函数分布
查看skewness和kurtosis
sns.distplot(Y_train)
print("Skewness: %f" % Y_train.skew())
print("Kurtosis: %f" % Y_train.kurt())
sns.distplot(Train_data.skew(),color='blue',axlabel ='Skewness')
sns.distplot(Train_data.kurt(),color='orange',axlabel ='Kurtness')
Skewness: 3.346487
Kurtosis: 18.995183
查看具体频数
plt.hist(Train_data['price'], orientation = 'vertical',histtype = 'bar', color ='blue')
plt.show()
#进行对数变换
plt.hist(np.log(Train_data['price']), orientation = 'vertical',histtype = 'bar', color ='red')
plt.show()
2.5 数据特征分析
我们观察数据特征,发现特征分为两类数字特征和类型特征
2.5.1数字特征分析
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' ]
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())
- df.nunique(): 回的是唯一值的个数
相关性分析
numeric_features.append('price')
price_numeric = Train_data[numeric_features]
correlation = price_numeric.corr() # 返回各特征之间的相关系数DataFrame表格
# print(correlation['price'].sort_values(ascending = False),'\n') # 查看各数字特征与价格的相关性
f , ax = plt.subplots(figsize = (7, 7)) # 函数返回一个figure图像和子图ax的array列表。
plt.title('Correlation of Numeric Features with Price',y=1,size=16)
sns.heatmap(correlation,square = True, vmax=0.8) # 相关性热图
查看几个特征的 偏度和峰值
del price_numeric['price']
for col in numeric_features:
print('{:15}'.format(col),
'Skewness: {:05.2f}'.format(Train_data[col].skew()) ,
' ' ,
'Kurtosis: {:06.2f}'.format(Train_data[col].kurt())
)
每个数字特征得分布可视化
f = pd.melt(Train_data, value_vars=numeric_features) # value_vars需要转换的值
g = sns.FacetGrid(f, col="variable", col_wrap=2, sharex=False, sharey=False) # 用于绘制成对关系的子图网格。col_wrap: 制网格的列维度 share{x, y} 是否共享x,y轴
g = g.map(sns.distplot, "value") # 数据填充
- pandas.melt(frame, id_vars=None, value_vars=None, var_name=None, value_name=‘value’, col_level=None) 将列名转换为列数据(columns name → column values),重构DataFrame
数字特征相互之间的关系可视化
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()
多变量互相回归关系可视化
fig, ((ax1, ax2), (ax3, ax4), (ax5, ax6), (ax7, ax8), (ax9, ax10)) = plt.subplots(nrows=5, ncols=2, figsize=(24, 20))
# ['v_12', 'v_8' , 'v_0', 'power', 'v_5', 'v_2', 'v_6', 'v_1', 'v_14']
v_12_scatter_plot = pd.concat([Y_train,Train_data['v_12']],axis = 1)
sns.regplot(x='v_12',y = 'price', data = v_12_scatter_plot,scatter= True, fit_reg=True, ax=ax1) # 绘制数据并拟合线性回归模型。
v_6_scatter_plot = pd.concat([Y_train,Train_data['v_6']],axis = 1)
sns.regplot(x='v_6',y = 'price',data = v_6_scatter_plot,scatter= True, fit_reg=True, ax=ax7)
...
2.5.2类型特征分析
类别特征unique分析
for fea in categorical_features:
print(fea+":", Train_data[fea].nunique())
类别特征箱型图
categorical_features = ['model',
'brand',
'bodyType',
'fuelType',
'gearbox',
'notRepairedDamage']
for c in categorical_features:
Train_data[c] = Train_data[c].astype('category')
if Train_data[c].isnull().any():
Train_data[c] = Train_data[c].cat.add_categories(['MISSING'])
Train_data[c] = Train_data[c].fillna('MISSING')
def boxplot(x, y, **kwargs):
sns.boxplot(x=x, y=y)
x=plt.xticks(rotation=90)
f = pd.melt(Train_data, id_vars=['price'], value_vars=categorical_features)
g = sns.FacetGrid(f, col="variable", col_wrap=2, sharex=False, sharey=False, size=5)
g = g.map(boxplot, "value", "price")
- 箱形图绘制须使用常用的统计量,能提供有关数据位置和分散情况的关键信息,尤其在比较不同的母体数据时更可表现其差异。它能显示出一组数据的最大值、最小值、中位数、及上下四分位数。
-
类别特征小提琴图
catg_list = categorical_features
target = 'price'
for catg in catg_list :
sns.violinplot(x=catg, y=target, data=Train_data)
plt.show()
- 小提琴图 (Violin Plot)是用来展示多组数据的分布状态以及概率密度。这种图表结合了箱形图和密度图的特征,主要用来显示数据的分布形状。
类别特征的柱形图可视化
def bar_plot(x, y, **kwargs):
sns.barplot(x=x, y=y)
x=plt.xticks(rotation=90)
f = pd.melt(Train_data, id_vars=['price'], value_vars=categorical_features)
g = sns.FacetGrid(f, col="variable", col_wrap=2, sharex=False, sharey=False, size=5)
g = g.map(bar_plot, "value", "price")
2.6生成数据报
用pandas_profiling生成一个较为全面的可视化和数据报告(较为简单、方便) 最终打开html文件即可
import pandas_profiling
pfr = pandas_profiling.ProfileReport(Train_data)
pfr.to_file("./example.html")
总结:概要地学习了如何对数据集进行EDA,我的比赛之路又迈向一步。
参考资料: