1、统计学异常检测概述
概述:通常使用统计学进行异常检测,一般要先依据数据训练一个模型,然后依据模型来评估数据是否异常。
2 统计学常用方法
2.1 z 分数(标准化)
概念:z分数(z-score),也叫标准分数(standard score)是一个数与平均数的差再除以标准差的过程。在统计学中,标准分数是一个观测或数据点的值高于被观测值或测量值的平均值的标准偏差的符号数。
如何使用z分数判断异常点:如果将数据进行z分数转化后,其得到的值的绝对值大于三倍标准差,就认为这个样本异常,属于离群点。
2.2 IQR四分位数
概念:四分位距通常是用来构建箱形图,以及对概率分布的简要图表概述。对一个对称性分布数据(其中位数必然等于第三四分位数与第一四分位数的算术平均数),二分之一的四分差等于绝对中位差(MAD)。中位数是集中趋势的反映。
包含三个概念:中位数Q2,第一分位数Q1,第二分位数Q3。
2.3 拉伊达(3σ)准则剔除异常值
概念:3σ原则:数值分布在(μ-σ,μ+σ)中的概率为0.6827,数值分布在(μ-2σ,μ+2σ)中的概率为0.9544,数值分布在(μ-3σ,μ+3σ)中的概率为0.9974,可以认为,Y 的取值几乎全部集中在(μ-3σ,μ+3σ)区间内,超出这个范围的可能性仅占不到0.3%。所以可以剔除这些异常点。
2.4 多元异常点检测
涉及两个或多个属性或变量的数据称为多元数据。许多一元异常点检测方法都可以扩充,用来处理多元数据。其核心思想是把多元异常点检测任务转换成一元异常点检测问题。例如基于正态分布的一元异常点检测扩充到多元情形时,可以求出每一维度的均值和标准差。对于第 j j j维: μ j = 1 m ∑ i = 1 m x j ( i ) \mu_j=\frac 1m\sum_{i=1}^m x_j^{(i)} μj=m1∑i=1mxj(i) σ j 2 = 1 m ∑ i = 1 m ( x j ( i ) − μ j ) 2 \sigma_j^2=\frac 1m\sum_{i=1}^m (x_j^{(i)}-\mu_j)^2 σj2=m1∑i=1m(xj(i)−μj)2
计算概率时的概率密度函数为
p ( x ) = ∏ j = 1 n p ( x j ; μ j , σ j 2 ) = ∏ j = 1 n 1 2 π σ j e x p ( − ( x j − μ j ) 2 2 σ j 2 ) p(x)=\prod_{j=1}^n p(x_j;\mu_j,\sigma_j^2)=\prod_{j=1}^n\frac 1{\sqrt{2\pi}\sigma_j}exp(-\frac{(x_j-\mu_j)^2}{2\sigma_j^2}) p(x)=∏j=1np(xj;μj,σj2)=∏j=1n2πσj1exp(−2σj2(xj−μj)2)
这是在各个维度的特征之间相互独立的情况下。如果特征之间有相关性,就要用到多元高斯分布了。
待后续理解使用,有需要后再进行整理补充。
3、课程学习算法HBOS
HBOS全名为:Histogram-based Outlier Score。它是一种单变量方法的组合,不能对特征之间的依赖关系进行建模,但是计算速度较快,对大数据集友好。其基本假设是数据集的每个维度相互独立。然后对每个维度进行区间(bin)划分,区间的密度越高,异常评分越低。
HBOS算法流程:
- 为每个数据维度做出数据直方图。对分类数据统计每个值的频数并计算相对频率。对数值数据根据分布的不同采用以下两种方法:
1.1 静态跨度的柱状图:将值域分成K个等宽的桶,落入每个桶的值的频数作为密度的估计(桶的高度)
1.2动态宽度柱状图:先将所有值排序,然后将连续的N/k个值装进一个桶里,其中N是所有的样例数,k是桶的个数,是一个超参数;柱状图的面积对应桶中的样例数。因为桶的宽度是有桶中第一个值和最后一个值决定的,所有桶的面积都一样,所以,每一个桶的高度可以被计算出来。这意味着跨度大的桶的高度低,即密度小,只有一种情况例外,超过k个数相等,此时一个桶里允许超过N/k个值。 - 对每个维度都计算了一个独立的直方图,其中每个箱子的高度表示密度的估计。然后为了使得最大高度为1(确保了每个特征与异常值得分的权重相等),对直方图进行归一化处理。最后,每一个实例的HBOS值由以下公式计算:
推导过程:
假设样本p第 i 个特征的概率密度为 p i ( p ) p_i(p) pi(p) ,则p的概率密度可以计算为: P ( p ) = P 1 ( p ) P 2 ( p ) ⋯ P d ( p ) P(p)=P_{1}(p) P_{2}(p) \cdots P_{d}(p) P(p)=P1(p)P2(p)⋯Pd(p) 两边取对数: log ( P ( p ) ) = log ( P 1 ( p ) P 2 ( p ) ⋯ P d ( p ) ) = ∑ i = 1 d log ( P i ( p ) ) \begin{aligned} \log (P(p)) &=\log \left(P_{1}(p) P_{2}(p) \cdots P_{d}(p)\right) =\sum_{i=1}^{d} \log \left(P_{i}(p)\right) \end{aligned} log(P(p))=log(P1(p)P2(p)⋯Pd(p))=i=1∑dlog(Pi(p)) 概率密度越大,异常评分越小,为了方便评分,两边乘以“-1”: − log ( P ( p ) ) = − 1 ∑ i = 1 d log ( P t ( p ) ) = ∑ i = 1 d 1 log ( P i ( p ) ) -\log (P(p))=-1 \sum_{i=1}^{d} \log \left(P_{t}(p)\right)=\sum_{i=1}^{d} \frac{1}{\log \left(P_{i}(p)\right)} −log(P(p))=−1i=1∑dlog(Pt(p))=i=1∑dlog(Pi(p))1 最后可得: H B O S ( p ) = − log ( P ( p ) ) = ∑ i = 1 d 1 log ( P i ( p ) ) H B O S(p)=-\log (P(p))=\sum_{i=1}^{d} \frac{1}{\log \left(P_{i}(p)\right)} HBOS(p)=−log(P(p))=i=1∑dlog(Pi(p))1
4、总结
- 异常检测的统计学方法由数据学习模型,以区别正常的数据对象和异常点。使用统计学方法的一个优点是,异常检测可以是统计上无可非议的。当然,仅当对数据所做的统计假定满足实际约束时才为真。
- HBOS在全局异常检测问题上表现良好,但不能检测局部异常值。但是HBOS比标准算法快得多,尤其是在大数据集上。
5、Toy Example
5.1 代码
仍使用PyOD示例数据集进行学习研究,代码备注统一使用英文备注
from pyod.models.hbos import HBOS #Use HBOS algorithm
from pyod.utils.data import generate_data #Generate data set
from pyod.utils.data import evaluate_print #evaluate result
from pyod.utils.example import visualize #draw
if __name__ == "__main__":
contamination = 0.1 # percentage of outliers
n_train = 10000 # number of training points
n_test = 5000 # number of testing points
# Generate sample data
X_train, y_train, X_test, y_test = \
generate_data(n_train=n_train,
n_test=n_test,
n_features=2,
contamination=contamination,
random_state=42)
# print(X_train)
# print(y_train)
# print(X_test)c
# print(y_test)
# train kNN detector
clf_name = 'HBOS'
clf = HBOS()
clf.fit(X_train)
#print(X_train)
# get the prediction labels and outlier scores of the training data
y_train_pred = clf.labels_ # binary labels (0: inliers, 1: outliers)
#print(y_train_pred)
y_train_scores = clf.decision_scores_ # raw outlier scores
#print(y_train_scores)
# get the prediction on the test data
y_test_pred = clf.predict(X_test) # outlier labels (0 or 1)
y_test_scores = clf.decision_function(X_test) # outlier scores
# evaluate and print the results
print("\nOn Training Data:")
evaluate_print(clf_name, y_train, y_train_scores)
print("\nOn Test Data:")
evaluate_print(clf_name, y_test, y_test_scores)
#print(X_train)
visualize(clf_name, X_train, y_train, X_test, y_test, y_train_pred,
y_test_pred, show_figure=True, save_figure=True)
HBOS数据直方图绘制
重写_add_sub_plot()绘图方法:
def _add_sub_plot(X_inliers, X_outliers, sub_plot_title,
inlier_color='blue', outlier_color='orange'):
"""Internal method to add subplot of inliers and outliers.
Parameters
----------
X_inliers : numpy array of shape (n_samples, n_features)
Outliers.
X_outliers : numpy array of shape (n_samples, n_features)
Inliers.
sub_plot_title : str
Subplot title.
inlier_color : str, optional (default='blue')
The color of inliers.
outlier_color : str, optional (default='orange')
The color of outliers.
"""
plt.hist(X_inliers[:, 0], bins=20, facecolor="blue", edgecolor="black", alpha=3)
plt.hist(X_outliers[:, 0], bins=20, facecolor="orange", edgecolor="black", alpha=3)
plt.hist(X_inliers[:, 1], bins=20, facecolor="green", edgecolor="black", alpha=3)
plt.hist(X_outliers[:, 1], bins=20, facecolor="red", edgecolor="black", alpha=3)
plt.title(sub_plot_title, fontsize=15)
5.2 数据样本对结果的影响
数据样本:n_train = 10000 ,n_test = 5000,bins=20,为保持与第一次任务结果一致性,呈现效果如下:
预测结果:
On Training Data:
HBOS ROC:0.9383, precision @ rank n:0.6667
On Test Data:
HBOS ROC:1.0, precision @ rank n:1.0
其中蓝色和绿色为正常数据,橘色和红色为异常数据,且蓝色和橘色为同一纬数据,绿红为同一纬数据。
通过HBOS算法得到的结果图对比可知:异常分布一般分布在6以下,所占频次低,分布较为规律性,6-8基本为正常数据,异常概率低。
减少数据量数据样本:n_train = 30,n_test = 15,bins=20,后进行预测,呈现效果如下:
预测结果:
On Training Data:
HBOS ROC:0.9915, precision @ rank n:0.9593
On Test Data:
HBOS ROC:0.9932, precision @ rank n:0.9712
可以清晰的预测结果不理想,异常和非异常数据无法分割开来。
5.3 柱形箱数对结果的影响
同数据量:n_train = 10000 ,n_test = 5000,bins=10,减少柱形显示箱数。
可以更清晰的看出异常和非异常数据。
5.4 结论
- 相对大数据量异常检测,使用HBOS才能够有效的检测出异常数据,HBOS算法对大数据量统计更有效。
- 大数据量条件柱形数越少,更能有效的区分异常和非异常数据。
第一次任务见:Task01:异常检测介https://blog.csdn.net/qq_36818174/article/details/112416430
Only For Freedom