0%

机器学习-05

学习异常检测

概念

给定数据集{$x^{(1)}, $ $x^{(2)}$, …, $x^{(m)}$},建立模型,根据模型判断新数据$x_{test}$是否异常(即是否与元数据集相似)

算法将找出具有高概率和低概率的值

如果:

  • $p(x_{test}) < \epsilon$ -> 异常的信号
  • $p(x_{test}) > \epsilon$ -> OK

应用

  • 欺诈检测
  • 可疑账号检测
  • 装置异常检测
  • 商业、金融

高斯分布(正态分布)

估计量:

异常检测算法

各特征的概率独立,因此可以连乘

过程

  • 选择n个特征xi
  • 求出各自的$\mu_j$和$\sigma_j^2$
  • 根据新给出的样例x,计算p(x)

模型评估与修正

  • 特征选取
  • $\epsilon$选取

大量好的样例和少量异常的样例(还是标签)

  • 使用好的样例训练模型
  • 在交叉验证集(CV)中混杂异常样例,根据损失函数调整$\epsilon$大小和特征
  • 再测试集(test)中混杂异常样例,查看模型普适性和泛化能力

或者:

由于异常数据很少,可以只包含训练集和交叉验证集

但因为没有测试集,观察不了实际表现,可能会过拟合

栗子:

在CV上验证评估模型时,可以使用精确率、召回率、F1分数(在偏数据集中经常使用)

异常检测 VS 监督学习

场景:异常数据远比正常数据少

异常检测:

  • 针对异常数据很少的情况
  • 重点针对正常情况是什么样的进行分析,与正常情况偏离太大的数据都会是异常数据,所以不在数据集中的新的异常方式也有一定适应性

监督学习:

  • 针对大量的正常和异常数据
  • 通过大量数据训练得到依照数据集的规律,所以所能预测的异常都只针对已出现的,对新型异常的适应性不强

特征选择技巧

高斯分布特征

非高斯分布特征 -> 变换 -> 高斯分布特征

变换方式:

  • 次幂
  • log(x + C) 据说C越高越好

python plt的API:

1
2
3
plt.hist(x, bins=50)   # bins 直方图区间个数
plt.hist(x ** 0.4, bins = 50)
plt.hist(np.log(x + 1), bins = 50)

错误分析

  • 希望p(x)对于正常样例足够大
  • 希望p(x)对于异常样例足够小

查看异常数据,如果其p(x)与有的正常数据的p(x)相近,那可能是有特征没有考虑进去

组合特征

根据已知特征进行组合

implement code

计算$\mu$和$\sigma$

1
2
3
4
5
def estimate_gaussian(X):
mu = 1 / m * np.sum(X, axis = 0)
var = (1 / m) * np.sum((X - mu) ** 2, axis = 0)

return mu, var

阈值选择

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# UNQ_C2
# GRADED FUNCTION: select_threshold

def select_threshold(y_val, p_val):
"""
Finds the best threshold to use for selecting outliers
based on the results from a validation set (p_val)
and the ground truth (y_val)

Args:
y_val (ndarray): Ground truth on validation set
p_val (ndarray): Results on validation set

Returns:
epsilon (float): Threshold chosen
F1 (float): F1 score by choosing epsilon as threshold
"""

best_epsilon = 0
best_F1 = 0
F1 = 0

step_size = (max(p_val) - min(p_val)) / 1000

for epsilon in np.arange(min(p_val), max(p_val), step_size):

predictions = (p_val < epsilon)

tp = np.sum((predictions == 1) & (y_val == 1))
fp = np.sum((predictions == 1) & (y_val == 0))
fn = np.sum((predictions == 0) & (y_val == 1))

prec = tp / (tp + fp) # 精确率
rec = tp / (tp + fn) # 召回率

F1 = 2 * prec * rec / (prec + rec) # F1分数

if F1 > best_F1:
best_F1 = F1
best_epsilon = epsilon

return best_epsilon, best_F1

多元高斯分布计算函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def multivariate_gaussian(X, mu, var):
"""
Computes the probability
density function of the examples X under the multivariate gaussian
distribution with parameters mu and var. If var is a matrix, it is
treated as the covariance matrix. If var is a vector, it is treated
as the var values of the variances in each dimension (a diagonal
covariance matrix
"""

k = len(mu)

if var.ndim == 1:
var = np.diag(var)

X = X - mu
p = (2* np.pi)**(-k/2) * np.linalg.det(var)**(-0.5) * \
np.exp(-0.5 * np.sum(np.matmul(X, np.linalg.pinv(var)) * X, axis=1))
# np.linalg.det表示矩阵行列式,np.linalg.pinv表示矩阵的伪逆

return p

调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Estimate the Gaussian parameters
mu, var = estimate_gaussian(X_train_high)

# Evaluate the probabilites for the training set
p = multivariate_gaussian(X_train, mu, var)

# Evaluate the probabilites for the cross validation set
p_val = multivariate_gaussian(X_val, mu, var)

# Find the best threshold
epsilon, F1 = select_threshold(y_val, p_val)

print('Best epsilon found using cross-validation: %e'% epsilon)
print('Best F1 on Cross Validation Set: %f'% F1)
print('# Anomalies found: %d'% sum(p_high < epsilon))