美文网首页互联网科技每天写1000字程序员
机器学习笔记039 | 异常检测与推荐系统

机器学习笔记039 | 异常检测与推荐系统

作者: 止一量化养家 | 来源:发表于2017-10-24 07:42 被阅读109次

1 异常检测

我们有一些服务器的延迟和吞吐量数据:

我们想要监控服务器的表现,并自动发现异常的情况。

通过验证集有标记的数据,选择一个最佳的临界点,并识别出来哪些是异常的:

下面是主要部分的代码:

均值和方差:

# 计算均值和方差
def estimateGaussian(X):
    m,n = X.shape
    # 均值
    mu = mean(X,axis = 0)
    # 方差
    sigma2 = 1.0*sum((X - mu)**2,axis=0)/m
    
    return mu,sigma2

多元高斯分布:

# 多元高斯分布
def multivariateGaussian(X, mu, sigma2):
    # 训练集数量和特征数量
    m,n = X.shape
    # 协方差矩阵(特例:对角矩阵情况)
    C = np.diag(sigma2)
    #C = 1.0/m*X.T.dot(X)
    C_det = np.linalg.det(C)
    # 协方差矩阵的逆矩阵
    C_inv = np.linalg.inv(C)
    
    # 结果
    temp = sum((X-mu).dot(C_inv)*(X-mu),axis = 1)
    p = 1.0/((2.0*np.pi)**(n/2.0)*C_det**(1.0/2))*np.e**(-1.0/2*temp)
    
    return p

选择最优错误临界点 ε:

# 选择最优错误临界点 ε
def selectThreshold(yval, pval):
    bestEpsilon = 0
    bestF1 = 0
    F1 = 0
    
    # 根据最大值最小值划分1000份
    stepsize = (max(pval) - min(pval)) / 1000
    rangelist = np.arange(min(pval),max(pval)+stepsize,stepsize)
    
    for epsilon in rangelist:
        predictions = pval<epsilon
        tp = sum((predictions == 1) & (yval.T[0] == 1)) # 真阳性
        fp = sum((predictions == 1) & (yval.T[0] == 0)) # 假阳性
        fn = sum((predictions == 0) & (yval.T[0] == 1)) # 假阴性
        
        if epsilon == min(pval):
            continue
        
        prec = 1.0*tp / (tp+fp) # 查准率
        rec = 1.0*tp / (tp+fn) # 召回率

        F1 = 2.0*prec*rec/(prec+rec) # F1Score

        # 如果计算得到的F1score更好,则记录对应的 ε
        if F1 > bestF1:
            bestF1 = F1
            bestEpsilon = epsilon
        
    return bestEpsilon,bestF1

训练并发现异常:

# 均值与方差
mu,sigma2 = estimateGaussian(X)
# 多元高斯分布
p = multivariateGaussian(X, mu, sigma2)

# 验证集预测结果
pval = multivariateGaussian(Xval, mu, sigma2)
# 通过验证集选择最优临界点
epsilon,F1 = selectThreshold(yval, pval)

2 推荐系统

我们已经有了一些用户对电影的评分,评分是从 1 到 5 。

我们想要给用户推荐电影,一种可行的方式是通过系统过滤算法来训练数据,得到电影的特征和用户偏好参数,并在这个基础上给用户推荐。

主要实现的代码如下:

代价函数:

# 代价函数
def costFunc(params, Y, R, num_users, num_movies, num_features, mylambda = 0):
    # 参数展开
    X = params[:num_movies*num_features].reshape(num_movies, num_features)
    Theta = params[num_movies*num_features:].reshape(num_users, num_features)
    # 代价函数计算
    J = sum((X.dot(Theta.T)-Y)**2*R)/2 + 1.0*mylambda/2*(sum(X**2)+sum(Theta**2))
    return J

梯度:

# 梯度
def gradient(params, Y, R, num_users, num_movies, num_features, mylambda = 0):
    # 参数展开
    X = params[:num_movies*num_features].reshape(num_movies, num_features)
    Theta = params[num_movies*num_features:].reshape(num_users, num_features)
    
    # 梯度计算
    X_grad = ((X.dot(Theta.T)-Y)*R).dot(Theta) + mylambda*X
    Theta_grad = ((X.dot(Theta.T)-Y)*R).T.dot(X) + mylambda*Theta
    
    # 结果扁平化
    grad = np.append(X_grad.flatten(), Theta_grad.flatten())
    
    return grad

评分结果均值化:

# 评分结果均值化
def normalizeRatings(Y, R):
    m,n = Y.shape
    Ymean = np.zeros(m).reshape(m,1)
    Ynorm = np.zeros(Y.shape)
    for i in range(m):
        idx = find(R[0, :] == 1)
        Ymean[i] = mean(Y[i, idx])
        Ynorm[i, idx] = Y[i, idx] - Ymean[i];
    
    return Ynorm, Ymean

推荐系统训练:

print('协同过滤训练...')

print('读取电影数据...')
body=read_file("Machine Learning/ex8_movies.mat")
data=sio.loadmat(StringIO(body))

# 评分结果矩阵
Y = data['Y']
# 是否评分矩阵
R = data['R']

# 加入个人评分
Y = np.c_[my_ratings,Y]
R = np.c_[my_ratings <> 0,R]

# 均值化
Ynorm, Ymean = normalizeRatings(Y, R)

num_users = Y.shape[1] # 用户数
num_movies = Y.shape[0] # 电影数
num_features = 10 # 特证数

# 参数随机初始化
X = np.random.randn(num_movies, num_features)
Theta = np.random.randn(num_users, num_features)
# 参数扁平化并且合并
initial_parameters = np.append(X.flatten(),Theta.flatten())

print('训练开始……(需要一点时间)')
opts = {'maxiter': 500}
mylambda = 10
result = optimize.minimize(costFunc, initial_parameters, 
                           args=(Y, R, num_users, num_movies, num_features, mylambda), 
                           method='CG', jac=gradient, tol=None, callback=None, options=opts)
params = result.x
print("代价函数计算结果:\n%s"%result.fun)
print("参数计算结果:\n%s"%result.x)

# 参数展开拆分
X = params[:num_movies*num_features].reshape(num_movies, num_features)
Theta = params[num_movies*num_features:].reshape(num_users, num_features)

print('推荐系统训完成。')

推荐:

# 预测电影评分
p = X.dot(Theta.T)
# 获得个人评分
my_predictions = p[:,0] + Ymean.T[0]
# 读取电影数据
movieList = loadMovieList()
# 个人评分预测结果降序排序,得到列表索引
ix = np.argsort(-my_predictions) #按降序排列

print("前十的推荐……")
for i in range(10):
    j = ix[i]
    print('预测评分:%s   ,电影:  %s'% (my_predictions[j],movieList[j]))

print('\n原始评分结果:')
for i in range(len(my_ratings)):
    if my_ratings[i] > 0 :
        print('评分:%s  ,电影: %s'%(my_ratings[i][0],movieList[i]))

文章转载自公众号:止一之路

相关文章

网友评论

    本文标题:机器学习笔记039 | 异常检测与推荐系统

    本文链接:https://www.haomeiwen.com/subject/acqsuxtx.html