吴恩达机器学习python实现8 异常检测及推荐系统
·
异常检测
1、可视化数据
def visualize_dataset(X):
plt.scatter(X[..., 0], X[..., 1], marker="x", label="point")
2、估计参数
def estimate_parameters_for_gaussian_distribution(X):
mu = np.mean(X, axis=0)
sigma2 = np.var(X, axis=0)
return mu, sigma2
3、根据高斯模型,计算概率
def gaussian_distribution(X, mu, sigma2):
p = np.exp(-(X-mu)**2/(2*sigma2)) * 1/(np.sqrt(2*np.pi*sigma2))
return np.prod(p, axis=1)
4、画出高斯分布的等高线
def visualize_contours(mu, sigma2):
x, y = np.linspace(5, 25, 100), np.linspace(5, 25, 100)
xx, yy = np.meshgrid(x, y)
X = np.concatenate((xx.reshape(-1, 1), yy.reshape(-1, 1)), axis=1)
z = gaussian_distribution(X, mu, sigma2).reshape(xx.shape)
cont_levels = [10**h for h in range(-20, 0, 3)] # 当z为当前列表的值时才绘出等高线
plt.contour(xx, yy, z, cont_levels)
5、计算precision、recall
# yp是预测值,yt是真实值
def error_analysis(yp, yt):
tp, fp, fn, tn = 0, 0, 0, 0
for i in range(len(yp)):
if yp[i] == yt[i]:
if yp[i] == 1:
tp += 1
else:
tn += 1
else:
if yp[i] == 1:
fp += 1
else:
fn += 1
precision = tp / (tp+fp) if tp + fp else 0
recall = tp / (tp+fn) if tp+fn else 0
f1 = 2*precision*recall/(precision+recall) if precision+recall else 0
return f1
6、选择最好的阈值
# yval真实值 pval预测值
def select_threshold(yval, pval):
epsilons = np.linspace(min(pval), max(pval), 1000)
l = np.zeros((1, 2))
for e in epsilons:
ypre = (pval<e).astype(float)
f1 = error_analysis(ypre, yval)
l = np.concatenate((l, np.array([[e, f1]])), axis=0)
index = np.argmax(l[..., 1])
return l[index, 0], l[index, 1]
7、根据高斯模型检测出异常数据
def detection(X, e, mu, sigma2):
p = gaussian_distribution(X, mu, sigma2)
anomaly_points = np.array([X[i] for i in range(len(p)) if p[i]<e])
return anomaly_points
8、可视化异常数据
def circle_anomaly_points(X):
plt.scatter(X[..., 0], X[..., 1], s=80, facecolor="none", edgecolors="r", label="anomaly point")
9、低维数据测试
data = sio.loadmat(文件路径)
X = data["X"] # (307,2)
visualize_dataset(X)
mu, sigma2 = estimate_parameters_for_gaussian_distribution(X) # [14.11222578 14.99771051] [1.83263141 1.70974533]
p = gaussian_distribution(X, mu, sigma2) # (307,)
visualize_contours(mu, sigma2)
Xval = data["Xval"] # (307,2)
yval = data["yval"] # (307,1)
print(yval[:3])
e, f1 = select_threshold(yval.ravel(), gaussian_distribution(Xval, mu, sigma2))
print('best choice of epsilon is ', e, ',the F1 score is ', f1)
# best choice of epsilon is 8.999852631901394e-05 ,the F1 score is 0.8750000000000001
anomaly_points = detection(X, e, mu, sigma2)
circle_anomaly_points(anomaly_points)
plt.title('anomaly detection')
plt.legend()
plt.show()

