Anomaly detection

异常检测是机器学习中比较常见的应用,它主要用于非监督学习问题,从某些角度看, 它又类似于一些监督学习问题。
什么是异常检测?来看几个例子:
例1. 假设是飞机引擎制造商, 要对引擎进行质量控制测试,现在测量了飞机引擎的一些特征变量,比如引擎运转时产生的热量,引擎的震动,然后得到了两个特征的无标签数据集, 现在有了新的特征变量xtest ,我们希望这个新飞机引擎是否有某种异常。就是异常检测。

在这次练习中,实现一个异常检测算法来检测服务器计算机中的异常行为。这些特性测量每个服务器的响应速度 (mb/s)和响应延迟(ms)。
收集到了m=307的样本,无标签。相信其中绝大多数样本是正常的,但还是有一小部分的样本是异常的。

mat = loadmat('ex8data1.mat')
print(mat.keys())
X = mat['X']
Xval, yval = mat['Xval'], mat['yval']
X.shape, Xval.shape, yval.shape
def gaussian(X, mu, sigma2):m, n = X.shapeif np.ndim(sigma2) == 1:sigma2 = np.diag(sigma2)norm = 1. / (np.power((2 * np.pi), n / 2) * np.sqrt(np.linalg.det(sigma2)))exp = np.zeros((m, 1))for row in range(m):xrow = X[row]exp[row] = np.exp(-0.5 * ((xrow - mu).T).dot(np.linalg.inv(sigma2)).dot(xrow - mu))return norm * exp

Gaussian distribution

高斯分布,也称为正态分布,变量x 符合高斯分布 xN(µ,σ2)x~N(µ, σ^{2})x N(µ,σ2) 则其概率密度函数为:

利用已有的数据来预测总体中的µ和σ2的计算方法如下:利用已有的数据来预测总体中的µ和σ^{2}的计算方法如下:利用已有的数据来预测总体中的µ和σ2的计算方法如下:

一旦我们获得了平均值和方差的估计值,给定新的一个训练实例,根据模型计算 p(x):

当p(x) < ε, 为异常。

Estimating parameters for a Gaussian

def get_gaussian_params(X, useMultivariate):mu = X.mean(axis=0)if useMultivariate:sigma2 = ((X - mu).T @ (X - mu)) / len(X)else:sigma2 = X.var(axis=0, ddof=0)  # 样本方差return mu, sigma2
def plot_contours(mu, sigma2):"""画出高斯概率分布的图,在三维中是一个上凸的曲面。投影到平面上则是一圈圈的等高线。"""delta = .3  # 注意delta不能太小!!!否则会生成太多的数据,导致矩阵相乘会出现内存错误。x = np.arange(0, 30, delta)y = np.arange(0, 30, delta)# 这部分要转化为X形式的坐标矩阵,也就是一列是横坐标,一列是纵坐标,# 然后才能传入gaussian中求解得到每个点的概率值xx, yy = np.meshgrid(x, y)points = np.c_[xx.ravel(), yy.ravel()]  # 按列合并,一列横坐标,一列纵坐标z = gaussian(points, mu, sigma2)z = z.reshape(xx.shape)  # 这步骤不能忘cont_levels = [10 ** h for h in range(-20, 0, 3)]plt.contour(xx, yy, z, cont_levels)  # 这个levels是作业里面给的参考,或者通过求解的概率推出来。plt.title('Gaussian Contours', fontsize=16)

First contours without using multivariate gaussian

plot_data()
useMV = False
plot_contours(*get_gaussian_params(X, useMV))# Then contours with multivariate gaussian:
plot_data()
useMV = True
# *表示解元组
plot_contours(*get_gaussian_params(X, useMV))

Selecting the threshold, ε

确定哪些例子是异常的一种方法是通过一组交叉验证集,选择一个好的阈值 ε 。

在这部分的练习中,您将实现一个算法使用交叉验证集的F1分数来选择合理的阈值 ε

tp means true positives:是异常值,并且我们的模型预测成异常值了,即真的异常值。
fp means false positives:是正常值,但模型把它预测成异常值,即假的异常值。
fn means false negatives:是异常值,但是模型把它预测成正常值,即假的正常值。

precision 表示你预测为positive的样本中有多少是真的positive的样本。
recall 表示实际有多少positive的样本,而你成功预测出多少positive的样本。

