Python学习-数据异常检测

数据科学中,在对数据分析前,必须要多数据进行处理。将非正常的、错误的数据输入到算法中会导致不好的结果。所以异常的检测及处理为非常重要的一环。

1.1 单变量异常检测

        在处理单变量异常时,有一条准则:极端值可以当做异常值

       1.  IQR(四分位距,75分位与25分位的差)。第一种是比25分位值减去IQR*1.5小的值;第二种是比75分为大IQR*1.5的值

       2. Z-scores 得分绝对值大于3的观测值可认为是异常值

先用箱图来直观观察一下每个特征的分布情况

from sklearn.datasets import load_boston 
import numpy as np
import pandas as pd
from sklearn import preprocessing

data=load_boston()
boston=pd.DataFrame( data.data)
boston.columns=data['feature_names']
boston.pop('CHAS')#remove column 
normolized_data=preprocessing.StandardScaler().fit_transform(boston)
boston.boxplot(sym='r',vert=False,patch_artist=True,meanline=False,showmeans=True)


箱图能非常直观的观察数据间离散程度、异常值(红色)、分布差异等。在这里,

sym='r',表示异常点的形状,
vert=False表示横向、竖向,
patch_artist=True表示上下四分位框内是否填充,True为填充
传送门:箱图https://www.jianshu.com/p/b2f70f867a4a

以下为用Z-scores寻找异常值。

之所以以3作为界限,原因是一个正态分布的数据95%的面积分布在平均数左右两个标准差范围内;99.9%的面积分布在平均数左右3个标准差范围内。

outliers_rows,outliers_columns=np.where(np.abs(normolized_data)>3)
print(len(outliers_columns))

结果为65。

这种方法虽然可以发现很多异常值,但是很多不是极端值的异常值仍会被漏掉。为了发现这些异常,利用PCA降维之后再找绝对标准差大于3的值。

传送门:PCA降维简介https://blog.csdn.net/qq_36056559/article/details/80738779


OneClassSVM

OneClassSVM是一种无监督的算法,它可以用来检查新的样本是否符合以前的数据分布。它有三个主要参数:

1. Kernel (核函数)和Degree

    此两变量相关,根据经验值kernel应为rbf,degree应为3.

2. Gamma

    它是与rbf核相关的参数。建议这个参数设置的越低越好,通常为实例数倒数和变量数倒数之间的最小值。

3. Nu

   它决定模型是否必须符合一个精确的分布,还是应该尽量保持某种标准分布而不太注重适应现有数据

    区间为(0,1],默认值为0.5.但在这里0.5的结果并不好,所以

    可以由一下公式确定:    nu_estimate=0.95*outliers_fraction+0.05

    通常outliers_fraction的范围为0.02-0.1

一下代码用聚类生成器产生一个聚类并用OneSVM进行异常检测:

from sklearn.datasets import make_blobs
blobs=make_blobs(n_samples=1000,n_features=2,centers=1,cluster_std=1.5,shuffle=True,random_state=5)
normolized_data=preprocessing.StandardScaler().fit_transform(blobs[0])

out_fraction=0.02
nu_estimate=0.95*out_fraction+0.05
mechine_learning=svm.OneClassSVM(kernel="rbf",degree=3,gamma=1.0/len(normolized_data),nu=nu_estimate)
mechine_learning.fit(normolized_data)
detection=mechine_learning.predict(normolized_data)
outliers=np.where(detection==-1)
regular=np.where(detection==1)
from matplotlib import pyplot as plt
a=plt.plot(normolized_data[regular,0],normolized_data[regular,1],'x',markersize=2,color="green",alpha=0.6)
b=plt.plot(normolized_data[outliers,0],normolized_data[outliers,1],'o',color='red',markersize=6)

结果还是比较理想的

接下来回到波士顿的数据,先对数据进行标准化后再进行降维操作

normolized_data=preprocessing.StandardScaler().fit_transform(boston)#标准化
pca=PCA(n_components=5)
Zscore_components=pca.fit_transform(normolized_data)#PCA降维

out_fraction=0.02
nu_estimate=0.95*out_fraction+0.05
mechine_learning=svm.OneClassSVM(kernel="rbf",degree=3,gamma=1.0/len(Zscore_components),nu=nu_estimate)
mechine_learning.fit(Zscore_components)
detection=mechine_learning.predict(Zscore_components)
outliers=np.where(detection==-1)
regular=np.where(detection==1)
from matplotlib import pyplot as plt

a=plt.plot(Zscore_components[regular,0],Zscore_components[regular,1],'x',markersize=2,color="green",alpha=0.6)
b=plt.plot(Zscore_components[outliers,0],Zscore_components[outliers,1],'o',color='red',markersize=6)

outliers 和 regular结果:

35个点被认为是异常点,471个点是正常点。

因为在PCA降维中,分量1和2占据了原数据大部分的信息量。为了观察更加直观的结果,用pyplot来看看分量1和2的分布情况:

当outliers_fraction值为0.1时:




参考文献:

1.    《数据科学导论》

2.      http://scikit-learn.org/stable/modules/generated/sklearn.svm.OneClassSVM.html

3.      https://www.jianshu.com/p/b2f70f867a4a


猜你喜欢

转载自blog.csdn.net/qq_36056559/article/details/80822514