博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
推荐算法——非负矩阵分解(NMF)
阅读量:7208 次
发布时间:2019-06-29

本文共 3172 字,大约阅读时间需要 10 分钟。

一、矩阵分解回想

在博文中,提到了将用户-商品矩阵进行分解。从而实现对未打分项进行打分。

矩阵分解是指将一个矩阵分解成两个或者多个矩阵的乘积。对于上述的用户-商品矩阵(评分矩阵),记为Vm×n。能够将其分解成两个或者多个矩阵的乘积,如果分解成两个矩阵Wm×kHk×n。我们要使得矩阵Wm×kHk×n的乘积能够还原原始的矩阵Vm×n

Vm×nWm×k×Hk×n=V^m×n

当中,矩阵Wm×k表示的是m个用户与k个主题之间的关系,而矩阵Hk×n表示的是k个主题与n个商品之间的关系。

通常在用户对商品进行打分的过程中。打分是非负的,这就要求:

Wm×k0

Hk×n0

这便是非负矩阵分解(Non-negtive Matrix Factorization, NMF)的来源。

二、非负矩阵分解

2.1、非负矩阵分解的形式化定义

上面简介了非负矩阵分解的基本含义。简单来讲,非负矩阵分解是在矩阵分解的基础上对分解完毕的矩阵加上非负的限制条件。即对于用户-商品矩阵Vm×n,找到两个矩阵Wm×kHk×n,使得:

Vm×nWm×k×Hk×n=V^m×n

同一时候要求:

Wm×k0

Hk×n0

2.2、损失函数

为了能够定量的比較矩阵Vm×n和矩阵V^m×n的近似程度。在參考文献1中作者提出了两种损失函数的定义方式:

  • 平方距离

AB2=i,j(Ai,jBi,j)2
  • KL散度

D(AB)=i,j(Ai,jlogAi,jBi,jAi,j+Bi,j)

在KL散度的定义中,D(AB)0。当且仅当A=B时取得等号。

当定义好损失函数后,须要求解的问题就变成了例如以下的形式,相应于不同的损失函数:

求解例如以下的最小化问题:

  • minimizeVWH2s.t.W0,H0
  • minimizeD(VWH)s.t.W0,H0

2.3、优化问题的求解

在參考文献1中,作者提出了乘法更新规则(multiplicative update rules),详细的操作例如以下:

对于平方距离的损失函数:

Wi,k=Wi,k(VHT)i,k(WHHT)i,k

Hk,j=Hk,j(WTV)k,j(WTWH)k,j

对于KL散度的损失函数:

Wi,k=Wi,kuHk,uVi,u/(WH)i,uvHk,v

Hk,j=Hk,juWu,kVu,j/(WH)u,j)vWv,k

上述的乘法规则主要是为了在计算的过程中保证非负,而基于梯度下降的方法中,加减运算无法保证非负。事实上上述的乘法更新规则与基于梯度下降的算法是等价的。以下以平方距离为损失函数说明上述过程的等价性:

平方损失函数能够写成:

l=i=1mj=1n[Vi,j(k=1rWi,kHk,j)]2

使用损失函数对Hk,j求偏导数:

lHk,j=i=1mj=1n[2(Vi,j(k=1rWi,kHk,j))(Wi,k)]=2[(WTV)k,j(WTWH)k,j]

则依照梯度下降法的思路:

Hk,j=Hk,jηk,jlHk,j

即为:

Hk,j=Hk,j+ηk,j[(WTV)k,j(WTWH)k,j]

ηk,j=Hk,j(WTWH)k,j,即能够得到上述的乘法更新规则的形式。

2.4、非负矩阵分解的实现

对于例如以下的矩阵:

这里写图片描写叙述

通过非负矩阵分解。得到例如以下的两个矩阵:

这里写图片描写叙述

这里写图片描写叙述

对原始矩阵的还原为:

这里写图片描写叙述

实现的代码

#!/bin/pythonfrom numpy import * def load_data(file_path):    f = open(file_path)    V = []    for line in f.readlines():        lines = line.strip().split("\t")        data = []        for x in lines:            data.append(float(x))        V.append(data)    return mat(V)def train(V, r, k, e):    m, n = shape(V)    W = mat(random.random((m, r)))    H = mat(random.random((r, n)))    for x in xrange(k):        #error         V_pre = W * H        E = V - V_pre        #print E        err = 0.0        for i in xrange(m):            for j in xrange(n):                err += E[i,j] * E[i,j]        print err        if err < e:            break        a = W.T * V        b = W.T * W * H        #c = V * H.T        #d = W * H * H.T        for i_1 in xrange(r):            for j_1 in xrange(n):                if b[i_1,j_1] != 0:                    H[i_1,j_1] = H[i_1,j_1] * a[i_1,j_1] / b[i_1,j_1]        c = V * H.T        d = W * H * H.T        for i_2 in xrange(m):            for j_2 in xrange(r):                if d[i_2, j_2] != 0:                    W[i_2,j_2] = W[i_2,j_2] * c[i_2,j_2] / d[i_2, j_2]    return W,H if __name__ == "__main__":    #file_path = "./data_nmf"    file_path = "./data1"    V = load_data(file_path)    W, H = train(V, 2, 100, 1e-5 )    print V    print W    print H    print W * H

收敛曲线例如以下图所看到的:

这里写图片描写叙述

'''Date:20160411@author: zhaozhiyong'''from pylab import *from numpy import *data = []f = open("result_nmf")for line in f.readlines():    lines = line.strip()    data.append(lines)n = len(data)x = range(n)plot(x, data, color='r',linewidth=3)plt.title('Convergence curve')plt.xlabel('generation')plt.ylabel('loss')show()

參考文献

  • Algorithm for Non-negative Matrix Factorization

转载于:https://www.cnblogs.com/gavanwanggw/p/7337227.html

你可能感兴趣的文章
FPGA机器学习之学习的方向
查看>>
WebBrowser控件使用相关
查看>>
【Android】1.1 开发环境安装和配置
查看>>
站点公司亚马逊砸了10亿也没能做成智能手机,技术是须要沉淀和积累的
查看>>
[数据库]SQL Server 用户NT AUTHORITY\IUSR 登录失败
查看>>
轻松学会多线程(四)——synchronized同步keyword知多少
查看>>
Apache Kylin 部署之不完全指南
查看>>
php中将SimpleXMLElement Object数组转化为普通数组
查看>>
docker学习(7) docker-compose使用示例
查看>>
Android 推断当前Activity是不是最后一个Activity 以及 应用或Activity是否存在
查看>>
【Android】6.3 ProgressDialog
查看>>
设计模式六大原则——迪米特法则(LoD)
查看>>
HtmlAgilityPack 之 HtmlNode类
查看>>
[转]Java Web基础——Action+Service +Dao三层的功能划分
查看>>
ngx.location.capture 只支持相对路径,不能用绝对路径
查看>>
自己在OC考试中的试题
查看>>
向 Git 服务器添加 SSH 公钥
查看>>
Lua学习笔记5:类及继承的实现
查看>>
Vagrant工具
查看>>
如何使用 Android Studio 的 git hub 功能
查看>>