关于人工智能:使用Python进行异常检测

4次阅读

共计 4192 个字符,预计需要花费 11 分钟才能阅读完成。

作者 |Rashida Nasrin Sucky
编译 |VK
起源 |Towards Datas Science

异样检测能够作为异样值剖析的一项统计工作来解决。然而如果咱们开发一个机器学习模型,它能够像平常一样自动化,能够节俭很多工夫。

异样检测有很多用例。信用卡欺诈检测、故障机器检测或基于异样特色的硬件零碎检测、基于医疗记录的疾病检测都是很好的例子。还有更多的用例。异样检测的利用只会越来越多。

在本文中,我将解释在 Python 中从头开始开发异样检测算法的过程。

公式和过程

与我之前解释过的其余机器学习算法相比,这要简略得多。该算法将应用均值和方差来计算每个训练数据的概率。

如果一个训练实例的概率很高,这是失常的。如果某个训练实例的概率很低,那就是一个异样的例子。对于不同的训练集,高概率和低概率的定义是不同的。咱们当前再探讨。

如果我要解释异样检测的工作过程,这很简略。

  1. 应用以下公式计算平均值:

这里 m 是数据集的长度或训练数据的数量,而 $x^i$ 是一个独自的训练例子。如果你有多个训练特色,大多数状况下都须要计算每个特色能的平均值。

  1. 应用以下公式计算方差:

这里,mu 是上一步计算的平均值。

  1. 当初,用这个概率公式计算每个训练例子的概率。

不要被这个公式中的求和符号弄糊涂了!这实际上是 Sigma 代表方差。

稍后咱们将实现该算法时,你将看到它的样子。

  1. 咱们当初须要找到概率的临界值。正如我后面提到的,如果一个训练例子的概率很低,那就是一个异样的例子。

低概率有多大?

这没有广泛的限度。咱们须要为咱们的训练数据集找出这个。

咱们从步骤 3 中失去的输入中获取一系列概率值。对于每个概率,通过阈值的设置失去数据是否异样

而后计算一系列概率的精确度、召回率和 f1 分数。

精度可应用以下公式计算

召回率的计算公式如下:

在这里,True positives(真正例)是指算法检测到一个异样的例子的数量,而它真实情况也是一个异样。

False Positives(假正例)当算法检测到一个异样的例子,但在理论状况中,它不是异样的,就会呈现误报。

False Negative(假反例)是指算法检测到的一个例子不是异样的,但实际上它是一个异样的例子。

从下面的公式你能够看出,更高的精确度和更高的召回率总是好的,因为这意味着咱们有更多的真正的正例。但同时,假正例和假反例起着至关重要的作用,正如你在公式中看到的那样。这须要一个平衡点。依据你的行业,你须要决定哪一个对你来说是能够忍耐的。

一个好方法是取平均数。计算平均值有一个独特的公式。这就是 f1 分数。f1 得分公式为:

这里,P 和 R 别离示意精确性和召回率。

我不想具体阐明为什么这个公式如此独特。因为这篇文章是对于异样检测的。如果你对这篇文章更感兴趣的话,能够查看:https://towardsdatascience.co…

依据 f1 分数,你须要抉择你的阈值概率。

异样检测算法

我将应用 Andrew Ng 的机器学习课程的数据集,它具备两个训练特色。我没有在本文中应用实在的数据集,因为这个数据集非常适合学习。它只有两个特色。在任何实在的数据集中,都不可能只有两个特色。

有两个个性的益处是能够可视化数据,这对学习者十分有用。请随便从该链接下载数据集,而后持续:

https://github.com/rashida048…

首先,导入必要的包

import pandas as pd 
import numpy as np

导入数据集。这是一个 excel 数据集。在这里,训练数据和穿插验证数据存储在独自的表中。所以,让咱们把训练数据带来。

df = pd.read_excel('ex8data1.xlsx', sheet_name='X', header=None)
df.head()

让咱们将第 0 列与第 1 列进行比拟。

plt.figure()
plt.scatter(df[0], df[1])
plt.show()

你可能通过看这张图晓得哪些数据是异样的。

查看此数据集中有多少个训练示例:

m = len(df)

计算每个特色的平均值。这里咱们只有两个特色:0 和 1。

s = np.sum(df, axis=0)
mu = s/m
mu

输入:

0    14.112226
1    14.997711
dtype: float64

依据下面“公式和过程”局部中形容的公式,让咱们计算方差:

vr = np.sum((df - mu)**2, axis=0)
variance = vr/m
variance

输入:

0    1.832631
1    1.709745
dtype: float64

当初把它做成对角线形态。正如我在概率公式前面的“公式和过程”一节中所解释的,求和符号实际上是方差

var_dia = np.diag(variance)
var_dia

输入:

array([[1.83263141, 0.],
       [0.        , 1.70974533]])

计算概率:

