首先,您的类别是否相互独立?如果这真的是四个并行的问题,一次解决一个,它会简化一些事情。
其次,聚类的核心是任意两个观测值之间的距离函数。因为您的数据有缺失值,所以您需要明确决定如何处理它们。一种常见的方法是通过丢弃任何具有任何空值的行来忽略该问题,这对您的数据根本不起作用。
一种简单的方法是忽略任何 NA 列,但保留其余列——对于 C 类,第 1 行和第 2 行之间的差异为 4(第 11、14、15 和 16 列都减一) . 这种方法有一个问题,我稍后会谈到,但现在让我们实现它。
对于每个类别,我们需要三行质心位置(我们不妨从随机选择的没有缺失值的行开始)。然后,我们使用一堆求和的 ifs 计算到每个质心的距离:if(matrix cell != NA, matrix cell - centroid cell, 0) 跨越所有列。(如果您在电子表格中进行此计算,我会使用中间单元格来计算各个部分,而不是处理一个庞大的公式。)
然后我们使用标准的迭代过程优化质心:每一行获得一个与最近的质心相对应的组成员资格,然后每个质心成为其组成员的平均值(看起来你的平均值函数自动排除了 NA),然后我们重复直到使满意。
为什么我指定我们必须在没有 NA 的情况下播种?如果您允许在质心中进行 NA 测量,这将失败,因为所有 NA 的一行都处于中心位置!如果我们的更新步骤永远不允许我们移动到 NA,则 NA 列将是暂时的,但是当我们取缺失列的平均值时会发生什么?(在您的示例数据中,考虑如果第 4-12 行是 B 类别中的一个组会发生什么。)
因此,如果我们想在质心中允许 NA,我们需要将距离函数修改为如下所示:
- 如果两个单元格都是数字,则距离就是差异
- 如果两个单元格都是 NA,则距离为 2
- 如果只有一个单元格为 NA,则距离为 3。
选择这些数字使得对于任何完整的数字列,质心位置的数值将更接近,但如果该列有足够多的 NA 行,质心中的 NA 值将更接近。您可能需要调整这些值,使 NA 阈值看起来像您想要的那样。
为了使用我们的距离函数找到一组行的质心,我们应该使用优化程序,但我们可以作弊:如果组中的 NA 数量高于阈值,我们将其设置为 NA,否则我们将其设置为平均值。