機器學習作業---異常檢測


一:異常檢測回顧

異常檢測也是一個無監督學習算法

(一)異常檢測做什么?

從一組數據中找到那些“異常”的數據,基於高斯分布(正態分布)。

生活中的很多事情都是符合高斯分布的,對於數據也是如此。

我們通過參數估計,估計出數據符合的高斯分布參數,當其中的數據分布在高斯分布中概率很小的地方,就認為這是異常數據。

(二)具體怎么做?

選擇那些你認為處於異常狀態(有反常樣本)的特征xj作為輸入:(下面是該xj特征的樣本)

根據上面每個特征的樣本數據估計高斯分布的參數(對每一個特征)

對於一個新的數據,預測其發生概率

當概率小於一定閾值后認定為異常。

(三)這個算法有什么缺點?

可以看到,之前的模型中對每個特征都是獨立地處理,最后的組合只是簡單的相乘。這樣就是存在一些問題,特征之間的關聯沒有捕捉到。
升級的方式就是多元高斯分布,將不再單獨考慮特征,而是將特征一起考慮,自動捕捉之間的關聯。

參數的估計變為,其中的sigma為協方差矩陣:

預測變為:

這個模型有個前提就是m>n,而且協方差矩陣是非奇異矩陣。另外這個計算也是復雜的。

(四)怎么評估算法的效果?

使用標簽化的數據,計算F1score:

查准率和查全率公式:

二:作業介紹

在本練習中,將實現一個異常檢測算法來檢測服務器計算機中的異常行為。這些特性度量每個服務器的吞吐量(mb/s)和響應延遲(ms)。在您的服務器運行時,您收集了m = 307個關於它們行為的示例,因此有一個未標記的dataset {x(1),…,x(m)}。您懷疑這些示例中的絕大多數都是服務器正常運行的“正常”(非異常)示例,但是也可能有一些服務器在這個數據集中異常運行的示例。

將使用高斯模型來檢測數據集中的異常示例。您將首先從一個2D數據集開始,該數據集將允許您可視化算法在做什么。在該數據集上,將擬合高斯分布,然后找到概率非常低的值,因此可以考慮異常。之后,您將把異常檢測算法應用於具有多個維度的較大數據集

三:數據導入及可視化

import numpy as np
import matplotlib.pyplot as plt
import scipy.io as sio

data = sio.loadmat("ex8data1.mat")
X = data['X']
Xval = data['Xval'] #獲取驗證集
yval = data['yval'].flatten()

print(X.shape)
print(Xval.shape,yval.shape)

plt.figure()
plt.scatter(X[:,0],X[:,1],c='b',marker='x',s=15,linewidths=1)
plt.show()

四:估計高斯分布的參數(對每一個特征)均值和方差

def estimate_gussian(X):
    mu = np.mean(X,0)
    sigma2 = np.sum(np.power(X-mu,2),0)/X.shape[0]

    return mu,sigma2
data = sio.loadmat("ex8data1.mat")
X = data['X']
Xval = data['Xval'] #獲取驗證集
yval = data['yval'].flatten()

mu,sigma2 = estimate_gussian(X)
print(mu)
print(sigma2)

五:實現高斯分布模型

def gaussian_distribution(X,mu,sigma2):
    p = (1/np.sqrt(2*np.pi*sigma2))*np.exp(-np.power((X-mu),2)/(2*sigma2))
    return np.prod(p,axis=1)    #橫向累乘
px = gaussian_distribution(X,mu,sigma2)
print(px.shape)
print(px[:10])

六:繪制輪廓線,進行可視化

def visualize_countours(mu,sigma2): #繪制高斯分布等高線
    #由上圖可以知道,我們選取5-25,范圍比較合適
    x = np.linspace(5,25,100)
    y = np.linspace(5,25,100)

    xx,yy =np.meshgrid(x,y)
    X = np.c_[xx.flatten(),yy.flatten()]    #數據對應網格中每一個點
    z = gaussian_distribution(X,mu,sigma2).reshape(xx.shape)    #獲取每一個點坐標的高斯值
    cont_levels = [10 ** h for h in range(-20, 0, 3)] #當z為當前列表的值才繪出等高線(最高1) 不設置的話,會比較奇怪     plt.contour(xx,yy,z,cont_levels)
data = sio.loadmat("ex8data1.mat")
X = data['X']
Xval = data['Xval'] #獲取驗證集
yval = data['yval'].flatten()

mu,sigma2 = estimate_gussian(X)
px = gaussian_distribution(X,mu,sigma2)

plt.figure()
visualize_countours(mu,sigma2)
plt.scatter(X[:,0],X[:,1],c='b',marker='x',s=15,linewidths=1)
plt.show()

七:選擇閾值

取最好的F1分數及對應的閾值進行返回

計算F1score:

查准率和查全率公式:

