nmf算法 python_NMF算法简介及python实现

[ pca算法用于原始数据维数较高时对数据进行降维 关于pca算法的学习,有一篇分析特别详细的论文http://www.cs.otago.ac.nz/cosc453/student_tutorials/principal_componen

基本原理

NMF,非负矩阵分解,它的目标很明确,就是将大矩阵分解成两个小矩阵,使得这两个小矩阵相乘后能够还原到大矩阵。而非负表示分解的矩阵都不包含负值。 从应用的角度来说,矩阵分解能够用于发现两种实体间的潜在特征,一个最常见的应用就是协同过滤中的预测打分值,而从协同过滤的这个角度来说,非负也很容易理解:打分都是正的,不会出现负值。

在例如Netflix或MovieLens这样的推荐系统中,有用户和电影两个集合。给出每个用户对部分电影的打分,我们希望预测该用户对其他没看过电影的打分值,这样可以根据打分值为其做出推荐。用户和电影的关系,可以用一个矩阵来表示,每一行表示用户,每一列表示电影,每个元素的值表示用户对已经看过的电影的打分,矩阵看起来如下:

D1

D2

D3

D4

U1 5 3 - 1

U2 4 - - 1

U3 1 1 - 5

U4 1 - - 4

U5 - 1 5 4

而使用矩阵分解来预测评分的思想来源于,我们可以通过矩阵分解来发现一些用户打分的潜在特征。比如两个人都喜欢某一演员,那他们就倾向于给TA演的电影打高分;或者两个人都喜欢动作片。假如我们能够发现这些特征,我们就能够预测特定用户对特定电影的打分。

为了发现不同的特征,我们假设特征的数量少于用户和电影的数量(要是每个用户都有一个独立特征,那代价也太大啦)。

数学基础

首先,我们定义U为用户的集合,D为电影的集合,R = U * D,为评分的集合。假设我们需要寻找K个特征,则我们的目标是,找到两个矩阵P和Q,使得它们相乘近似等于R。即:

mf-o010.png

这样P的每一行表示用户,每一列表示一个特征,它们的值表示用户与某一特征的相关性,值越大,表明特征越明显。同理,Q的每一行表示电影,每一列表示电影与特征的关联。最后为了预测用户ui对特定电影dj的评分,我们可以直接计算ui和dj对应的特征向量的点积,即:

mf-o017.png

现在我们就来计算P和Q。最简单的方法就是梯度下降,该方法先初始化P和Q为特定的值,计算它们的乘积与真实矩阵的误差,然后通过迭代,逐渐减小误差直至收敛。

由于误差可大可小,这里使用平方根误差(squared error)来计算,计算公式如下:

mf-o021.png

即循环地计算每一条目的误差,最后相加。

为了最小化误差,我们需要知道怎么改变Pik和Qkj的值(在梯度下降中表现为下降的方向)。我们对这个公式求偏微分,即得:

mf-o024.png

mf-o025.png

计算出梯度之后,我们逐步更新Pik和Qkj:

mf-o028.png[KNN算法的Python实现]

mf-o029.png

上面公式中,

mf-o030.png为梯度下降常数,通常取一个较小的值(防止无法收敛),如0.0002。

有人可能会问一个问题:假如我们计算出P和Q,使得P*Q近似等于R,那么那些未评分的不全是0了么?首先,我们并不要求P*Q精确等于R;其次,我们输入的数据是所有已评分的数据(或它的子集),即训练集,而并不包含未评分的数据。因此,它能够对未评分的做出不等于0的预测。

通过上面的更新规则,我们就可以逐步减小误差,直至收敛:

mf-o045.png

规范化

上面的算法只是最简单的一个实现,实际使用中可能复杂得多。一个最常见的修改就是引入规范化,以防止过度拟合。这通过加入另外一个参数

mf-o046.png来修改误差公式:

mf-o047.png

参数

mf-o046.png用来控制用户特征向量与条目特征向量的比例,以避免出现特征向量中出现特别大的值。实际应用中,通常设置为0~0.02之间的值。因此更新公式变成:

mf-o053.png

mf-o054.png

一个简单的python实现如下(需要安装numpy)

import numpy

def matrix_factorisation(R, P, Q, K, steps=5000, alpha=0.0002, beta=0.02):

Q = Q.T

for step in range(steps):

for i in range(len(R)):

for j in range(len(R[i])):

if R[i][j] > 0:

eij = R[i][j] - numpy.dot(P[i,:],Q[:,j])

for k in range(K):

P[i][k] = P[i][k] + alpha * (2 * eij * Q[k][j] - beta * P[i][k])

Q[k][j] = Q[k][j] + alpha * (2 * eij * P[i][k] - beta * Q[k][j])

eR = numpy.dot(P,Q)

e = 0

for i in range(len(R)):

for j in range(len(R[i])):

if R[i][j] > 0:

e = e + pow(R[i][j] - numpy.dot(P[i,:],Q[:,j]), 2)

for k in range(K):

e = e + (beta/2) * (pow(P[i][k],2) + pow(Q[k][j],2))

if e < 0.001:

break

return P, Q.T

使用示例如下:

R = [

[5,3,0,1],

[4,0,0,1],

[1,1,0,5],

[1,0,0,4],

[0,1,5,4],

]

R = numpy.array(R)

N = len(R)

M = len(R[0])

K = 2

P = numpy.random.rand(N,K)

Q = numpy.random.rand(M,K)

nP, nQ = matrix_factorisation(R, P, Q, K)

nR = numpy.dot(nP, nQ.T)

print(nR)

最后P*Q还原出的矩阵如下:

D1

D2

D3

D4

U1 4.97 2.98 2.18 0.98

U2 3.97 2.40 1.97 0.99

U3 1.02 0.93 5.32 4.93

U4 1.00 0.85 4.59 3.93

U5 1.36 1.07 4.89 4.12

可以看到,还原后的矩阵跟原矩阵很接近,并且对原来空缺的值作出了预测。在这个例子中,我们可以看到U1和U2口味比较接近,他们都喜欢D1和D2。而其他的用户则喜欢D3,D4和D5。[Apriori算法是数据挖掘中频发模式挖掘的鼻祖,从60年代就开始流行,其算法思想也十分简单朴素,首先挖掘出长度为1的频繁模式,然后k=2将这些频繁模式合并组成长度为k的频

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/434136.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux 修改消息队列大小

环境&#xff1a;red hat5 linux消息队列的配置文件为&#xff1a; /etc/sysctl.conf ,里面&#xff1a; msgmax:  一条最大消息的字节数 msgmnb&#xff1a; 一个消息队列总共最大字节数 而我的系统这2个值都默认是65536&#xff0c;假如发一条65536长度的消息&#xff0c;…

龙芯购买MIPS指令集的授权

以前指责龙芯购买MIPS授权的那篇文章让人啼笑皆非&#xff0c;只能用无知来概况我在IT从业多年&#xff0c;非常赞同龙芯购买MIPS指令集的授权&#xff01;分几个方面来阐述&#xff1a;&#xff08;1&#xff09;什么是指令集&#xff1f;指令集好像英文的26个字母&#xff0c…

python网络爬虫_Python爬虫实战之网络小说

今天和大家分享的是python爬虫实战&#xff0c;由于本人最近迷上了看网络小说&#xff0c;学生党又穷&#xff0c;只能看看网络dao版小说&#xff0c;现在这类dao版小说网站可以说非常的多&#xff0c;但是所有的网站进去都可以看见一大把的广告信息&#xff0c;非常影响我们的…

java反射机制详解_JAVA反射机制详解_JSP/Java编程_互联网开发技术网_传播最新的编程技术_php361.com...

今天&#xff0c;下午在和朋友聊天的时候&#xff0c;聊起了反射这个话题。我们就从下面这个段简单的代码开始吧。这个代码输出什么&#xff0c;想必大部分的读者跟我一样&#xff0c;会很快地知道答案&#xff1a;0 1 2 3 4 5 6 7 8 9。事实也是如此&#xff1a;朋友这个时候就…

实时修改和读取webconfig

ConfigurationManager.AppSettings.Set("MailUser","3" );ConfigurationManager.AppSettings.Set("MailPassword","2");ConfigurationManager.AppSettings.Set("MailEnable","1" ); 只能临时保存实时修改webconfi…

activity 点击后传递数据给fragment_Fragment 新特性 : Fragment Result API 使用以及源码分析

原标题: Android Fragments: Fragment Result原文地址: https://proandroiddev.com/android-fragments-fragment-result......原文作者: Husayn Hakeem今年 Google 推出了 Fragment Result API 和 Activity Results API&#xff0c;用来取代之前的 Activity 和 Fragment 之间通…

linux动态库与静态库混合连接

在应用程序需要连接外部库的情况下&#xff0c;linux默认对库的连接是使用动态库&#xff0c;在找不到动态库的情况下再选择静态库。使用方式为&#xff1a; gcc test.cpp -L. -ltestlib 如果当前目录有两个库libtestlib.so libtestlib.a 则肯定是连接libtestlib.so。如果要指定…

java运算函数_Java中的数学计算函数

Math类&#xff1a;java.lang.Math类中包含基本的数字操作&#xff0c;如指数、对数、平方根和三角函数。java.math是一个包&#xff0c;提供用于执行任意精度整数(BigInteger)算法和任意精度小数(BigDecimal)算法的类。java.lang.Math类中包含E和PI两个静态常量&#xff0c;以…

从无头单链表中删除节点

#include<iostream> using namespace std;struct Node{int data;Node* next; };void deleteNode(Node* p) {p->datap->next->data; //将p后的节点的数值赋给p的data域p->nextp->next->next; //将p后的节点删除&#xff0c;即完成了删除节点p的效果…

android卡片层叠效果_ReactNative之Android绝对布局position:#x27;absolute#x27;问题

工作中会遇到各种各样的问题&#xff0c;ReactNative开发也是填坑不止。比如最近在开发需求中&#xff0c;就遇到一个问题。在一个卡片类型的右上角添加一个删除按钮。使用了绝对布局position:absolute属性&#xff0c;在Android上却无法正常显示&#xff0c;很是烦恼。有一个相…

java监听机制_详解java的事件监听机制和观察者设计模式

首先说说监听器&#xff1a;监听器就是一个实现特定接口的普通java程序&#xff0c;这个程序专门用于监听另一个java对象的方法调用或属性改变&#xff0c;当被监听对象发生上述事件后&#xff0c;监听器某个方法将立即被执 行。java的事件监听机制可概括为3点&#xff1a;1,ja…

敏捷开发的6个实战经验

在大型企业中经常是各种软件开发模式混用&#xff0c;一些采用敏捷开发&#xff0c;一些则是采用传统的瀑布式或RUP&#xff08;统一软件开发过程&#xff09;。敏捷开发&#xff0c;相对传统软件开发模式&#xff0c;它主要是针对快速变化的需求&#xff0c;不断优化管理流程&…

C++ Editbox换行问题

在EditBox中"/r/n" 换行有时是不行的。 使用&#xff1a;strFilePath.Format("File Name: %s%c%c", strFileName,0x0D,0x0A); //strFilePath.Format("File Name: %s/r/n", strFileName);转载于:https://www.cnblogs.com/mygod/archive/2012/11/1…

java 正则匹配括号是否成对_十分钟学会正则表达式

正则表达式用处挺广的&#xff0c;主要用于处理字符串。正则引擎想要在计算机语言中使用正则表达式&#xff0c;那么这门计算机语言必须要利用正则引擎去实现相应的正则库。主要的正则引擎分为以下两类&#xff1a;DFA 确定性的状态机。不使用”回溯”&#xff0c;效率高&#…

shell 脚本比较字符串相等_比较带空格的字符串相等的Shell脚本 如何比较两个.....

****************************比较带空格的字符串相等的Shell脚本***************************如果要比较的字符串中间有空格&#xff0c;可以用下面的程序(摘自《Unix Shells by Example, 3rd Edition》)name"Joe Blow"if [[ $name "Joe Blow" ]]thenpri…

Linux 下编译并安装配置 Qt

本文介绍的是Linux 下编译并安装配置 Qt&#xff0c;最近准备做 Nokia 的 Symbian,Maemo 下触摸屏开发。考虑到程序的跨平台可移植性&#xff0c;最终选择使用 Qt 开发。相对来说&#xff0c;国内关于 Qt 相关文档并不算很多。作者将 Linux 下编译并安装配置 Qt 全过程总结了…

itext jsp页面打印

最近项目中需要一个打印功能&#xff0c;需求很简单&#xff0c;只要打印出单据就可以了&#xff0c;画出一个表格&#xff0c;一些信息需要从数据库中提取 找到了免费的itext&#xff0c;可以实现我的简单的功能了 代码&#xff1a;&#xff08;打印方法&#xff09; public S…

android token机制_你真的了解16.6ms刷新机制吗?

阅读本文前&#xff0c;请您先点击上面的蓝色字体“Android扫地僧”&#xff0c;“关注”后再点击置顶公众号&#xff0c;优质干货&#xff0c;重磅资源第一时间送达。散人丶https://juejin.im/post/5ce686a46fb9a07ec754f470前言之前在整理知识的时候&#xff0c;看到android屏…

dfa2.java 原理_DFA编程练习2

题目: 请设计DFA, 使其接受全部含有奇数个1的串, 假定 ∑ {0, 1}.解:DFA可能出现两个个状态:qeven: 读入了偶数个1的串.qodd: 读入了奇数个1的串, 该状态也是终结状态(accept state).它们的状态转移图如下:编写程序, 运行效果如下:测试用例说明:0000不被上图的DFA接受1111不被…

Asp.net的HTTP请求处理过程

说明&#xff1a; &#xff08;1&#xff09;、客户端浏览器向服务器发出一个Http请求&#xff0c;此请求会被inetinfo.exe进程截获&#xff0c;然后转交给 aspnet_isapi.dll进程&#xff0c;接着它又通过Http Pipeline的管道&#xff0c;传送给aspnet_wp.exe这个进程&#xff…