10、高维数据测试
data2 = sio.loadmat(文件路径)
X = data2["X"] # (1000,11)
Xval = data2["Xval"] # (100,11)
yval = data2["yval"] # (100, 1)
mu, sigma2 = estimate_parameters_for_gaussian_distribution(X)
e, f1 = select_threshold(yval.ravel(), gaussian_distribution(Xval, mu, sigma2))
anomaly_points = detection(X, e, mu, sigma2)
print('\n\nfor this high dimensional dataset \nbest choice of epsilon is ', e, ',the F1 score is ', f1)
print('the number of anomaly points is', anomaly_points.shape[0])
# for this high dimensional dataset
# best choice of epsilon is 1.3786074982000235e-18 ,the F1 score is 0.6153846153846154
# the number of anomaly points is 117
推荐系统
1、导入所需的库
import scipy.io as sio
import numpy as np
import scipy.optimize as opt
from sklearn.metrics import mean_squared_error
2、参数维数变换
# 参数一维向量化
def serialize(X, theta):
return np.concatenate((X.flatten(), theta.flatten()), axis=0)
# 将一维参数向量还原
def deserializer(params, nm, nu, nf):
X = params[: nm*nf].reshape(nm, nf)
theta = params[nm*nf:].reshape(nu, nf)
return X, theta
3、协同过滤算法目标函数
def collaborative_filtering_cost(params, Y, R, nm, nu, nf, lamda=0.0):
X, theta = deserializer(params, nm, nu, nf)
part1 = np.sum(((X.dot(theta.T) - Y) ** 2)*R)/2
part2 = (lamda/2) * np.sum(theta**2)
part3 = (lamda/2) * np.sum(X**2)
return part1 +part2 + part3
4、协同过滤梯度下降
def collaborative_filtering_gradient(params, Y, R, nm, nu, nf, lamda=0.0):
X, theta = deserializer(params, nm, nu, nf)
g_X = ((X.dot(theta.T)-Y) * R).dot(theta) + lamda*X
g_theta = ((X.dot(theta.T)-Y) * R).T.dot(X) + lamda*theta
return serialize(g_X, g_theta)
5、检验预测
def check_gradient(params, Y, R, nm, nu, nf):
e = 0.0001
m = len(params)
g_params = np.zeros((m,))
for i in range(m):
temp = np.zeros((m,))
temp[i] = e
g_params = (collaborative_filtering_cost(params+temp, Y, R, nm, nu, nf)-
collaborative_filtering_gradient(params-temp, Y, R, nm, nu, nf))/(2 * e)
return g_params
6、代入数据
data1 = sio.loadmat(文件路径)
# Y是包含从1到5的等级的(数量的电影x数量的用户)数组.R是包含指示用户是否给电影评分的二进制值的“指示符”数组。 两者应该具有相同的维度。
Y = data1["Y"] # (1682,943)
R = data1["R"] # (1682,943)
data2 = sio.loadmat(r"E:\zl\机器学习\1\data\ex8\ex8_anomaly_detection_and_recommender_system_data_ex8_movieParams")
X = data2["X"] # (1682,10)
theta = data2["Theta"] # (943,10)
nu = data2["num_users"][0][0] # 943
nm = data2["num_movies"][0][0] # 1682
nf = data2["num_features"][0][0] # 10
print(collaborative_filtering_cost(serialize(X, theta), Y, R, nm, nu, nf)) # 27918.64012454421
print(collaborative_filtering_cost(serialize(X, theta), Y, R, nm, nu, nf, 1.5)) # 34821.703613072226
# 读入电影标签
with open(文件路径) as f:
movies = []
for line in f.readlines():
movies.append(line.split(' ', 1)[-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] = 5
Y = np.concatenate((Y, my_ratings), axis=1)
R = np.concatenate((R, my_ratings > 0), axis=1)
nu += 1
# params = serialize(np.random.random((nm, nf)), np.random.random((nu, nf)))
# res = opt.minimize(fun=collaborative_filtering_cost, x0=params, args=(Y, R, nm, nu, nf,10), method="TNC",
# jac=collaborative_filtering_gradient)
# print(res.shape)
trained_X, trained_theta = deserializer(sio.loadmat(文件路径)["params"].ravel(), nm, nu, nf)
predict = trained_X.dot(trained_theta.T)
my_predict = predict[..., -1]
# 从预测结果选择10个最优推荐
for i in range(10):
index = int(np.argmax(my_predict))
print("Predicting rating ", my_predict[index], " for movie ", movies[index])
my_predict[index] = -1
# Predicting
# rating
# 4.291401160077979
# for movie Titanic(1997)
#
# Predicting
# rating
# 4.119953862808096
# for movie Star Wars (1977)
#
# Predicting
# rating
# 3.9792200003762264
# for movie Raiders of the Lost Ark (1981)
#
# Predicting
# rating
# 3.9099976364851314
# for movie Good Will Hunting (1997)
#
# Predicting
# rating
# 3.885805506896392
# for movie Shawshank Redemption, The (1994)
#
# Predicting
# rating
# 3.8729551652292584
# for movie Return of the Jedi (1983)
#
# Predicting
# rating
# 3.8712945387591366
# for movie Braveheart(1995)
#
# Predicting
# rating
# 3.863004536777663
# for movie Empire Strikes Back, The (1980)
#
# Predicting
# rating
# 3.757933676945382
# for movie Terminator 2: Judgment
# Day(1991)
#
# Predicting
# rating
# 3.7576861972110667
# for movie As Good As It Gets (1997)
# 用均方误差来评价
Y = Y.flatten()
R = R.flatten()
predict = predict.flatten()
true_y = []
pre_y = []
for i in range(len(Y)):
if R[i] == 1:
true_y.append(Y[i])
pre_y.append(predict[i])
print("当前训练对岳原始数据集的均方误差", mean_squared_error(true_y, pre_y)) # 当前训练对岳原始数据集的均方误差 0.6400023155268085
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)