k = len(mu)
X = df - mu
p = 1/((2*np.pi)**(k/2)*(np.linalg.det(var_dia)**0.5))* np.exp(-0.5* np.sum(X @ np.linalg.pinv(var_dia) * X,axis=1))
p

训练局部曾经实现。

下一步是找出阈值概率。如果概率低于阈值概率,则示例数据为异样数据。但咱们须要为咱们的非凡状况找出那个阈值。

对于这一步,咱们应用穿插验证数据和标签。

对于你的案例,你只需保留一部分原始数据以进行穿插验证。

当初导入穿插验证数据和标签:

cvx = pd.read_excel('ex8data1.xlsx', sheet_name='Xval', header=None)
cvx.head()

标签如下:

cvy = pd.read_excel('ex8data1.xlsx', sheet_name='y', header=None)
cvy.head()

我将把 ’cvy’ 转换成 NumPy 数组,因为我喜爱应用数组。不过,数据帧也不错。

y = np.array(cvy)

输入:

# 数组的一部分
array([[0],
       [0],
       [0],
       [0],
       [0],
       [0],
       [0],
       [0],
       [0],

这里,y 值 0 示意这是一个失常的例子,y 值 1 示意这是一个异样的例子。

当初,如何抉择一个阈值?

我不想只查看概率表中的所有概率。这可能是不必要的。让咱们再检查一下概率值。

p.describe()

输入:

count    3.070000e+02
mean     5.905331e-02
std      2.324461e-02
min      1.181209e-23
25%      4.361075e-02
50%      6.510144e-02
75%      7.849532e-02
max      8.986095e-02
dtype: float64

如图所示,咱们没有太多异样数据。所以,如果咱们从 75% 的值开始,这应该是好的。但为了平安起见,我会从平均值开始。

因而,咱们将从平均值和更低的概率范畴。咱们将查看这个范畴内每个概率的 f1 分数。

首先,定义一个函数来计算真正例、假正例和假反例:

def tpfpfn(ep):
    tp, fp, fn = 0, 0, 0
    for i in range(len(y)):
        if p[i] <= ep and y[i][0] == 1:
            tp += 1
        elif p[i] <= ep and y[i][0] == 0:
            fp += 1
        elif p[i] > ep and y[i][0] == 1:
            fn += 1
    return tp, fp, fn

列出低于或等于均匀概率的概率。

eps = [i for i in p if i <= p.mean()]

检查一下列表的长度

len(eps)

输入:

133

依据后面探讨的公式定义一个计算 f1 分数的函数:

def f1(ep):
    tp, fp, fn = tpfpfn(ep)
    prec = tp/(tp + fp)
    rec = tp/(tp + fn)
    f1 = 2*prec*rec/(prec + rec)
    return f1

所有函数都筹备好了!

当初计算所有 epsilon 或咱们之前抉择的概率值范畴的 f1 分数。

f = []
for i in eps:
    f.append(f1(i))
f

输入:

[0.14285714285714285,
 0.14035087719298248,
 0.1927710843373494,
 0.1568627450980392,
 0.208955223880597,
 0.41379310344827586,
 0.15517241379310345,
 0.28571428571428575,
 0.19444444444444445,
 0.5217391304347826,
 0.19718309859154928,
 0.19753086419753085,
 0.29268292682926833,
 0.14545454545454545,

这是 f 分数表的一部分。长度应该是 133。

f 分数通常在 0 到 1 之间,其中 f1 得分越高越好。所以,咱们须要从方才计算的 f 分数列表中取 f 的最高分数。

当初,应用“argmax”函数来确定 f 分数值最大值的索引。

np.array(f).argmax()

输入:

131

当初用这个索引来失去阈值概率。

e = eps[131]
e

输入:

6.107184445968581e-05

找出异样实例

咱们有临界概率。咱们能够从中找出咱们训练数据的标签。

如果概率值小于或等于该阈值,则数据为异样数据,否则为失常数据。咱们将失常数据和异样数据别离示意为 0 和 1,

label = []
for i in range(len(df)):
    if p[i] <= e:
        label.append(1)
    else:
        label.append(0)
label

输入:

[0,
 0,
 0,
 0,
 0,
 0,
 0,
 0,
 0,
 0,

这是标签列表的一部分。

我将在下面的训练数据集中增加此计算标签:

df['label'] = np.array(label)
df.head()

我在标签为 1 的中央用红色绘制数据,在标签为 0 的中央用彩色绘制。以下是后果。

有情理吗?

是的,对吧?红色的数据显著异样。

论断

我试图一步一步地解释开发异样检测算法的过程,我心愿这是能够了解的。如果你仅仅通过浏览就无奈了解,我倡议你运行每一段代码。那就很分明了。

原文链接:https://towardsdatascience.co…

欢送关注磐创 AI 博客站:
http://panchuang.net/

sklearn 机器学习中文官网文档:
http://sklearn123.com/

欢送关注磐创博客资源汇总站:
http://docs.panchuang.net/

正文完
 0