百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

机器学习编程作业8- 异常检测和推荐系统(Python版)

toyiye 2024-06-23 18:33 17 浏览 0 评论

本次编程作业的实现环境是Python3、Anaconda3(64-bit)、Jupyter Notebook。是在深度之眼“机器学习训练营”作业基础上完成的,个别代码有修改,供交流学习之用。

Anomaly detection(异常检测)?

我们的第一个任务是使用高斯模型来检测数据集中未标记的示例是否应被视为异常。 我们有一个简单的二维数据集开始,以帮助可视化该算法正在做什么。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sb
from scipy.io import loadmat

#读取ex8data1的数据
data = loadmat('data/ex8data1.mat')
#data
for key in data.keys():
 print(key, ' ')
X = data['X']
X.shape, data['Xval'].shape, data['yval'].shape
print(X)

#将data['X']的二维数据绘制出来
fig, ax = plt.subplots(figsize = (12, 8))
ax.scatter(X[:,0], X[:,1])
plt.show()

这是一个非常紧密的聚类,几个值远离了聚类。 在这个简单的例子中,这些可以被认为是异常的。 为了弄清楚,我们正在为数据中的每个特征估计高斯分布。 为此,我们将创建一个返回每个要素的均值和方差的函数。

def estimate_gaussian(X):
# INPUT:数据X
# OUTPUT:数据的均值和方差
# TODO:根据数据计算均值和方差,高斯分布
 
 # STEP:根据数据计算均值和方差
 mu = np.mean(X, axis=0)
 #sigma = np.power(np.std(X, axis=0), 2)
 sigma = np.var(X, axis=0)
 
 return mu, sigma

mu, sigma = estimate_gaussian(X)
mu, sigma

Out[128]:

(array([14.11222578, 14.99771051]), array([1.83263141, 1.70974533]))

现在我们有了我们的模型参数,我们需要确定概率阈值,这表明一个样本应该被认为是一个异常。 为此,我们需要使用一组标记的验证数据(其中真实异常样本已被标记),并在给出不同阈值的情况下,对模型的性能进行鉴定。

Xval = data['Xval']
yval = data['yval']
?
print(type(Xval), Xval.shape, type(yval), yval.shape)
print(Xval, yval)

我们还需要一种计算数据点属于正态分布的概率的方法。 幸运的是SciPy有这个内置的方法。

from scipy import stats
dist = stats.norm(mu[0], sigma[0]) #实现正态分布即高斯分布,?换一种方式试试?
dist.pdf(x=15) #计算在x处的概率密度函数,默认均值为0,方差为1

Out[130]:

0.1935875044615038

我们还可以将数组传递给概率密度函数,并获得数据集中每个点的概率密度。

dist.pdf(X[:,0])[0:10]

Out[131]:

array([0.183842 , 0.20221694, 0.21746136, 0.19778763, 0.20858956,
 0.21652359, 0.16991291, 0.15123542, 0.1163989 , 0.1594734 ])

我们定义高斯分布函数,计算并保存给定上述的高斯模型参数的数据集中每个值的概率密度。

def Gaussian(X, mu, sigma):
 px = (1 / (np.sqrt(2 * np.pi * sigma))) * np.exp(-np.power((X - mu), 2) / (2*sigma))
 return px[:,0] * px[:,1]
?
px = Gaussian(X, mu, sigma)
print(pp[0:12])

[0.06470829 0.05030417 0.07245035 0.05031575 0.06368497 0.04245832

0.04790945 0.03651115 0.0186658 0.05068826 0.02651509 0.08471302]

我们还需要为验证集(使用相同的模型参数)执行此操作。 我们将使用与真实标签组合的这些概率来确定将数据点分配为异常的最佳概率阈值。

pxval = Gaussian(Xval, mu, sigma)
pxval.min(), pxval.max(), pxval, len(pxval)

接下来,我们需要一个函数,找到给定概率密度值和真实标签的最佳阈值。 为了做到这一点,我们将为不同的epsilon值计算F1分数。 F1是真阳性,假阳性和假阴性的数量的函数。 方程式在练习文本中。

def select_threshold(pval, yval):
# INPUT:交叉验证集数据pval,标签yval
# OUTPUT:最好的参数epsilon,最高的得分F1
# TODO:寻找最好的参数epsilon,最高的得分F1
 
 # STEP1:初始化变量
 best_epsilon = 0
 best_f1 = 0
 f1 = 0
 
 step = (pval.max() - pval.min()) / 1000 #设定步长
 
 # STEP2:计算F1分数
 for epsilon in np.arange(pval.min()+step, pval.max(), step):
 preds = pval < epsilon
 
 tp = yval[preds==1].sum() #真阳性样本数,预测为真实际为真
 precision = tp / preds.sum() #查准率,在预测为真的样本里实际为真样本所占比例
 recall = tp / yval.sum() #查全率,在实际为真的样本里预测为真样本所占比例
 f1 = 2 * precision * recall / (precision + recall)
 
 if f1 > best_f1:
 best_f1 = f1
 best_epsilon = epsilon
 
 return best_epsilon, best_f1

epsilon, f1 = select_threshold(pxval, yval) #计算阈值和F1分数
epsilon, f1

输出:(8.990852779269492e-05, 0.8750000000000001)

