在数据清洗的过程中,异常值的检测及处理是非常重要的一部分,现就以下问题学习异常值的相关知识。
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%,超过这个范围的极大或极小值,即为异常值。
代码如下:
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*sigma
low = float(np.where(low<data[col].min(),np.nan,low))
up = miu + 3*sigma
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
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)
from sklearn import metrics
score = metrics.silhouette_score(data,y_pred)
4.异常值怎么处理?
|