def select_threshold(yval, pval):def computeF1(yval, pval):m = len(yval)tp = float(len([i for i in range(m) if pval[i] and yval[i]]))fp = float(len([i for i in range(m) if pval[i] and not yval[i]]))fn = float(len([i for i in range(m) if not pval[i] and yval[i]]))prec = tp / (tp + fp) if (tp + fp) else 0rec = tp / (tp + fn) if (tp + fn) else 0F1 = 2 * prec * rec / (prec + rec) if (prec + rec) else 0return F1epsilons = np.linspace(min(pval), max(pval), 1000)bestF1, bestEpsilon = 0, 0for e in epsilons:pval_ = pval < ethisF1 = computeF1(yval, pval_)if thisF1 > bestF1:bestF1 = thisF1bestEpsilon = ereturn bestF1, bestEpsilon
mu, sigma2 = get_gaussian_params(X, useMultivariate=False)
pval = gaussian(Xval, mu, sigma2)
bestF1, bestEpsilon = select_threshold(yval, pval)
# (0.8750000000000001, 8.999852631901397e-05)y = gaussian(X, mu, sigma2)  # X的概率
xx = np.array([X[i] for i in range(len(y)) if y[i] < bestEpsilon])
xx  # 离群点plot_data()
plot_contours(mu, sigma2)
plt.scatter(xx[:, 0], xx[:, 1], s=80, facecolors='none', edgecolors='r')
# High dimensional dataset
mat = loadmat('ex8data2.mat')
X2 = mat['X']
Xval2, yval2 = mat['Xval'], mat['yval']
X2.shape  # (1000, 11)mu, sigma2 = get_gaussian_params(X2, useMultivariate=False)
ypred = gaussian(X2, mu, sigma2)yval2pred = gaussian(Xval2, mu, sigma2)# You should see a value epsilon of about 1.38e-18, and 117 anomalies found.
bestF1, bestEps = select_threshold(yval2, yval2pred)
anoms = [X2[i] for i in range(X2.shape[0]) if ypred[i] < bestEps]
bestEps, len(anoms)

Recommender Systems

Movie ratings dataset

mat = loadmat('ex8_movies.mat')
print(mat.keys())
Y, R = mat['Y'], mat['R']
nm, nu = Y.shape  # Y中0代表用户没有评分
nf = 100
Y.shape, R.shape
# ((1682, 943), (1682, 943))Y[0].sum() / R[0].sum()  # 分子代表第一个电影的总分数,分母代表这部电影有多少评分数据# "Visualize the ratings matrix"
fig = plt.figure(figsize=(8,8*(1682./943.)))
plt.imshow(Y, cmap='rainbow')
plt.colorbar()
plt.ylabel('Movies (%d) ' % nm, fontsize=20)
mat = loadmat('ex8_movieParams.mat')
X = mat['X']
Theta = mat['Theta']
nu = int(mat['num_users'])
nm = int(mat['num_movies'])
nf = int(mat['num_features'])
# For now, reduce the data set size so that this runs faster
nu = 4
nm = 5
nf = 3
X = X[:nm, :nf]
Theta = Theta[:nu, :nf]
Y = Y[:nm, :nu]
R = R[:nm, :nu]

Collaborative filtering learning algorithm

# 展开参数
def serialize(X, Theta):return np.r_[X.flatten(),Theta.flatten()]# 提取参数
def deserialize(seq, nm, nu, nf):return seq[:nm*nf].reshape(nm, nf), seq[nm*nf:].reshape(nu, nf)
Collaborative filtering cost function
def co_fi_cost_func(params, Y, R, nm, nu, nf, l=0):"""params : 拉成一维之后的参数向量(X, Theta)Y : 评分矩阵 (nm, nu)R :0-1矩阵,表示用户对某一电影有无评分nu : 用户数量nm : 电影数量nf : 自定义的特征的维度l : lambda for regularization"""X, Theta = deserialize(params, nm, nu, nf)# (X@Theta)*R含义如下: 因为X@Theta是我们用自定义参数算的评分,但是有些电影本来是没有人# 评分的,存储在R中,0-1表示。将这两个相乘,得到的值就是我们要的已经被评分过的电影的预测分数。error = 0.5 * np.square((X @ Theta.T - Y) * R).sum()reg1 = .5 * l * np.square(Theta).sum()reg2 = .5 * l * np.square(X).sum()return error + reg1 + reg2co_fi_cost_func(serialize(X,Theta),Y,R,nm,nu,nf),co_fi_cost_func(serialize(X,Theta),Y,R,nm,nu,nf,1.5)
Collaborative filtering gradient
def check_gradient(params, Y, myR, nm, nu, nf, l=0.):"""Let's check my gradient computation real quick"""print('Numerical Gradient \t cofiGrad \t\t Difference')# 分析出来的梯度grad = co_fi_gradient(params, Y, myR, nm, nu, nf, l)# 用 微小的e 来计算数值梯度。e = 0.0001nparams = len(params)e_vec = np.zeros(nparams)# Choose 10 random elements of param vector and compute the numerical gradient# 每次只能改变e_vec中的一个值,并在计算完数值梯度后要还原。for i in range(10):idx = np.random.randint(0, nparams)e_vec[idx] = eloss1 = co_fi_cost_func(params - e_vec, Y, myR, nm, nu, nf, l)loss2 = co_fi_cost_func(params + e_vec, Y, myR, nm, nu, nf, l)numgrad = (loss2 - loss1) / (2 * e)e_vec[idx] = 0diff = np.linalg.norm(numgrad - grad[idx]) / np.linalg.norm(numgrad + grad[idx])print('%0.15f \t %0.15f \t %0.15f' % (numgrad, grad[idx], diff))print("Checking gradient with lambda = 0...")
check_gradient(serialize(X, Theta), Y, R, nm, nu, nf)
print("\nChecking gradient with lambda = 1.5...")
check_gradient(serialize(X, Theta), Y, R, nm, nu, nf, l=1.5)

