异常检测步骤:
- 选择处于异常状态(有反常样本)的特征作为输入
- 针对每一个特征计算μ和σ2
μ i = 1 m ∑ j = 1 m x i ( j ) \mu_i=\frac{1}{m}\sum_{j=1}^mx_i^{(j)} μi=m1j=1∑mxi(j)
σ i 2 = 1 m ∑ j = 1 m ( x i ( j ) − μ i ) 2 \sigma_i^2=\frac{1}{m}\sum_{j=1}^m(x_i^{(j)}-\mu_i)^2 σi2=m1j=1∑m(xi(j)−μi)2
你要做的是,输入一个X矩阵,输出2个n维的向量,mu包含了每一个维度的平均值,sigma2包含了每一个维度的方差。
def estimate_gaussian(X):
mu = X.mean(axis=0)
sigma = X.var(axis=0)
return mu, sigma
- 给定一个新的训练实例,根据模型计算p(x),当p(x)<ε为异常
3.1. 计算数据集中每个点的概率密度
python的SciPy工具库中内置了一种计算数据点属于正态分布的概率的方法:
scipy.stats.norm函数参考:https://blog.csdn.net/m0_37586991/article/details/89792673
from scipy import stats
pval = np.zeros((Xval.shape[0], Xval.shape[1]))
pval[:,0] = stats.norm(mu[0], sigma[0]).pdf(Xval[:,0])
pval[:,1] = stats.norm(mu[1], sigma[1]).pdf(Xval[:,1])
3.2. 通过F1 Score评估确定ε的值
输入:数据集概率密度值pval、标签值yval
输出:最佳阈值best_epsilon、best_f1
def select_threshold(pval, yval):
best_epsilon = 0
best_f1 = 0
f1 = 0
step = (pval.max() - pval.min()) / 1000
for epsilon in np.arange(pval.min(), pval.max(), step):
preds = pval < epsilon #根据案例为二维数组,值为1(true) or 0(false)
tp = np.sum(np.logical_and(preds == 1, yval == 1)).astype(float) #正确肯定
fp = np.sum(np.logical_and(preds == 1, yval == 0)).astype(float) #错误肯定
fn = np.sum(np.logical_and(preds == 0, yval == 1)).astype(float) #错误否定
precision = tp / (tp + fp) #计算查准率
recall = tp / (tp + fn) #计算查全率
f1 = (2 * precision * recall) / (precision + recall)
if f1 > best_f1:
best_f1 = f1
best_epsilon = epsilon
return best_epsilon, best_f1
3.3. 当p(x)<ε为异常
outliers保存异常序号
outliers = np.where(p < epsilon)