【问题标题】:SKLearn NMF Vs Custom NMFSKLearn NMF 与自定义 NMF
【发布时间】:2018-08-26 12:53:24
【问题描述】:

我正在尝试使用非负矩阵分解来构建推荐系统。使用scikit-learn NMF作为模型,我拟合了我的数据,导致了一定的损失(即重建错误)。然后我使用inverse_transform 方法为新数据生成推荐。

现在我使用我在 TensorFlow 中构建的另一个模型来做同样的事情。训练后的重建误差与之前使用 sklearn 的方法获得的误差接近。 但是,潜在因素和最终建议都不相似。

我知道的两种方法之间的一个区别是: 在 sklearn 中,我使用的是坐标下降求解器,而在 TensorFlow 中,我使用的是基于梯度下降的 AdamOptimizer。 其他一切似乎都一样:

  1. 使用的损失函数是 Frobenius 范数
  2. 在这两种情况下都没有正则化
  3. 使用相同数量的潜在维度对相同数据进行测试

我正在使用的相关代码:

1. scikit-learn 方法:

model =  NMF(alpha=0.0, init='random', l1_ratio=0.0, max_iter=200, 
n_components=2, random_state=0, shuffle=False, solver='cd', tol=0.0001, 
verbose=0)
model.fit(data)
result = model.inverse_transform(model.transform(data))

2。 TensorFlow 方法:

w = tf.get_variable(initializer=tf.abs(tf.random_normal((data.shape[0], 
2))), constraint=lambda p: tf.maximum(0., p))
h = tf.get_variable(initializer=tf.abs(tf.random_normal((2, 
data.shape[1]))), constraint=lambda p: tf.maximum(0., p))
loss = tf.sqrt(tf.reduce_sum(tf.squared_difference(x, tf.matmul(w, h))))

我的问题是,如果这两种方法生成的建议不匹配,那么我如何确定哪些是正确的? 根据我的用例,sklearn 的 NMF 给了我很好的结果,但不是 TensorFlow 实现。如何使用我的自定义实现来达到同样的效果?

【问题讨论】:

  • 一个人可以写多页关于所有这些组件的内容,但我们只是说:它是非凸优化和收敛(如果发生)取决于初始值(可能有不同的局部最小值)。如果没有看到代码,很难准确地掌握你在做什么。 (此外:如果没有正则化,你可能在推荐器设置中没有取得好的结果;另外:大多数推荐器不使用 NMF,那么你使用它的理由是什么?)
  • @sascha - 修改帖子以包含代码。我确实意识到多个局部最小值,并且它们很可能不会收敛到同一点。但是,我想了解如何使用自定义实现获得良好的结果。我理解为了获得更好的结果,正则化是必要的,但这只是一个基本示例,我想首先使用这两种方法获得可比较的结果。您的意思是协同过滤、基于内容的方法?
  • 然后研究所有组件,使用相同的初始点,将优化器调整为更保守/更局部(不是 Adam;简单的香草 SGD;小步长,很多)。但我认为这样做没有任何好处。我在替代方案方面的意思是 低秩矩阵分解 具有更好的秩代理(trace-norm 或 max-norm)。简而言之:一种不同的损失,更难优化,但可行,即使是大规模的(在某些假设下)。
  • 已经使用相同的初始值,也尝试使用 SGD 和一系列超参数。 NMF 不也是低秩矩阵分解的一种形式,因为与原始维度相比,潜在维度的数量非常少?

标签: python tensorflow scikit-learn recommendation-engine nmf


【解决方案1】:

优化器的选择对训练的质量有很大的影响。一些非常简单的模型(例如,我正在考虑 GloVe)确实可以与某些优化器一起使用,而其他一些则根本不可用。然后,回答您的问题:

  1. 我如何确定哪些是正确的?

评估与模型的设计一样重要,也同样困难,也就是说,您可以尝试这 2 个模型和几个可用的数据集,并使用一些指标对它们进行评分。您还可以在真实案例应用程序上使用 A/B 测试来估计您的建议的相关性。

  1. 我怎样才能使用我的自定义实现来达到同样的效果?

首先,尝试为 Tensorflow 找到坐标下降优化器,并确保您实现的所有步骤与 scikit-learn 中的步骤完全相同。然后,如果您无法重现相同的内容,请尝试不同的解决方案(为什么不先尝试一个简单的梯度下降优化器?)并利用 Tensorflow 提供的强大模块化优势!

最后,如果您的实施提供的建议很糟糕,我建议您有错误。尝试与一些existing codes 进行比较。

【讨论】:

  • 已经尝试过使用 SGD,与使用 Adam 相比,最终结果没有太大差异(不考虑收敛时间)。我还遵循了您链接的完全相同的代码,上述结果基于此。 “从 Tensorflow 提供的巨大模块化中获利”是什么意思?能否请您详细说明或更具体一点?
  • 模块化是指您可以轻松更改部分代码(优化器、约束、损失、正则化等)
猜你喜欢
  • 2016-12-22
  • 2017-05-29
  • 2018-09-25
  • 2020-08-12
  • 1970-01-01
  • 1970-01-01
  • 2016-11-16
  • 2021-02-24
  • 2018-08-26
相关资源
最近更新 更多