def select_threshold(yval,pval): #yval是驗證集標簽 0或者1,pval是我們進行高斯處理后得到的概率在[0,1]之間
    best_eps = 0
    best_f1 = 0

    for epsilon in np.linspace(np.min(pval),np.max(pval),num=1001):
 predictions = np.where(pval < epsilon, 1, 0) # 小於epsilon則預測為異常(為真) 滿足條件返回1,不滿足返回0 tp = np.sum(yval[np.where(predictions==1)]) #正確肯定 上面預測的為1,並且yval中也是1,我們才進行添加 fp = np.sum(np.where(yval[np.where(predictions==1)]==0,1,0)) #錯誤肯定 預測為真,實際為假 fn = np.sum(np.where(yval[np.where(predictions==0)]==1,1,0)) #錯誤否定

        #計算查准率和查全率
        if tp+fp == 0 or tp + fn ==0: continue

        prec = tp / (tp + fp)  # 查准率
        rec = tp / (tp + fn)  # 查全率

        #計算F1-score
        f1 = 2*prec*rec/(prec+rec)

        if f1 > best_f1:
            best_f1 = f1
            best_eps = epsilon

    return best_eps,best_f1
mu,sigma2 = estimate_gussian(X)  #利用訓練集獲取均值方差 px = gaussian_distribution(Xval,mu,sigma2)  #利用驗證集數據,獲取高斯概率 eps,f1 = select_threshold(yval,px)  #利用驗證集標簽進行判斷,獲取閾值 print(eps,f1)

八:根據閾值來判斷異常

def detection(X,eps,mu,sigma2):
    px = gaussian_distribution(X,mu,sigma2) #獲取訓練集的高斯分布值
    #進行判斷異常點
    anomaly_points = X[np.where(px<eps)]
    return anomaly_points
def circle_anomaly_points(X):   #將異常點圈出
    plt.scatter(X[:,0],X[:,1],s=80,facecolors='none', edgecolors='r')
data = sio.loadmat("ex8data1.mat")
X = data['X']
Xval = data['Xval'] #獲取驗證集
yval = data['yval'].flatten()

mu,sigma2 = estimate_gussian(X)
px = gaussian_distribution(Xval,mu,sigma2)

eps,f1 = select_threshold(yval,px)
anomaly_points = detection(X,eps,mu,sigma2)

plt.figure()
visualize_countours(mu,sigma2)
circle_anomaly_points(anomaly_points)
plt.scatter(X[:,0],X[:,1],c='b',marker='x',s=15,linewidths=1)
plt.show()

九:高維數據異常檢測

import numpy as np
import matplotlib.pyplot as plt
import scipy.io as sio

def estimate_gussian(X):
    mu = np.mean(X,0)
    sigma2 = np.sum(np.power(X-mu,2),0)/X.shape[0]

    return mu,sigma2

def gaussian_distribution(X,mu,sigma2): #獲取高斯模型p(x)值
    p = (1/np.sqrt(2*np.pi*sigma2))*np.exp(-np.power((X-mu),2)/(2*sigma2))
    return np.prod(p,axis=1)    #橫向累乘

def select_threshold(yval,pval): #yval是驗證集標簽 0或者1,pval是我們進行高斯處理后得到的概率在[0,1]之間
    best_eps = 0
    best_f1 = 0

    for epsilon in np.linspace(np.min(pval),np.max(pval),num=1001):
        predictions = np.where(pval < epsilon, 1, 0)  # 小於epsilon則預測為異常(為真) 滿足條件返回1,不滿足返回0
        tp = np.sum(yval[np.where(predictions==1)]) #正確肯定 上面預測的為1,並且yval中也是1,我們才進行添加
        fp = np.sum(np.where(yval[np.where(predictions==1)]==0,1,0))   #錯誤肯定 預測為真,實際為假
        fn = np.sum(np.where(yval[np.where(predictions==0)]==1,1,0))  #錯誤否定

        #計算查准率和查全率
        if tp+fp == 0 or tp + fn ==0:
            continue

        prec = tp / (tp + fp)  # 查准率
        rec = tp / (tp + fn)  # 查全率

        #計算F1-score
        f1 = 2*prec*rec/(prec+rec)

        if f1 > best_f1:
            best_f1 = f1
            best_eps = epsilon

    return best_eps,best_f1

def detection(X,eps,mu,sigma2):
    px = gaussian_distribution(X,mu,sigma2) #獲取訓練集的高斯分布值
    #進行判斷異常點
    anomaly_points = X[np.where(px<eps)]
    return anomaly_points

def visualize_countours(mu,sigma2): #繪制高斯分布等高線
    #由上圖可以知道,我們選取5-25,范圍比較合適
    x = np.linspace(5,25,100)
    y = np.linspace(5,25,100)

    xx,yy =np.meshgrid(x,y)
    X = np.c_[xx.flatten(),yy.flatten()]    #數據對應網格中每一個點
    z = gaussian_distribution(X,mu,sigma2).reshape(xx.shape)    #獲取每一個點坐標的高斯值
    cont_levels = [10 ** h for h in range(-20, 0, 3)]   #當z為當前列表的值才繪出等高線(最高1)   不設置的話,會比較奇怪
    plt.contour(xx,yy,z,cont_levels)

def circle_anomaly_points(X):   #將異常點圈出
    plt.scatter(X[:,0],X[:,1],s=80,facecolors='none', edgecolors='r')

data = sio.loadmat("ex8data2.mat")
X = data['X']
print(X.shape)
Xval = data['Xval'] #獲取驗證集
yval = data['yval'].flatten()

mu,sigma2 = estimate_gussian(X)
px = gaussian_distribution(Xval,mu,sigma2)
print(px)   #(1000, 11)

eps,f1 = select_threshold(yval,px)
print(eps,f1)

anomaly_points = detection(X,eps,mu,sigma2)
print(anomaly_points)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM