如何在推荐系统中的Pearson相关用户 - 用户相似度矩阵中处理​​NaN?

pho*_*xis 6 recommendation-engine r nan pearson correlation

我正在从用户评级数据(特别是MovieLens100K数据)生成用户 - 用户相似度矩阵.计算相关性导致一些NaN值.我在一个较小的数据集中测试过:

用户 - 项目评级矩阵

   I1 I2 I3 I4
U1 4  0  5  5  
U2 4  2  1  0  
U3 3  0  2  4  
U4 4  4  0  0  
Run Code Online (Sandbox Code Playgroud)

用户 - 用户Pearson相关相似度矩阵

              U1        U2        U3       U4      U5
U1             1        -1         0      -nan  0.755929
U2            -1         1         1      -nan -0.327327
U3             0         1         1      -nan  0.654654
U4          -nan      -nan      -nan      -nan      -nan
U5      0.755929 -0.327327  0.654654      -nan         1
Run Code Online (Sandbox Code Playgroud)

为了计算皮尔逊相关性,在两个用户之间仅考虑经过指定的项目.(参见下一代推荐系统:对最新技术和可能扩展的调查,Gediminas Adomavicius,Alexander Tuzhilin

我该如何处理NaN值?

编辑 这是一个代码,我在其中找到R中的皮尔森相关性.R矩阵是用户项目评级矩阵.包含1到5刻度等级0表示未评级.S是用户 - 用户相关矩阵.

  for (i in 1:nrow (R))
  {
    cat ("user: ", i, "\n");
    for (k in 1:nrow (R))
    {
      if (i != k)
      {
        corated_list <- which (((R[i,] != 0) & (R[k,] != 0)) == TRUE);
        ui <- (R[i,corated_list] - mean (R[i,corated_list]));
        uk <- (R[k,corated_list] - mean (R[k,corated_list]));
        temp <- sum (ui * uk) / sqrt (sum (ui^2) * sum (uk^2));
        S[i,k] <- ifelse (is.nan (temp), 0, temp)
      }
      else
      {
        S[i,k] <- 0;
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

请注意,S[i,k] <- ifelse (is.nan (temp), 0, temp)在行中我将NaNs 替换为0.

小智 3

我最近用 Java 开发了一个用于用户-用户和用户-项目矩阵的推荐系统。首先,您可能已经发现了。RS很难。对于我的实现,我使用了 Apache Common Math Library,它非常棒,您使用的是 R,它在计算 Pearson 的方式方面可能相对相似。

\n\n

你的问题是:我如何处理 NaN 值,然后编辑说你说 NaN is = 0。

\n\n

我的回答是这样的:

\n\n

您不应该真正将 NaN 值处理为 0,因为您所说的是用户或用户/项目之间绝对不存在相关性。情况可能是这样,但情况可能并不总是如此。忽略这一点将会扭曲你的建议。

\n\n

首先,您应该问自己,“为什么我会得到 NaN 值”?以下是 NaN 的 Wiki 页面中的一些原因,详细说明了为什么您可能会得到 NaN 值:

\n\n

可以返回 NaN 的操作有以下三种:

\n\n
    \n
  1. 使用 NaN 作为至少一个操作数的运算。

  2. \n
  3. 不定形式\n除法 0/0 和 \xc2\xb1\xe2\x88\x9e/\xc2\xb1\xe2\x88\x9e\n乘法 0\xc3\x97\xc2\xb1\xe2\x88\x9e 和 \ xc2\xb1\xe2\x88\x9e\xc3\x970\n添加 \xe2\x88\x9e + (\xe2\x88\x92\xe2\x88\x9e), (\xe2\x88\x92\xe2\x88\ x9e) + \xe2\x88\x9e 和等效减法\n该标准具有幂的替代函数:\n标准 pow 函数和整数指数 pown 函数定义 00、1\xe2\x88\x9e 和 \xe2\x88\x9e0为 1。\npowr 函数将所有三种不确定形式定义为无效操作,因此返回 NaN。

  4. \n
  5. 具有复杂结果的实数运算,例如:\n负数的平方根。\n负数的对数\n小于 \xe2\x88\x921 或大于 +1 的数字的反正弦或余弦。

  6. \n
\n\n

您应该调试您的应用程序并逐步执行每个步骤,以查看上述哪个原因是造成问题的原因。

\n\n

其次,了解皮尔逊相关性可以用多种不同的方式表示,您需要考虑是否在样本或总体中计算它,然后找到适当的计算方法,即针对总体:

\n\n

cor(X, Y) = \xce\xa3[(xi - E(X))(yi - E(Y))] / [(n - 1)s(X)s(Y)]

\n\n

其中 E(X) 是 X 的平均值,\nE(Y) 是 Y 值的平均值,\ns(X)、s(Y) 是标准差,\n标准差通常是方差的正平方根和 \n方差 = sum((x_i - 均值)^2) / (n - 1)

\n\n

其中mean是均值,\nn是样本观测值的数量。

\n\n

这可能是您的 NaN 出现的地方,即除以 0 表示未评级。如果可以的话,我建议不要使用 0 值来表示未评级,而是使用 null。我这样做有两个原因: \n1. 0 可能是导致 NaN 和 \n2 结果出现错误的原因。可读性/可理解性。你的量表是 1 - 5,所以 0 不应该出现,这会让事情变得混乱。因此,如果可能的话,请避免这种情况。

\n\n

第三,站在推荐者的角度,从推荐的角度思考问题。如果您有 2 个用户,并且他们只有 1 个共同评分,则在较小的数据集中为 I1 假设为 U1 和 U4。这 1 个共同点真的足以提供建议吗?答案是——当然不是。那么我是否也建议您设置一个 ratingInCommon 的最低阈值,以确保推荐的质量更好。您可以为此阈值设置的最小值为 2,但请考虑将其设置得更高一些。如果您阅读了 MovieLens 研究,那么他们会将其设置为 5-10 之间(我记不清了)。设置越高,您获得的覆盖范围就越少,但您将获得“更好”(错误分数更低)的建议。您可能已经阅读了学术文献,然后您可能会明白这一点,但我想我还是会提到它。

\n\n

就上述一点而言。查看 U4 并与其他所有用户进行比较。请注意 U4 与任何用户的共同点不超过 1 个。现在希望您会注意到 NaN 只与 U4 一起出现。如果您遵循了这个答案,那么您现在希望看到您得到 NaN 的原因是因为您实际上可以仅使用 1 个共同项来计算 Pearson's :)。

\n\n

最后,上面的示例数据集让我有点困扰的一件事是 1 和 -1 的相关性数量。想想这实际上说明了这些用户的偏好,然后根据实际评级进行检查。例如,查看 U1 和 U2 评级。对于项目 1,它们具有很强的正相关性 1(均将其评为 4),然后对于项目 3,它们具有很强的负相关性(U1 将其评为 5,U3 将其评为 1),这两个用户之间的 Pearson 相关性似乎很奇怪 - 1(即他们的偏好完全相反)。显然情况并非如此,实际上 Pearson 分数应该略高于或略低于 0。这个问题又回到了关于在量表上使用 0 以及仅比较少量项目的观点。

\n\n

现在,有一些策略可以“填写”用户未评分的项目。我不会深入讨论它们,您需要阅读它们,但本质上它就像使用该项目的平均分数或该用户的平均评分。这两种方法都有其缺点,就我个人而言,我不太喜欢它们中的任何一种。我的建议是仅当用户有 5 个或更多共同项目时才计算用户之间的 Pearson 相关性,并忽略评级为 0(或更好 - 空)评级的项目。

\n\n

所以得出结论。

\n\n
    \n
  1. NaN 不等于 0,因此不要将其设置为 0。
  2. \n
  3. 比例中的 0 最好表示为 null
  4. \n
  5. 仅当两个用户之间的共同项目数 >1(最好大于 5/10)时,才应计算 Pearson 相关性。
  6. \n
  7. 仅计算两个用户具有共同评分项目的皮尔逊相关性,不包括其他用户未评分的项目。
  8. \n
\n\n

希望有帮助,祝你好运。

\n