基于NMF生成推荐时,如何为新用户重建数据?
解决NMF新用户数据重建与sklearn inverse_transform的差异问题
嘿,我之前也踩过这个坑,咱们来一步步拆解问题所在,以及怎么得到和sklearn一致的结果:
核心差异:你的公式 vs sklearn的逻辑
你用的公式 data.dot(H.T.dot(np.linalg.pinv(H.dot(H.T))).dot(H)) 本质是将新用户数据正交投影到H的列空间,这是无约束的线性代数解法,但sklearn的NMF inverse_transform 完全是另一个逻辑:
- sklearn的NMF模型基于
X ≈ W @ H,其中W(用户潜在特征)和H(物品潜在成分)都满足非负约束 inverse_transform的步骤是:先对新数据求解非负的W_new(即argmin ||X_new - W_new@H||²,同时W_new ≥ 0),再通过W_new @ H生成重建数据
你的公式没有考虑非负约束,也没有遵循NMF的非负最小二乘目标,所以结果自然和sklearn不一致。
正确的新用户重建步骤(含缺失数据)
针对带缺失项的新用户数据,我们需要手动模拟sklearn的非负约束求解逻辑,步骤如下:
1. 准备训练好的模型和新用户数据
假设你已经用sklearn训练好了NMF模型:
from sklearn.decomposition import NMF import numpy as np from scipy.optimize import nnls # 示例训练(假设你已经完成这一步) model = NMF(n_components=5, random_state=42) W_train = model.fit_transform(X_train) # X_train是训练数据 H = model.components_ # 物品潜在成分矩阵,形状(n_components, n_features) # 带缺失的新用户数据(用np.nan表示缺失) x_new = np.array([[2, np.nan, 0, np.nan, 5]]) # 示例:1个用户,5个物品
2. 提取已知特征,求解非负的W_new
因为新用户数据有缺失,我们只利用已知的特征来估计W_new:
# 标记非缺失的特征索引 mask = ~np.isnan(x_new) # 提取已知的特征值和对应的H列 x_known = x_new[mask].reshape(1, -1) H_known = H[:, mask] # 用非负最小二乘求解W_new # nnls要求目标是列向量,所以调整形状 w_new, _ = nnls(H_known.T, x_known.T.flatten()) w_new = w_new.reshape(1, -1) # 转成(1, n_components)的用户特征矩阵
3. 生成重建数据
用求解得到的非负W_new和H相乘,得到最终的重建结果:
x_recon = w_new @ H print("重建结果:", x_recon)
如果新用户数据没有缺失,直接用 model.transform(x_new) 得到W_new,再调用 model.inverse_transform(W_new) 也会得到相同的结果。
为什么你的公式会出问题?
- 无约束vs非负约束:你的公式是无约束的线性投影,可能产生负值,而NMF的重建结果必须是非负的(符合原始数据的非负假设,比如评分、点击量等)
- 目标函数不同:NMF的核心是最小化带非负约束的重构误差,而正交投影只是最小化无约束的欧氏距离,两者的优化目标完全不同
内容的提问来源于stack exchange,提问作者Vivek Sethia
相关产品推荐
相关产品推荐

