目录
一、数据概览
df.head(n):查看DataFrame对象的前n行,默认是5行
data.tail(n):查看DataFrame对象的后n行,默认是5行
data.info(): 查看索引、数据类型和内存信息
data.isnull():检查DataFrame对象中的空值,并返回一个Boolean数组
data.describe():查看数值型列的汇总统计 (对于object类型字段,可以单独用:data['column'].describe() )
data_train.shape:查看数据特征维度
data_train.columns:查看数据列名称
具体操作如下所示:
- 查看总体数据类型
1.查看类别型数据(非数值类型)
category_fea =list(data_train.select_dtypes(include=['object']).columns)
2.查看数值型数据
numerical_fea=list(data_train.select_dtypes(exclude=['object']).columns)
# 数字特征
numeric_features = Train_data.select_dtypes(include=[np.number])
numeric_features.columns
# 类型特征
categorical_features = Train_data.select_dtypes(include=[np.object])
categorical_features.columns
二、查看总体数据缺失值
missingno
提供了一个灵活且易于使用的缺失数据可视化和实用程序的小工具集,使您可以快速直观地总结数据集的完整性。参考链接:缺失值可视化处理--missingno
1.查看数据缺失值
have_null_fea_dict = (data_train.isnull().sum()/len(data_train)).to_dict()
2.查看每列缺失值的数量
df.isnull().sum()
3.查看数据缺失率情况
missing = data_train.isnull().sum()/len(data_train)
4.替换字符为NaN
# 可以看出‘ - ’也为空缺值,因为很多模型对nan有直接的处理,这里我们先不做处理,先替换成nan
Train_data['notRepairedDamage'].replace('-', np.nan, inplace=True)
Train_data['notRepairedDamage'].value_counts()
三、查看总体数据异常值
1、异常检测判别方法
1.简单统计分析
对属性值进行一个描述性的统计,从而查看哪些值是不合理的。比如对年龄这个属性进行规约:年龄的区间在[0:200],如果样本中的年龄值不再该区间范围内,则表示该样本的年龄属性属于异常值。
2. 3δ原则
当数据服从正态分布:
根据正态分布的定义可知,距离平均值3δ之外的概率为 P(|x-μ|>3δ) <= 0.003 ,这属于极小概率事件,在默认情况下我们可以认定,距离超过平均值3δ的样本是不存在的。 因此,当样本距离平均值大于3δ,则认定该样本为异常值。
当数据不服从正态分布:
当数据不服从正态分布,可以通过远离平均距离多少倍的标准差来判定,多少倍的取值需要根据经验和实际情况来决定。
3.箱形图(只针对数值型)
fig = plt.figure(figsize=(4, 6)) # 指定绘图对象宽度和高度
sns.boxplot(train_data['V0'],orient="v", width=0.5) # orient:控制图像水平、竖直显示 “v”竖直,“h”水平
异常值处理:上图有很多偏离值,许多数据点位于下四分位点以下,可以考虑移除。
箱线图
箱线图(Boxplot)也称箱须图(Box-whisker Plot),是利用数据中的五个统计量:最小值(下限)、第一四分位数(Q1)、中位数、第三四分位数(Q3)与最大值(上限)来描述数据的一种方法,它也可以粗略地看出数据是否具有有对称性,分布的分散程度等信息,特别可以用于对几个样本的比较。
具体含义如下,首先计算出第一四分位数(Q1)、中位数、第三四分位数(Q3)。
中位数我们都知道,就是将一组数字按从小到大的顺序排序后,处于中间位置(也就是50%位置)的数字。
同理,第一四分位数、第三四分位数是按从小到大的顺序排序后,处于25%、75%的数字。令 IQR=Q3−Q1,那么 Q3+1.5(IQR) 和 Q1−1.5(IQR) 之间的值就是可接受范围内的数值,这两个值之外的数认为是异常值。(内限范围之内)
在Q3+1.5IQR(四分位距)和Q1-1.5IQR处画两条与中位线一样的线段,这两条线段为异常值截断点,称其为内限;在Q3+3IQR和Q1-3IQR处画两条线段,称其为外限。
处于内限以外位置的点表示的数据都是异常值,其中在内限与外限之间的异常值为温和的异常值(mild outliers),在外限以外的为极端的异常值(li)的异常值extreme outliers。这种异常值的检测方法叫做Tukey’s method。从矩形盒两端边向外各画一条线段直到不是异常值的最远点 表示该批数据正常值的分布区间点,示该批数据正常值的分布区间。
一般用“〇”标出温和的异常值,用“*”标出极端的异常值。
你可以从IQR中计算出中间的50%。
IQR = Q3 - Q1
中值MAD = IQR / 2
4.散点图
比如绘制身高和体重的双变量分布,观察是否有样本值在[身高,体重]组合的平均值一下。
5.模型预测找出异常值
采用模型预测的形式找出异常值。
6.其他方法
(1)偏差检测( 聚类(KMeans)和最近邻(KNN))
比如我们可以用KMeans聚类将训练样本分成若干个簇,如果某一个簇里的样本数很少,而且簇质心和其他所有的簇都很远,那么这个簇里面的样本极有可能是异常特征样本了。我们可以将其从训练集过滤掉。
(2)异常点检测(iForest,one class SVM)
主要是使用iForest或者one class SVM,使用异常点检测的机器学习算法来过滤所有的异常点。
(3)基于统计的异常点检测
例如极差,四分位数间距,均差,标准差等,这种方法适合于挖掘单变量的数值型数据。全距(Range),又称极差,是用来表示统计资料中的变异量数(measures of variation) ,其最大值与最小值之间的差距;四分位距通常是用来构建箱形图,以及对概率分布的简要图表概述。
(4)基于距离的异常点检测
主要通过距离方法来检测异常点,将数据集中与大多数点之间距离大于某个阈值的点视为异常点,主要使用的距离度量方法有绝对距离 ( 曼哈顿距离 ) 、欧氏距离和马氏距离等方法。
(5)基于密度的异常点检测
考察当前点的周围密度,可以发现局部异常点,例如LOF算法
四、数值特征分析
1.数值的相关性
相关性可以对变量之间的关系进行量化分析
(相关性系数的取值区间为[-1,1]。当相关性系数为-1时,表示强负线性相关;当相关性系数为1时,表示强正线性相关;当相关性系数为0时,表示不相关)
一般来说,在取绝对值后,0~0.09为没有相关性,0.1~0.3为弱相关性,0.3~0.5为中等相关,0.5~1.0为强相关。
1.计算相关性
方法一:
import numpy as np
X = np.array([65,72,78,65,72,70,65,68])
Y = np.array([72,69,79,69,84,75,60,73])
np.corrcoef(X,Y)
结果如下:
array([[1. , 0.64897259],
[0.64897259, 1. ]])
方法二:
data_train1 = train_data.drop(['V5','V9','V11','V17','V22','V28'],axis=1)
train_corr = data_train1.corr()
train_corr
2.画出相关性热力图
为了便于分析,将相关性系数的结果以热力图的形式显示。
# 画出相关性热力图
ax = plt.subplots(figsize=(20, 16)) # 调整画布大小
ax = sns.heatmap(train_corr, vmax=.8, square=True, annot=True) # 画热力图 annot=True 显示系数
3.根据相关系数筛选特征变量
寻找K个与target变量最相关的特征变量(K=10)
# 寻找K个最相关的特征信息
k = 10 # number of variables for heatmap
cols = train_corr.nlargest(k, 'target')['target'].index
hm = plt.subplots(figsize=(10, 10))#调整画布大小
hm = sns.heatmap(train_data[cols].corr(),annot=True,square=True)
plt.show()
4.找出与target变量的相关系数大于0.5的特征变量
threshold = 0.5
corrmat = train_data.corr()
top_corr_features = corrmat.index[abs(corrmat["target"])>threshold]
plt.figure(figsize=(10,10))
g = sns.heatmap(train_data[top_corr_features].corr(),annot=True,cmap="RdYlGn")
说明:
相关性选择主要用于判别线性相关,对于target变量如果存在更复杂的函数形式的影响,则建议使用树模型的特征重要性去选择。
相关性低的特征可以考虑移除。
计算相关性的方法:
1、np.corrcoef(X, Y)
2、pd.corr() 输出pd,可控制参数,默认pearson相关性
3、pd.scatter_matrix() 绘制图形
2.数据的分布
需要统计数据的中心分布趋势和变量的分布,可以用直方图、箱形图等等
若数据分布表现出重尾,可能导致某些机器学习算法难以检测模式,可以尝试将属性转化为更偏向钟形的分布。
若数据表现出数值分层太多,有些层的实例少,有些层的实例非常多,可以尝试减少数值层数(数据分桶)。(在数据集中,每一层都要有足够数量的实例,不然数据不足的层,其重要程度很可能被错估)
1.箱形图
如上
2.直方图和Q-Q图
Q-Q图是指数据的分位数和正态分布的分位数对比参照的图,如果数据符合正态分布,则所有点都会落在直线上。
数据处理:对于特征变量的数据分布不是正态的,后续可以使用数据变换对其进行处理
- 绘制直方图、Q-Q图:
# 查看特征变量的数据分布,是否符合正态分布
import seaborn as sns
plt.figure(figsize=(10,5))
# 绘制直方图
ax = plt.subplot(1,2,1)
sns.distplot(train_data['V0'], fit=stats.norm) # 默认hist=True,kde=True 拟合标准正态分布,显示核密度
# 绘制Q-Q图
ax = plt.subplot(1,2,2)
res = stats.probplot(train_data['V0'], plot=plt) # 默认检测样本是否符合正态分布
- 绘制直方图
1.绘制每个数值属性的直方图
# hist()方法绘制每个数值属性的直方图(直方图用来显示给定值范围(横轴)的实例数量(纵轴))
%matplotlib inline
import matplotlib.pyplot as plt
housing.hist(bins=50, figsize=(20,15)) # bins 每张图柱子的个数
plt.show() # jupyter中调用show()是可选的
Q-Q图(quantile-quantile 分位数-分位数图)
作用:1.检验一列数据是否符合正态分布
2.检验两列数据是否符合同一分布
原理:
比较两列数据的分位数(其中一列已知分布),从而检验数据分布。
当两列数据行数相同时,首先将两列数据从高到低排序,直接画散点图。当行数不一致时,计算数据的百分位数,再画图。
百分位数:一组n个数据值按照从小到大排列,处于p%位置的值称为第p百分位数。
总结:
绘制直方图:
1、plt.hist()
2、sns.distplot(data, ax=axes[0])
3.KDE分布图
KDE(核密度估计)可以理解为是对直方图的加窗平滑。
通过绘制kde分布图,可以查看并对比训练集和测试集中特征变量的分布情况,发现两个数据集中分布不一致的特征变量
数据处理:对于特征变量在训练集与测试集中的分布不一致的,会导致模型的泛化能力变差,需要删除此类特征(或者重采样方法)
# 对比同一特征变量V0在训练集和测试集中的分布情况
plt.figure(figsize=(8,4), dpi=150)
ax = sns.kdeplot(train_data['V0'], color='Red', shade=True) # shade 是否对曲线下的区域进行阴影处理
ax = sns.kdeplot(test_data['V0'], color='Blue', shade=True)
ax.set_xlabel('V0')
ax.set_ylabel('Frequency')
ax = ax.legend(["train", "test"])
4.小提琴图
参考:seaborn系列 (11) | 小提琴图violinplot()
5.线性回归关系图
plt.figure(figsize=(8,4))
ax=plt.subplot(1,2,1)
sns.regplot(x='V0', y='target', data=train_data, ax=ax, # data:x,y所属的df
scatter_kws={'marker':'.','s':3,'alpha':0.3},
line_kws={'color':'k'}); # 比较两变量是否符合线性回归;一般用来比较特征和标签
plt.xlabel('V0')
plt.ylabel('target')
ax=plt.subplot(1,2,2)
sns.distplot(train_data['V0'].dropna()) # 绘制特征的直方图
plt.xlabel('V0')
plt.show()
6.数值的特征偏度和峰值
一般会拿偏度和峰度来看数据的分布形态,而且一般会跟正态分布做比较,我们把正态分布的偏度和峰度都看做零。如果我们在实操中,算到偏度峰度不为0,即表明变量存在左偏右偏,或者是高顶平顶这么一说。
Definition:是描述数据分布形态的统计量,其描述的是某总体取值分布的对称性,简单来说就是数据的不对称程度
Kurtosis:偏度是描述某变量所有取值分布形态陡缓程度的统计量,简单来说就是数据分布顶的尖锐程度。
# 查看特征的偏度和峰值
tips['total_bill'].skew()
tips['total_bill'].kurt()
总体分布概况
数据整体服从正态分布,样本均值和方差则相互独立,正态分布具有很多好的性质,很多模型也假设数据服从正态分布。
例如线性回归(linear regression),它假设误差服从正态分布,从而每个样本点出现的概率就可以表示为正态分布形式,将多个样本点连乘再取对数,就是所有训练集样本出现的条件概率,最大化该条件概率就是LR最终求解的问题。这个条件概率的最终表达式的形式就是我们熟悉的误差平方和。
总之, 机器学习中很多model都假设数据或参数服从正态分布。当样本不服从正态分布时,可以做如下转换:
-
线性变化z-scores
-
使用Boxcox变换
-
使用yeo-johnson变换
盲目假设变量服从正态分布可能导致不准确的结果,要结合分析。例如:不能假设股票价格服从正态分布,因为价格不能为负,故我们可以将股票价格假设为服从对数正态分布,以确保其值≥0;而股票收益可能是负数,因此收益可以假设服从正态分布。
当样本数据表明质量特征的分布为非正态时,应用基于正态分布的方法会作出不正确的判决。约翰逊分布族即为经约翰(yeo-johnson)变换后服从正态分布的随机变量的概率分布,约翰逊分布体系建立了三族分布,分别为有界SB 、对数正态SL和无界SU。
本案例(天池学习赛-二手车交易价格预测)的预测值为价格,显然不符合正态分布,故分别采用无界约翰逊分布Johnson SU、正态分布normal、对数正态分布lognormal,综合来看无界约翰逊分布对price的拟合效果更好。(下图的结果展示省略)
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)
偏度和峰度
五、类别特征分析
一般使用频次或占比表示每个类别的分布情况,对应的衡量指标分别是类别变量的频次(次数)和频率(占比),可以用柱状图来表示可视化分布情况
类别型特征原始输入通常是字符串形式,除了决策树等少数模型能直接处理字符串形式的输入,对于逻辑回归、支持向量机等模型来说,类别型特征必须经过处理转换成数值型。
1.类别型与类别型
一般采用双向表、堆叠柱状图、卡方检验进行分析。
- 双向表:通过建立频次(次数)和频率(占比)的双向表来分析变量之间的关系,其中行和列分别表示一个变量。
- 堆叠柱状图:比双向表更加直观
- 卡方检验:主要用于两个核两个以上样本率(构成比)及两个二值型离散变量的关联性分析,即比较理论频次与实际频次的吻合程度或拟合优度。
2.类别型与连续型
可以绘制小提琴图,这样可以分析类别变量在不同类别时,另一个连续变量的分布情况。
小提琴图
小提琴图结合来箱形图和密度图的相关特征信息,可以直观、清晰地显示数据的分布,常用于展示多组数据的分布及相关的概率密度。
(说明:建议使用Seaborn包中的violinplot()函数)