如何使用 sklearn 的矩阵分解来预测新用户的推荐分数

如何解决如何使用 sklearn 的矩阵分解来预测新用户的推荐分数

我正在尝试使用 sklearn.decomposition.NMF 到矩阵 R,其中包含有关用户如何评价项目的数据,以预测用户对他们尚未看到的项目的评分。

矩阵的行是用户,列是项目,值是分数,0 分表示用户还没有给这个项目打分。

现在使用下面的代码,我只能得到两个矩阵,当它们相乘时,返回原始矩阵。

import numpy

R = numpy.array([
     [5,3,1],[4,[1,1,5],4],[0,5,])

from sklearn.decomposition import NMF
model = NMF(n_components=4)

A = model.fit_transform(R)
B = model.components_

n = numpy.dot(A,B)
print(n)

问题是,模型没有预测新值来代替 0 的值,这将是预测的分数,而是按原样重新创建矩阵。

如何让模型预测用户分数来代替原始矩阵的零?

解决方法

这就是应该发生的事情。

但是,在大多数情况下,您的组件数量不会与产品和/或客户的数量如此相似。

例如考虑 2 个组件

model = NMF(n_components=2)
A = model.fit_transform(R)
B = model.components_
R_estimated = np.dot(A,B)
print(np.sum(R-R_estimated))
-1.678873127048393
R_estimated
array([[5.2558264,1.99313836,0.,1.45512772],[3.50429478,1.32891458,0.9701988 ],[1.31294288,0.94415991,1.94956896,3.94609389],[0.98129195,0.72179987,1.52759811,3.0788454 ],[0.,0.65008935,2.84003662,5.21894555]])

在这种情况下,您可以看到许多以前的零现在是您可以使用的其他数字。这里有一些上下文https://en.wikipedia.org/wiki/Matrix_factorization_(recommender_systems)

如何选择 n_components?

我认为上面的问题已经回答了,但如果完整的程序可能如下所示。

为此,我们需要知道 R 中的真实值,并且我们希望专注于预测。

在许多情况下,R 中的 0 是那些新案例/场景。 通常用产品或客户的平均值更新 R,然后计算分解以选择理想的 n_components。对于选择它们可能是一个或多个标准来计算测试样本中的优势

  1. 创建 R_with_Averages
  2. 型号选择: 2.1) 拆分 R_with_Averages 测试和训练 2.2)使用度量(其中您只考虑 R 中的真实评估)在不同的 n_components(从 1 和任意数字)之间进行比较 2.3) 选择最佳模型 --> 最佳 n_components
  3. 使用最佳模型进行预测。

也许很高兴看到:

,

sklearnNMF的实现好像不支持缺失值(Nans,这里0个值基本代表新用户对应的未知评分),参考这个{{ 3}}。但是,我们可以使用 supriseNMF 实现,如以下代码所示:

import numpy as np
import pandas as pd
from surprise import NMF,Dataset,Reader

R = np.array([
     [5,3,1],[4,[1,1,5],4],[0,5,],dtype=np.float)

R[R==0] = np.nan
print(R)

# [[ 5.  3. nan  1.]
#  [ 4. nan nan  1.]
#  [ 1.  1. nan  5.]
#  [ 1. nan nan  4.]
#  [nan  1.  5.  4.]]

df = pd.DataFrame(data=R,index=range(R.shape[0]),columns=range(R.shape[1]))
df = pd.melt(df.reset_index(),id_vars='index',var_name='items',value_name='ratings').dropna(axis=0)
reader = Reader(rating_scale=(0,5))
data = Dataset.load_from_df(df[['index','items','ratings']],reader)

k = 2
algo = NMF(n_factors=k) 
trainset = data.build_full_trainset() 
algo.fit(trainset)
predictions = algo.test(trainset.build_testset()) # predict the known ratings
R_hat = np.zeros_like(R)
for uid,iid,true_r,est,_ in predictions:
    R_hat[uid,iid] = est
predictions = algo.test(trainset.build_anti_testset()) # predict the unknown ratings
for uid,iid] = est
print(R_hat)

# [[4.40762528 2.62138084 3.48176319 0.91649316]
# [3.52973408 2.10913555 2.95701406 0.89922637]
# [0.94977826 0.81254138 4.98449755 4.34497549]
# [0.89442186 0.73041578 4.09958967 3.50951819]
# [1.33811051 0.99007556 4.37795636 3.53113236]]

NMF 实现是按照 [NMF:2014] 论文中描述的 issue 和如下所示:

here

注意,这里只使用已知评分进行优化,导致已知评分的预测值接近真实评分(但未知评分的预测值一般不接近{{1 }},正如预期的那样)。

同样,像往常一样,我们可以使用交叉验证找到因子数 0

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?