admin 管理员组

文章数量: 1086019

【数据处理

在数据清洗的过程中,异常值的检测及处理是非常重要的一部分,现就以下问题学习异常值的相关知识。

1.什么是异常值?

  指样本中个别数值明显偏离其余的观测值,比如一个学生的年龄<0,身高>5m等等,这些数据都属于异常值

2.异常值有什么影响?

  回归模型对异常值比较敏感,如果数据样本中存在异常值,那么模型的拟合,变量的系数、显著性等都会产生较大影响。

3.怎么检测异常值?

- 箱型图

  首先计算变量的分位数(Q1、Q3),然后得到四分位数极差IQR=Q3-Q1,那么小于Q1-1.5IQR 或 大于Q3+1.5IQR的值称为异常值

代码如下:

# 函数:统计学方法计算每个字段的异常值情况
def outlier_box(data,cols_all,k=1.5):'''args:data:数据源cols_all:进行异常值分析的字段,列表形式k:超过高低四分位数时IQR的比例,1.5:中度异常,3:重度异常return:data_outlier:outlier_low:下部异常值outlier_up:上部异常值outlier_len:异常值记录条数'''outlier = {}for col in cols_all:print(col)# 下限low = np.percentile(data[col],25) - k*(np.percentile(data[col],75)-np.percentile(data[col],25))  low = float(np.where(low<data[col].min(),np.nan,low))# 上限up = np.percentile(data[col],75) + k*(np.percentile(data[col],75)-np.percentile(data[col],25))   up = float(np.where(up>data[col].max(),np.nan,up))# 异常记录条数out_index = (data[col]<low) | (data[col]>up)out_len = len(data[out_index]) outlier[col] = [low,up,out_len]data_outlier = df(outlier).T.rename(columns={0:'outlier_low',1:'outlier_up',2:'outlier_len'})return data_outlier# 画图:箱型图检测异常值
import seaborn as sns
sns.boxplot(data=data,whis=1.5)
'''x=None,y=None,hue=None,按照列名中的值分类形成分类的条形图data=None,order=None,用于控制条形图的顺序hue_order=None,用于控制条形图的顺序orient=None,"v"|"h" 用于控制图像使水平还是竖直显示(这通常是从输入变量的dtype推断出来的,此参数一般当不传入x、y,只传入data的时候使用)color=None,palette=None:调色板,控制图像的色调saturation=0.75,饱和度width=0.8,控制箱型图的宽度dodge=True,fliersize=5,用于指示离群值观察的标记大小linewidth=None,构图元素的灰线宽度whis=1.5,该值为超过高低四分位数时IQR的比例,超出此范围的点视为异常值ax=None,
'''

- 3σ准则

  如果样本是正态分布或者近似正态分布,认为数值分布在(μ-3σ,μ+3σ)中的概率为99.73%,超过这个范围的极大或极小值,即为异常值。

代码如下:

# 函数:3σ准则
def outlier_3sigma(data,cols_all):'''args:data:数据源cols_all:进行异常值分析的字段,列表形式'''outlier = {}for col in cols_all:print(col)miu = np.average(data[col]) # 均值sigma = np.std(data[col])   # 标准差# 下限low = miu - 3*sigmalow = float(np.where(low<data[col].min(),np.nan,low))# 上限up = miu + 3*sigmaup = float(np.where(up>data[col].max(),np.nan,up))# 异常记录条数out_index = (data[col]<low) | (data[col]>up)out_len = len(data[out_index]) outlier[col] = [low,up,out_len]data_outlier = df(outlier).T.rename(columns={0:'outlier_low',1:'outlier_up',2:'outlier_len'})return data_outlier# 画图:分布图
from matplotlib import pyplot as plt 
nrow = 2
ncol = 2
fig,axs = plt.subplots(nrows=nrow,ncols=ncol)for i in range(nrow):print(i)for j in range(ncol):print(j)sns.distplot(data.iloc[:,i+j+1],ax=axs[i,j])

- DBSCAN聚类

过程:
1)在数据集中任意选取一个数据点 p 作为起始点;

2)对于给定的参数 eps(半径) 和 min_samples(最小样本数),
如果距起始点 p 的距离在 eps 之内的数据点个数小于 min_samples,那么这个点 p 被标记为噪声
如果距离在 eps 之内的数据点个数大于 min_samples,则这个点 p 被标记为核心样本,并被分配一个新的簇标签;

3)访问该点 p 的所有邻居(在距离 eps 以内)
如果它们还没有被分配一个簇,那么就将刚刚创建的新的簇标签分配给它们,
如果它们是核心样本,那么就依次访问其邻居,以此类推,
直到在簇的 eps 距离内没有更多的核心样本为止;

4) 选取另一个尚未被访问过的点,并重复相同的过程,直到所有点被处理。

代码如下:

from sklearn.preprocessing import StandardScaler
from sklearn.cluster import DBSCAN
# 标准化
stscaler = StandardScaler().fit(data)
data = stscaler.transform(data)db = DBSCAN(min_samples = 20, eps = 3).fit(data)
y_pred = DBSCAN(min_samples = 20, eps = 3).fit_predict(data)# plt.scatter(data[:,0],data[:,1],c=y_pred) # 数据维度低可以可视化查看效果from sklearn import metrics  
score = metrics.silhouette_score(data,y_pred) # 轮廓系数评估聚类效果

4.异常值怎么处理?

  • 删除
  • 填充(盖帽、均值等)
  • 不处理

本文标签: 数据处理