共计 4192 个字符,预计需要花费 11 分钟才能阅读完成。
作者 |Rashida Nasrin Sucky
编译 |VK
起源 |Towards Datas Science
异样检测能够作为异样值剖析的一项统计工作来解决。然而如果咱们开发一个机器学习模型,它能够像平常一样自动化,能够节俭很多工夫。
异样检测有很多用例。信用卡欺诈检测、故障机器检测或基于异样特色的硬件零碎检测、基于医疗记录的疾病检测都是很好的例子。还有更多的用例。异样检测的利用只会越来越多。
在本文中,我将解释在 Python 中从头开始开发异样检测算法的过程。
公式和过程
与我之前解释过的其余机器学习算法相比,这要简略得多。该算法将应用均值和方差来计算每个训练数据的概率。
如果一个训练实例的概率很高,这是失常的。如果某个训练实例的概率很低,那就是一个异样的例子。对于不同的训练集,高概率和低概率的定义是不同的。咱们当前再探讨。
如果我要解释异样检测的工作过程,这很简略。
- 应用以下公式计算平均值:
这里 m 是数据集的长度或训练数据的数量,而 $x^i$ 是一个独自的训练例子。如果你有多个训练特色,大多数状况下都须要计算每个特色能的平均值。
- 应用以下公式计算方差:
这里,mu 是上一步计算的平均值。
- 当初,用这个概率公式计算每个训练例子的概率。
不要被这个公式中的求和符号弄糊涂了!这实际上是 Sigma 代表方差。
稍后咱们将实现该算法时,你将看到它的样子。
- 咱们当初须要找到概率的临界值。正如我后面提到的,如果一个训练例子的概率很低,那就是一个异样的例子。
低概率有多大?
这没有广泛的限度。咱们须要为咱们的训练数据集找出这个。
咱们从步骤 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/