赞
踩
异常值是指样本中的个别值,其数值明显偏离它所属样本集的其余观测值。
异常值分析是检验数据是否有录入错误以及含有不合常理的数据。忽视异常值的存在是十分危险的,不加剔除地把异常值包括进数据的计算分析过程中,对结果会产生不良影响;重视异常值的出现,分析其产生的原因,常常成为发现问题进而改进决策的契机。异常值也称为离群点,异常值的分析也称为离群点分析。
就是简单的画图看数据,计算方差、标准差查看数据的波动程度,另外查看均值大小、众数、最大值最小值、分位数值,结合这些来看就可以了。比如 如果方差标准差很大,然后最小值很小,那可能是有异常值问题了。
这个原则有个条件:数据需要服从正态分布。 使用K-S检验一个数列是否服从正态分布、两个数列是否服从相同的分布。值得一提的是,如果有些特征不符合高斯分布,可以通过一些函数变换(Z-score、Box-Cox),使其符合正态分布,再使用基于统计的方法。
在3∂原则下,异常值如超过3倍标准差,那么可以将其视为异常值。正负3∂的概率是99.7%,那么距离平均值3∂之外的值出现的概率为P(|x-u| 3∂) = 0.003,属于极个别的小概率事件。一组测定值中与平均值的偏差超过两倍标准差的测定值 。与平均值的偏差超过三倍标准差的测定值,称为高度异常的异常值。在处理数据时,应剔除高度异常的异常值。如果数据不服从正态分布,也可以用远离平均值的多少倍标准差来描述。
3σ原则:
其中,μ为平均值,σ为标准差。一般可以认为,数据Y的取值几乎全部集中在(μ-3σ,μ+3σ)区间内,超出这个范围的可能性仅占不到0.3%,这些超出该范围的数据可以认为是异常值。
步骤如下:
箱型图提供了识别异常值的一个标准:异常值通常被定义为小于QL-1.5IQR或大于QU+1.5IQR的值。
箱型图依据实际数据绘制,没有对数据作任何限制性要求(如服从某种特定的分布形式),它只是真实直观地表现数据分布的本来面貌;另一方面,箱型图判断异常值的标准以四分位数和四分位距为基础,四分位数具有一定的鲁棒性:多达25%的数据可以变得任意远而不会很大地扰动四分位数,所以异常值不能对这个标准施加影响。由此可见,箱型图识别异常值的结果比较客观,在识别异常值方面有一定的优越性。
箱线图绘制:【具体百度】
绘制单个箱线图:
labels = 'A'
data = [0.8685, 0.6671, 0.7971, 0.5774]
plt.grid(True) # 显示网格
plt.boxplot(data,
medianprops={'color': 'red', 'linewidth': '1.5'},
meanline=True,
showmeans=True,
meanprops={'color': 'blue', 'ls': '--', 'linewidth': '1.5'},
flierprops={"marker": "o", "markerfacecolor": "red", "markersize": 10},
labels=labels)
plt.yticks(np.arange(0.4, 0.91, 0.1))
plt.show()
绘制多个箱线图:
labels = 'A', 'B', 'C', 'D', 'E', 'F'
A = [0.4978, 0.5764, 0.5073, 0.5609]
B = [0.5996, 0.65, 0.6251, 0.6473]
C = [0.6015, 0.687, 0.6237, 0.6761]
D = [0.5918, 0.6999, 0.6343, 0.6947]
E = [0.577, 0.6932, 0.6593, 0.7036]
F = [0.5637, 0.7161, 0.6683, 0.697]
plt.grid(True) # 显示网格
plt.boxplot([A, B, C, D, E, F],
medianprops={'color': 'red', 'linewidth': '1.5'},
meanline=True,
showmeans=True,
meanprops={'color': 'blue', 'ls': '--', 'linewidth': '1.5'},
flierprops={"marker": "o", "markerfacecolor": "red", "markersize": 10},
labels=labels)
plt.yticks(np.arange(0.4, 0.81, 0.1))
plt.show()
DBScan 是一种用于把数据聚成组的聚类算法。它同样也被用于单维或多维数据的基于密度的异常检测。其它聚类算法比如 k 均值和层次聚类也可用于检测离群点。
基于DBSCAN聚类方法,DBSCAN是一维或多维特征空间中的非参数,基于密度的离群值检测方法。在DBSCAN聚类技术中,所有数据点都被定义为核心点(Core Points)、边界点(Border Points)或噪声点(Noise Points)。核心点是在距离内至少具有最小包含点数(minPTs)的数据点;边界点是核心点的距离内邻近点,但包含的点数小于最小包含点数(minPTs);所有的其他数据点都是噪声点,也被标识为异常值;从而,异常检测取决于所要求的最小包含点数、距离和所选择的距离度量,比如欧几里得或曼哈顿距离。
以每个点为中心,设定邻域及邻域内需要有多少个点,如果样本点大于指定要求,则认为该点与邻域内的点属于同一类,如果小于指定值,若该点位于其它点的邻域内,则属于边界点。设定两个参数,eps表示聚类点为中心划定邻域,min_samples表示每个邻域内需要多少个样本点。
def filter_data(data0, params):
from sklearn.cluster import DBSCAN
from sklearn import metrics
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(data0)
data = scaler.transform(data0)
#eps:半径,表示以给定点P为中心的圆形邻域的范围
#min_samples:以点P为中心的邻域内最少点的数量
#如果满足,以点P为中心,半径为EPS的邻域内点的个数不少于MinPts,则称点P为核心点
eps, min_samples = params
# eps为领域的大小,min_samples为领域内最小点的个数
model = DBSCAN(eps=eps, min_samples=min_samples) # 构造分类器
model.fit(data) # 拟合
labels = model.labels_ # 获取类别标签,-1表示未分类
# 获取其中的core points core_sample_indices_
core_indices = np.zeros_like(labels, dtype=bool) # 生成数据类型和数据shape和指定array一致的变量
core_indices[model.core_sample_indices_] = True # model.core_sample_indices_ border point位于labels中的下标
core_point = data[core_indices]
# 获取非异常点 两个类似
normal_point = data0[labels>=0]
return normal_point
该方法是一维或多维特征空间中 大数据集 的非参数方法,其中的一个重要概念是孤立数。孤立数是孤立数据点所需的拆分数。
通过以下步骤确定此分割数:随机选择要分离的点“a”;选择在最小值和最大值之间的随机数据点“b”,并且与“a”不同;如果“b”的值低于“a”的值,则“b”的值变为新的下限;如果“b”的值大于“a”的值,则“b”的值变为新的上限;只要在上限和下限之间存在除“a”之外的数据点,就重复该过程;与孤立非异常值相比,它需要更少的分裂来孤立异常值,即异常值与非异常点相比具有更低的孤立数。因此,如果数据点的孤立数低于阈值,则将数据点定义为异常值。阈值是基于数据中异常值的估计百分比来定义的,这是异常值检测算法的起点。
孤立森林是一个基于Ensemble的快速离群点检测方法,适用于连续数据的异常检测,通过对样本点的孤立来检测异常值。具体来说,该算法利用孤立树(iTree)的二叉搜索树结构来孤立样本。由于异常值的数量较少且与大部分样本的疏离性,因此,异常值会被更早的孤立出来,也即异常值会距离iTree的根节点更近,而正常值则会距离根节点有更远的距离。此外,相较于LOF,K-means等传统算法,孤立森林算法对高纬数据有较好的鲁棒性。
# 参考https://blog.csdn.net/ye1215172385/article/details/79762317
# 官方例子https://scikit-learn.org/stable/auto_examples/ensemble/plot_isolation_forest.html#sphx-glr-auto-examples-ensemble-plot-isolation-forest-py
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import IsolationForest
# 设置随机种子
rng = np.random.RandomState(42)
# 构造训练样本
n_samples = 200 #样本总数
outliers_fraction = 0.25 #异常样本比例
n_inliers = int((1. - outliers_fraction) * n_samples)
n_outliers = int(outliers_fraction * n_samples)
X = 0.3 * rng.randn(n_inliers // 2, 2)
X_train = np.r_[X + 2, X - 2] #正常样本
X_train = np.r_[X_train, np.random.uniform(low=-6, high=6, size=(n_outliers, 2))] #正常样本加上异常样本
# 构造模型并拟合
# max_samples 构造一棵树使用的样本数,输入大于1的整数则使用该数字作为构造的最大样本数目,
# contamination 多少比例的样本可以作为异常值
clf = IsolationForest(max_samples=n_samples, random_state=rng, contamination=outliers_fraction)
clf.fit(X_train)
# 计算得分并设置阈值
scores_pred = clf.decision_function(X_train)
threshold = np.percentile(scores_pred, 100 * outliers_fraction) #根据训练样本中异常样本比例,得到阈值,用于绘图
X_train_predict1 = X_train[clf.predict(X_train)==1]
X_train_predict2 = X_train[scores_pred>=threshold,:]
举例说明工作步骤:
读取数据:
import plotly.express as px
from sklearn.datasets import load_iris
from sklearn.ensemble import IsolationForest
data = load_iris(as_frame=True)
X,y = data.data,data.target
df = data.frame
df.head()
每个样本都有四个特征:萼片和花瓣的长度和宽度。这些特征将由孤立森林算法检测,以检查观测是否异常。
第二步是定义模型。有一些相关的超参数可以实例化类:
iforest = IsolationForest(n_estimators=100, max_samples='auto',
contamination=0.05, max_features=4,
bootstrap=False, n_jobs=-1, random_state=1)
定义了模型之后,就可以在数据上拟合模型并返回x的标签。这个任务是使用函数fit_predict完成的:
pred= iforest.fit_predict(X)
df['scores']=iforest.decision_function(X)
df['anomaly_label']=pred
以使用函数decision_function找到异常分数,同时我们可以存储在预测中获得的标签。当标签等于-1时,它表示我们有异常。如果标签是1,就是正常的。
df[df.anomaly_label==-1]
为了突出异常分数与通过预测得到的标签之间的这种关系,可以显示直方图。在创建直方图之前,我添加了一个表示异常状态的列:
df['anomaly']=df['anomaly_label'].apply(lambda x: 'outlier' if x==-1 else 'inlier')
fig=px.histogram(df,x='scores',color='anomaly')
fig.show()
sklearn中提供了one-class SVM和EllipticEnvelope两种方法用于异常检测,前者基于libsvm实现的非监督式异常检测方法,可用于做高维度分布的评估;后者只能做基于高斯分布数据集的异常检测。
from sklearn import svm
X_train = X_train_demo.values
# 构造分类器
# nu :错误和支持度的下界 0.5默认
# kernal:内核类型 rbf默认
clf = svm.OneClassSVM(nu=0.4, kernel="rbf", )
clf.fit(X_train)
# 预测,结果为-1或者1
labels = clf.predict(X_train)
# 分类分数
score = clf.decision_function(X_train) # 获取置信度
# 获取正常点
X_train_normal = X_train[labels>0]
一个样本点周围的样本点所处位置的平均密度比上该样本点所在位置的密度。比值越大于1,则该点所在位置的密度越小于其周围样本所在位置的密度。
整个算法,最主要的是下面四个概念:
K-邻近距离(k-distance):在距离数据点 p 最近的几个点中,第 k 个最近的点跟点 p 之间的距离称为点 p 的 K-邻近距离,记为 k-distance § 。
可达距离(rechability distance):可达距离的定义跟K-邻近距离是相关的,给定参数k时, 数据点 p 到 数据点 o 的可达距离 reach-dist(p, o)为数据点 o 的K-邻近距离 和 数据点p与点o之间的直接距离的最大值。即:
局部可达密度(local rechability density):局部可达密度的定义是基于可达距离的,对于数据点 p,那些跟点p的距离小于等于 k-distance(p)的数据点称为它的 k-nearest-neighbor,记为
N
k
(
p
)
N_k(p)
Nk(p),数据点 p 的局部可达密度为它与邻近的数据点的平均可达距离的倒数,即:
局部异常因子(local outlier factor):根据局部可达密度的定义,如果一个数据点跟其他点比较疏远的话,那么显然它的局部可达密度就小。但LOF算法衡量一个数据点的异常程度,并不是看它的绝对局部密度,而是看它跟周围邻近的数据点的相对密度。这样做的好处是可以允许数据分布不均匀、密度不同的情况。局部异常因子即是用局部相对密度来定义的。数据点 p 的局部相对密度(局部异常因子)为点p的邻居们的平均局部可达密度跟数据点p的局部可达密度的比值,即:
根据局部异常因子的定义,如果数据点 p 的 LOF 得分在1附近,表明数据点p的局部密度跟它的邻居们差不多;如果数据点 p 的 LOF 得分小于1,表明数据点p处在一个相对密集的区域,不像是一个异常点;如果数据点 p 的 LOF 得分远大于1,表明数据点p跟其他点比较疏远,很有可能是一个异常点。
来自 Wikipedia 的 LOF 词条,展示了一个二维的例子。上面的数字标明了相应点的LOF得分,可以让人对LOF有一个直观的印象:
了解了 LOF 的定义,整个算法也就显而易见了:
from sklearn.neighbors import LocalOutlierFactor
# 构造分类器
## 25个样本点为一组,异常值点比例为0.2
clf = LocalOutlierFactor(n_neighbors=25, contamination=0.2)
# 预测,结果为-1或者1
labels = clf.fit_predict(X_train)
# 获取正常点
X_train_normal = X_train[labels>0]
异常点也是数据分布的一部分,也许它在客观现实中就是那样的,所以为了让模型学到这种知识,有时候不应该去改变它或者删除它。
对于一些非时间序列数据、删除某n条数据对整体没产生大影响的场景,就应该删除异常值。
如果数据的样本量很小的话,也可用前后两个观测值的平均值来修正该异常值。这其实是一种比较折中的方法,大部分的参数方法是针对均值来建模的,用平均值来修正,优点是能克服了丢失样本的缺陷,缺点是丢失了样本“特色”。
将连续变量等级化之后,不同的分位数的数据就会变成不同的等级数据,连续变量离散化了,消除了极值的影响。
分箱法通过考察数据的“近邻”来光滑有序数据的值。有序值分布到一些桶或箱中。包括等深分箱:每个分箱中的样本量一致;等宽分箱:每个分箱中的取值范围一致。‘
’发现两个相关的变量之间的变化模式,通过使数据适合一个函数来平滑数据。若是变量之间存在依赖关系,也就是y=f(x),那么就可以设法求出依赖关系f,再根据x来预测y,这也是回归问题的实质。实际问题中更常为见的假设是p(y)=N(f(x)),N为正态分布。假设y是观测值并且存在噪声数据,根据我们求出的x和y之间的依赖关系,再根据x来更新y的值,这样就能去除其中的随机噪声,这就是回归去噪的原理 。
多重插补的处理有两个要点:先删除Y变量的缺失值然后插补。
盖帽法将某连续变量 均值上下三倍标准差 范围外的记录替换为 均值上下三倍标准差值,即盖帽处理。当然,这里的分位数可以依据数据业务含义自己定义,比如,可以将小于3%分位数的值 和 大于97%分位数的值 被 3%分位数 和 97%分位数 分别替代。
如果一个置信区间左右两边各有3个标准差,即区间置信度为99%时,一般建议三倍标准差以外删除; 而如果一个置信区间左右两边各有2个标准差,即区间置信度为95%时,此时到底取两个还是三个标准差则取决于模型对于异常的敏感程度。
https://github.com/sladesha/Reflection_Summary
异常检测方法
箱线图判断方法
3δ原则
数据的正态性检验方法
正太检验【墙裂推荐】
正太检验
箱线图绘制
异常检测方法实现
异常值检测方法 孤立森林(Isolation Forest)方法
https://blog.csdn.net/fengdu78/article/details/110848749
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。