Learning movie recommendations

movies = []  # 包含所有电影的列表
with open('data/movie_ids.txt', 'r', encoding='utf-8') as f:for line in f:
#         movies.append(' '.join(line.strip().split(' ')[1:]))movies.append(' '.join(line.strip().split(' ')[1:]))my_ratings = np.zeros((1682, 1))my_ratings[0] = 4
my_ratings[97] = 2
my_ratings[6] = 3
my_ratings[11] = 5
my_ratings[53] = 4
my_ratings[63] = 5
my_ratings[65] = 3
my_ratings[68] = 5
my_ratings[182] = 4
my_ratings[225] = 5
my_ratings[354] = 5for i in range(len(my_ratings)):if my_ratings[i] > 0:print(my_ratings[i], movies[i])mat = loadmat('data/ex8_movies.mat')
Y, R = mat['Y'], mat['R']
Y.shape, R.shapeY = np.c_[Y, my_ratings]  # (1682, 944)
R = np.c_[R, my_ratings!=0]  # (1682, 944)
nm, nu = Y.shape
nf = 10 # 我们使用10维的特征向量def normalizeRatings(Y, R):"""The mean is only counting movies that were rated"""Ymean = (Y.sum(axis=1) / R.sum(axis=1)).reshape(-1,1)
#     Ynorm = (Y - Ymean)*R  # 这里也要注意不要归一化未评分的数据Ynorm = (Y - Ymean)*R  # 这里也要注意不要归一化未评分的数据return Ynorm, YmeanYnorm, Ymean = normalizeRatings(Y, R)
Ynorm.shape, Ymean.shape
# ((1682, 944), (1682, 1))X = np.random.random((nm, nf))
Theta = np.random.random((nu, nf))
params = serialize(X, Theta)
l = 10
Recommendations
import scipy.optimize as opt
res = opt.minimize(fun=co_fi_cost_func(),x0=params,args=(Y, R, nm, nu, nf, l),method='TNC',jac=co_fi_gradient(),options={'maxiter': 100})ret = res.xfit_X, fit_Theta = deserialize(ret, nm, nu, nf)# Recommendations
# 所有用户的剧场分数矩阵
pred_mat = fit_X @ fit_Theta.T# 最后一个用户的预测分数, 也就是我们刚才添加的用户
pred = pred_mat[:,-1] + Ymean.flatten()pred_sorted_idx = np.argsort(pred)[::-1] # 排序并翻转,使之从大到小排列print("Top recommendations for you:")
for i in range(10):print('Predicting rating %0.1f for movie %s.' \% (pred[pred_sorted_idx[i]], movies[pred_sorted_idx[i]]))print("\nOriginal ratings provided:")
for i in range(len(my_ratings)):if my_ratings[i] > 0:print('Rated %d for movie %s.' % (my_ratings[i], movies[i]))

