zoukankan      html  css  js  c++  java
  • 机器学习作业---异常检测

    一:异常检测回顾

    异常检测也是一个无监督学习算法

    (一)异常检测做什么?

    从一组数据中找到那些“异常”的数据,基于高斯分布(正态分布)。

    生活中的很多事情都是符合高斯分布的,对于数据也是如此。

    我们通过参数估计,估计出数据符合的高斯分布参数,当其中的数据分布在高斯分布中概率很小的地方,就认为这是异常数据。

    (二)具体怎么做?

    选择那些你认为处于异常状态(有反常样本)的特征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)

  • 相关阅读:
    php 循环
    php 函数
    bzoj4541 [Hnoi2016]矿区
    bzoj4836 [Lydsy2017年4月月赛]二元运算
    bzoj4555 [Tjoi2016&Heoi2016]求和
    COGS2287 [HZOI 2015]疯狂的机器人
    bzoj3142 [Hnoi2013]数列
    bzoj4318 OSU!
    bzoj4247 挂饰
    bzoj2756 [SCOI2012]奇怪的游戏
  • 原文地址:https://www.cnblogs.com/ssyfj/p/12973671.html
Copyright © 2011-2022 走看看