在R中处理带有NA值的聚类

13

我很惊讶地发现来自library(cluster)clara函数允许NAs。但是函数文档没有说明如何处理这些值。

所以我的问题是:

  1. clara如何处理NAs?
  2. 这是否可以用于kmeans(不允许NAs)?

[更新] 所以我在clara函数中找到了代码行:

inax <- is.na(x)
valmisdat <- 1.1 * max(abs(range(x, na.rm = TRUE)))
x[inax] <- valmisdat

使用valmisdat进行缺失值替换。不确定为什么要使用这个公式。有什么建议吗?也许分别处理每列的NAs并用平均值/中位数替换更“自然”?

3个回答

9
尽管没有明确说明,但我认为 NA 是按照 ?daisy 帮助页面所描述的方式进行处理的。详细信息部分如下:

在 daisy 算法中,x 行中的缺失值不包含在涉及该行的差异中。

考虑到 clara() 内部将使用相同的代码,这就是我理解数据中的 NA 如何处理的方式 - 它们只是不参与计算。这是在这种情况下合理的标准做法,例如在 Gower 的广义相似系数的定义中使用。

更新 clara.cC 源代码清楚地表明了这一点(在 ./src/clara.c 中的第 350-356 行):

    if (has_NA && jtmd[j] < 0) { /* x[,j] has some Missing (NA) */
        /* in the following line (Fortran!), x[-2] ==> seg.fault
           {BDR to R-core, Sat, 3 Aug 2002} */
        if (x[lj] == valmd[j] || x[kj] == valmd[j]) {
        continue /* next j */;
        }
    }

在处理缺失值的代码方面,daisy函数与clara函数使用相同的代码行(请参阅我的问题更新)。 - danas.zuokas
@danas.zuokas 我不确定仅从您认为与问题相关的源代码中提取任意行是否有帮助。 您需要研究R代码和C代码。 valmisdat是C代码中用于指示缺失数据(NA)的值,而不是直接使用NA。 如果您查看C代码,您会发现它明显地忽略了变量具有一个或两个样本的缺失值的比较,这些样本正在计算差异性。 请参见更新的答案以获取指向代码的指针。 - Gavin Simpson
你能想到在“kmeans”中使用相同的NA处理方式的方法吗? - danas.zuokas
3
可能需要编写自己的 k-means 算法。基本上,k-means 是在组内平方和(即到质心的距离)上工作的。clara 做同样的事情,所以这个想法是可行的(当计算到质心的欧几里得距离和质心本身时,您只需忽略那些比较)。您是否一定要使用 k-means?如果可以使用 k-medoids(因为它比 k-means 更加健壮),则可以使用 cluster 包中的 pam() 函数,该函数处理 NA,就像 clara()daisy() 一样。 - Gavin Simpson
@GavinSimpson,你在使用基于矩阵的方法进行k-means之前是否遇到过可扩展性问题?根据R中的内存分配情况,向量可能会太大。 - Scott Davis
显示剩余2条评论

3

不确定kmeans是否可以通过忽略行中的缺失值来处理缺失数据。

kmeans有两个步骤:

  1. 计算观察值和原始聚类均值之间的距离。
  2. 根据新计算的距离更新新的聚类均值。

当我们的观察值存在缺失数据时:

第1步可以通过适当调整距离度量来处理,例如在clara/pam/daisy包中。但是,如果观察的每一列都没有值,则无法执行第2步。因此,将缺失值进行插补可能是kmeans处理缺失数据的下一个最佳选项。


0
透过查看 Clara c 代码,我发现在 Clara 算法中,当观测值存在缺失时,平方和会与缺失值数量成比例地“减少”,我认为这是错误的! clara.c 的第 646 行代码如下:“ dsum *= (nobs / pp) ”,显示它计算每对观测值中非缺失值的数量(nobs),将其除以变量数(pp),并将结果乘以平方和。我认为应该采用另外一种方法,即“ dsum *= (pp / nobs) ”。

1
你可以使用编辑链接来编辑你之前的回答。 - zero323

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接