机器学习实践七----异常检测和推荐系统相关推荐

  1. 入门机器学习(二十)--编程作业-异常检测和推荐系统(Python实现)

    编程作业–异常检测和推荐系统 在本练习中,我们将使用高斯模型实现异常检测算法,并将其应用于检测网络上的故障服务器. 我们还将看到如何使用协作过滤构建推荐系统,并将其应用于电影推荐数据集. Anomal ...

  2. 机器学习编程作业ex8(matlab/octave实现)-吴恩达coursera 异常检测与推荐系统/协同过滤

    程序打包网盘地址提取码1111 一.(Week 9)内容回顾 非监督学习问题的两种应用:异常检测与推荐系统 1.1 Anomaly Detection 异常检测 1.Density Estimatio ...

  3. 基于机器学习的web异常检测

    Web防火墙是信息安全的第一道防线.随着网络技术的快速更新,新的黑客技术也层出不穷,为传统规则防火墙带来了挑战.传统web入侵检测技术通过维护规则集对入侵访问进行拦截.一方面,硬规则在灵活的黑客面前, ...

  4. 经典算法笔记:异常检测和推荐系统

    本文是吴恩达老师的机器学习课程[1]的笔记和代码复现部分(聚类.降维). 作者:黄海广[2] 备注:笔记和作业(含数据.原始作业文件).视频都在github[3]中下载. 我将陆续将课程笔记和课程代码 ...

  5. 基于机器学习的web异常检测(转)

    阿里聚安全 Web防火墙是信息安全的第一道防线.随着网络技术的快速更新,新的黑客技术也层出不穷,为传统规则防火墙带来了挑战.传统web入侵检测技术通过维护规则集对入侵访问进行拦截.一方面,硬规则在灵活 ...

  6. 基于机器学习的web异常检测——基于HMM的状态序列建模,将原始数据转化为状态机表示,然后求解概率判断异常与否...

    基于机器学习的web异常检测 from: https://jaq.alibaba.com/community/art/show?articleid=746 Web防火墙是信息安全的第一道防线.随着网络 ...

  7. 机器学习中的异常检测

    机器学习最常用的应用程序之一是异常检测.寻找和识别异常有助于防止欺诈.对手攻击和网络入侵,所有这些都可能危及公司的未来. 在这篇文章中,我们将讨论如何进行异常检测,可以使用哪些机器学习技术,以及使用机 ...

  8. 基于机器学习的KPI异常检测(当初的讲课课件)

    基于机器学习的KPI异常检测(当初的讲课课件)

  9. 基于Spark的机器学习实践 (七) - 回归算法

    0 相关源码 1 回归分析概述 1.1 回归分析介绍 ◆ 回归与分类类似,只不过回归的预测结果是连续的,而分类的预测结果是离散的 ◆ 如此,使得很多回归与分类的模型可以经过改动而通用 ◆ 因此对于回归 ...

最新文章

  1. 软件架构是软件的组织形式
  2. java case or_java – 在CriteriaBuilder中使用子句和’case w...
  3. 【CVPR Oral】TensorFlow实现StarGAN代码全部开源,1天训练完
  4. python编写程序的一般步骤-Python:开发_基本流程
  5. 高性能最终一致性框架Ray之基本概念原理
  6. react学习(13)-moment中 isRangePicker 控制类型
  7. shell中执行某条语句失败能不能重复执行_如何理解Mysql中的事务隔离级别?
  8. Android逆向笔记-使用Android Killer修改包名Android系统安装相同应用
  9. 顺序表 (数组) 详解
  10. 80-600-020-原理-存储引擎-简介
  11. grasshop 犀牛5.0下载_神契幻奇谭 v1.129版发布 快来下载神契幻奇谭2020最新官方版...
  12. 神经网络训练输入数据并行化
  13. WPF的5种绑定模式(mode)
  14. matlab 添加断点,matlab设置断点
  15. 太阳能供电锂电充电IC
  16. npm查看源地址以及更换源地址
  17. TIC TAC TOE 井字游戏
  18. JAV----------数组操作
  19. sdn主要包含哪些接口_解读SDN的东西、南北向接口
  20. python中美元人汇率_Python爬虫练习:爬取美元历史汇率

热门文章

  1. AD软件之模块化原理图
  2. Linux串口阻塞与非阻塞
  3. 【精华文】C语言结构体特殊情况分析:结构体指针 / 基本数据类型指针,指向其他结构体
  4. 大牛带你直击优秀开源框架灵魂,给大家安排上!
  5. Cookie,Session基础知识
  6. [Swift]LeetCode884. 两句话中的不常见单词 | Uncommon Words from Two Sentences
  7. [设计模式]State模式
  8. 微信小程序把玩(三十三)Record API
  9. JavaWeb项目前端规范(采用命名空间使js深度解耦合)
  10. Android LBS系列05 位置策略(一)