異常值識別方法小結

 

總覽:

編號 方法
1 經驗判斷
2
3 dbscan
4 lof
5 isolation tree
6 one class svm

 

 

一. 經驗判斷

 

X={x1,x2,...,xn}

IQR=0.75 分位數 - 0.25 分位數

outlier_min=0.25分位數-1.5IQR

outlier_max=0.75分位數+1.5IQR

 

判斷標準:< outlier_min 或者 > outlier_max 則爲異常值 ;

備註:非參數方法

 

二.3σ原則

 

若x~N(u,σ)  

P(|x−μ|>3σ)≤0.003

 

 

三.dbscan

鄰域:對於x_I 來說,若x_J 到x_i的距離小於c,則稱x_j爲x_i的鄰域

核心對象:若x_i鄰域的x_J的數量超過d個,則成x_i爲核心對象

密度直達:x_I 爲核心對象,若x_j在x_i的鄰域內,則成x_j 到 x_j密度直達

密度可達:x_i → x_j → x_k , 其中 x_i → x_j 密度直達 x_j →x_k 密度直達,則 x_i → x_k 密度可達

密度相連:x_k 爲核心樣本, x_i,x_j均有x_k密度可達,那麼x_i,x_j密度連

 

 

 

'''
https://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html
'''

from sklearn.cluster import DBSCAN
from sklearn import datasets
import numpy as np
import matplotlib.pyplot as plt

# 測試樣本
iris=datasets.load_iris()
x=iris.data
y=iris.target

# 獲取eps
def dist(x,y):
    x=np.array(x)
    y=np.array(y)
    return np.sqrt(np.sum(np.square(x - y)))

k=4

k_dist=[]
for i in range(len(x)):
    dist_i=[]
    for j in range(len(y)):
        dist_i.append(dist(x[i],x[j]))
    dist_i.sort()
    dist_i_k=dist_i[k]
    k_dist.append(dist_i_k)

# k-dist 圖
#plt.plot([ele for ele in range(len(k_dist))],k_dist)
#plt.show()


eps=np.percentile(np.array(k_dist),80)

clustering=DBSCAN(eps=eps,min_samples=4).fit(x)
y_hat=clustering.fit_predict(x)
print(y_hat) # -1爲噪聲點



 

 

四. lof (local outlier factor)

  • 也是基於密度的思想,一個異常點的密度比上異常點周圍點的平均密度小於1 或者 反過來 異常點周圍樣本點的平均密度比上樣本點的密度大於1
  •                 

 

第一步是要先找到距離p k近個的集合o

第二步 計算lrd(o) 以及 lrd(p)

 

from sklearn.datasets import load_iris
from sklearn.neighbors import LocalOutlierFactor

iris=load_iris()
x=iris.data

cls=LocalOutlierFactor(n_neighbors=20,algorithm='auto',contamination=0.1)
cls.fit(x)
res=cls.fit_predict(x)
print(res)  # 1表示爲正常值,-1表示爲異常值

 

五.isolation tree

 

流程:

1.劃分n份樣本集

2.對於每份樣本集構造一個itree,如何構造?

step1: 隨機選擇一個特徵

step2:隨機選擇一個特徵中的隨機值,隨機值>= min , 隨機<=max

step3:根據隨機值,進行樣本劃分

滿足條件 : 深度到達一定條件 或者 節點只包含一個樣本

3.計算每個點距離根節點的平均長度(平均的意思是對多顆itree的深度做的平均)

 

那麼平均長度如何度量呢? 看論文:

 

 

BST:  Binary Search Tree  二叉搜索樹

H:harmonic number 調和級數,可以用ln + 歐拉係數進行估計,證明如下;

 

c(n) : 給定n,h(n)的平均

E(c(n)): 對於一系列itree的c(n)的平均

s(n,x):爲異常得分

 

E 與 s(n,x)的關係

 

from sklearn.datasets import load_iris
from sklearn.ensemble import IsolationForest

''' 參數說明
contamination : 異常值比例
n_estimators: 樹的數量
max_samples:每顆樹,樣本的比例0
max_features:每顆樹,特徵個數和比例
bootstrap: true表示有放回,false表示無返回
'''


iris=load_iris()
x=iris.data
cls=IsolationForest(contamination=0.1,n_estimators=30,max_features=3,max_samples=100)
cls.fit(x)
y=cls.predict(x)
print(y)  # -1 表示異常值,1表示正常值

 

 

六.one class svm

from sklearn.svm import OneClassSVM


'''
kernel 根據經驗判斷數據可能是那種分佈。‘linear’:線性;‘rbf’:高斯分佈,默認的;
nu:異常數據百分比
'''

from sklearn.datasets import load_iris
iris=load_iris()
x=iris.data


cls=OneClassSVM(nu=0.1,kernel='rbf')
cls.fit(x)
y=cls.predict(x)
print(y) # -1表示異常,1表示正常

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章