最后,我们可以将阈值应用于数据集,并可视化结果。

# indexes of the values considered to be outliers
outliers = np.where(pp < epsilon) #获取小于阈值的pp索引号(X数据集)
#outliers = X[np.where(pp < epsilon), :] #获取小于阈值的异常点(X数据集)
outliers

#画出数据集X超过阈值的异常点
fig, ax = plt.subplots(figsize=(9,6))
ax.scatter(X[:,0], X[:,1])
ax.scatter(X[outliers[0],0], X[outliers[0],1], s=100, facecolors='none', edgecolors='r', marker='o')
?
#绘制等高线图
delta = 0.3 # 注意delta不能太小!!!否则会生成太多的数据,导致矩阵相乘会出现内存错误。
x = np.arange(0,30,delta)
y = np.arange(0,30,delta)
 # 这部分要转化为X形式的坐标矩阵,也就是一列是横坐标,一列是纵坐标,
 # 然后才能传入gaussian中求解得到每个点的概率值
xx, yy = np.meshgrid(x, y) #将x行重复,将y列重复
points = np.c_[xx.ravel(), yy.ravel()] # 按列合并,一列横坐标,一列纵坐标
z = Gaussian(points, mu, sigma)
z = z.reshape(xx.shape) # 
cont_levels = [10**h for h in range(-20,0,3)]
plt.contour(xx, yy, z, cont_levels) 
plt.title('Gaussian Contours',fontsize=16)
plt.show()

协同过滤?

推荐引擎使用基于项目和用户的相似性度量来检查用户的历史偏好,以便为用户可能感兴趣的新“事物”提供建议。在本练习中,我们将实现一种称为协作过滤的特定推荐系统算法,并将其应用于 电影评分的数据集。

我们首先加载并检查我们将要使用的数据。

data = loadmat('data/ex8_movies.mat')
data

Y是包含从1到5的等级的(数量的电影x数量的用户)数组.R是包含指示用户是否给电影评分的二进制值的“指示符”数组。 两者应该具有相同的维度。

Y = data['Y'] #用户对电影评分
R = data['R'] #用户是否评分
Y.shape, R.shape #((1682, 943), (1682, 943))

我们可以通过平均排序Y来评估电影的平均评级。

Y[1, np.where(R[1,:]==1)[0]].mean() #Out[215]:3.2061068702290076

我们还可以通过将矩阵渲染成图像来尝试“可视化”数据。 我们不能从这里收集太多,但它确实给我们了解用户和电影的相对密度。

fig, ax = plt.subplots(figsize=(12,12))
ax.imshow(Y)
ax.set_xlabel('Users')
ax.set_ylabel('Movies')
fig.tight_layout() #调整坐标轴和标签的位置,使其更清楚
plt.show()

接下来,我们将实施协同过滤的代价函数。 直觉上,“代价”是指一组电影评级预测偏离真实预测的程度。 代价方程在练习文本中给出。 它基于文本中称为X和Theta的两组参数矩阵。 这些“展开”到“参数”输入中,以便稍后可以使用SciPy的优化包。同时在代价和梯度计算中添加正则化。

def cost(params, Y, R, num_features, alambda):
# INPUT:参数params,数据与标签Y,R,特征个数num_features,正则化参数alambda
# OUTPUT:梯度grad,代价函数J
# TODO:计算带正则化的梯度和代价函数
 
 # STEP1:创建变量
 Y = np.matrix(Y) # (1682, 943)
 R = np.matrix(R) # (1682, 943)
 num_movies = Y.shape[0]
 num_users = Y.shape[1]
 
 # STEP2:重新设置矩阵的维度
 # your code here (appro ~ 2 lines)
 X = np.matrix(np.reshape(params[:num_movies * num_features], (num_movies, num_features)))
 Theta = np.matrix(np.reshape(params[num_movies * num_features:], (num_users, num_features)))

# STEP3:初始化参数
 J = 0
 X_grad = np.zeros(X.shape)
 Theta_grad = np.zeros(Theta.shape)

 # STEP4:计算代价函数
 error = np.multiply(X * Theta.T - Y, R)
 squared_error = np.power(error, 2)
 J = (1. / 2) * np.sum(squared_error)

 # STEP5:加入正则项
 J = J + alambda / 2 * np.power(X, 2).sum()
 J = J + alambda / 2 * np.power(Theta, 2).sum()

 # STEP6:计算包含正则项的梯度
 X_grad = error * Theta + alambda * X
 Theta_grad = error.T * X + alambda * Theta

 # STEP7:拉直梯度矩阵
 grad = np.concatenate((np.ravel(X_grad), np.ravel(Theta_grad)))
 return J, grad

J, grad = cost(params, Y_sub, R_sub, features, 1.5)
J, grad

Out[250]:

(31.344056244274217,
 array([ -0.95596339, 6.97535514, -0.10861109, 0.60308088,
 2.77421145, 0.25839822, 0.12985616, 4.0898522 ,
 -0.89247334, 0.29684395, 1.06300933, 0.66738144,
 0.60252677, 4.90185327, -0.19747928, -10.13985478,
 2.10136256, -6.76563628, -2.29347024, 0.48244098,
 -2.99791422, -0.64787484, -0.71820673, 1.27006666,
 1.09289758, -0.40784086, 0.49026541]))

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码