R中多维度的聚类/匹配

Posted

技术标签:

【中文标题】R中多维度的聚类/匹配【英文标题】:Clustering / Matching Over Many Dimensions in R 【发布时间】:2014-12-04 22:47:18 【问题描述】:

我有一个非常庞大且复杂的数据集,其中包含许多对公司的观察。公司的一些观察是多余的,我需要制作一个键来将多余的观察映射到一个单一的观察。然而,判断它们是否真的代表同一家公司的唯一方法是通过各种变量的相似性。我认为合适的方法是一种基于各种条件的聚类,甚至可能是某种倾向得分匹配。也许我只需要灵活的工具来制作复杂的相似度矩阵。

不幸的是,我不太清楚如何在 R 中进行此操作。我见过的大多数用于聚类和分类的工具似乎都使用数值距离或分类数据,但似乎不允许多个条件或用户指定的条件。

在下面,我尝试创建一个较小的公开示例,说明我正在使用的数据类型以及我试图产生的结果。有一些条件必须适用,例如,位置必须相同。有一些特征可能会相互关联,例如 var1 和 var2。然后有一些特征可以相互关联,但不能冲突,比如var3。

另一个复杂的层面是,我试图用来映射冗余观察的关联类型会有所不同。例如,id1 和 id2 是同一家公司,重复输入了两次数据。在一个地方,它的名字是“苹果”,另一个是“红苹果”。它们共享相同的位置、var1 值和 var3(在调整格式后)。同样,id 3、5 和 6 也只是一家公司,尽管每个公司的大部分输入都不同。一些集群会识别多个观测值,而其他集群只有一个。理想情况下,我想找到一种方法来根据几个条件对观察进行分类或关联,例如: 1.测试位置是否相同 2.测试var3是否不同 3. 测试names是否是其他人的子串 4.测试名称的编辑距离 5. 检验观察值之间 var1 和 var2 的相似度

无论如何,希望有比我发现的更好、更灵活的工具,或者有人对 R 中的此类数据工作有经验。非常感谢任何和所有建议和建议!

数据

id  name        location    var1    var2    var3
1   apples        US        1       abc     12345
2   red apples    US        1       NA      12-345
3   green apples  Mexico    2       def     235-92
4   bananas       Brazil    2       abc     NA
5   oranges       Mexico    2       NA      23592
6   green apple   Mexico    NA      def     NA
7   tangerines    Honduras  NA      abc     3498
8   mango         Honduras  1       NA      NA
9   strawberries  Honduras  NA      abcd    3498
10  strawberry    Honduras  NA      abc     3498
11  blueberry     Brazil    1       abcd    2348
12  blueberry     Brazil    3       abc     NA
13  blueberry     Mexico    NA      def     1859
14  bananas       Brazil    1       def     2348
15  blackberries  Honduras  NA      abc     NA
16  grapes        Mexico    6       qrs     NA
17  grapefruits   Brazil    1       NA      1379
18  grapefruit    Brazil    2       bcd     1379
19  mango         Brazil    3       efaq    NA
20  fuji apples   US        4       NA      189-35

结果

id  name        location    var1    var2    var3        Result
1   apples        US        1       abc     12345       1
2   red apples    US        1       NA      12-345      1
3   green apples  Mexico    2       def     235-92      3
4   bananas       Brazil    2       abc     NA          4
5   oranges       Mexico    2       NA      23592       3
6   green apple   Mexico    NA      def     NA          3
7   tangerines    Honduras  NA      abc     3498        7
8   mango         Honduras  1       NA      NA          8
9   strawberries  Honduras  NA      abcd    3498        7
10  strawberry    Honduras  NA      abc     3498        7
11  blueberry     Brazil    1       abcd    2348        11
12  blueberry     Brazil    3       abc     NA          11
13  blueberry     Mexico    NA      def     1859        13
14  bananas       Brazil    1       def     2348        11
15  blackberries  Honduras  NA      abc     NA          15
16  grapes        Mexico    6       qrs     NA          16
17  grapefruits   Brazil    1       NA      1379        17
18  grapefruit    Brazil    2       bcd     1379        17
19  mango         Brazil    3       efaq    NA          19
20  fuji apples   US        4       NA      189-35      20

提前感谢您的时间和帮助!

【问题讨论】:

这里的问题就是我们所说的“困难”问题。我认为在每个变量中创建数字距离的一种方法是使用en.wikipedia.org/wiki/Levenshtein_distance。然后,您可以为匹配的总距离定义一些容差。编辑:我会尝试模拟一些东西。 还有一些软件包可以帮助您检查字符的相似性。它可以让您得出结论,“apple”和“red apple”在同一个簇中。 @Adii_ 不会有任何包可以匹配"apples""red apples",也不会匹配其中的任何其他苹果。 @iShouldUseAName 你想打赌吗? :) @Adii_ 嗯...当然!我会很感动的! 【参考方案1】:
library(stringdist)
getMatches <- function(df, tolerance=6)
  out <- integer(nrow(df))
  for(row in 1:nrow(df))
    dists <- numeric(nrow(df))
    for(col in 1:ncol(df))
      tempDist <- stringdist(df[row, col], df[ , col], method="lv")

      # WARNING: Matches NA perfectly.
      tempDist[is.na(tempDist)] <- 0
      dists <- dists + tempDist
    
    dists[row] <- Inf

    min_dist <- min(dists)
    if(min_dist < tolerance)
      out[row] <- which.min(dists)
    
    else
      out[row] <- row
    
  
  return(out)


test$Result <- getMatches(test[, -1])

test 是您的数据。这可能肯定需要一些改进,当然也需要一些后处理。这将创建一个具有最接近匹配索引的列。如果在给定的容差范围内找不到匹配项,则返回自身的索引。

编辑:我稍后会尝试更多。

【讨论】:

感谢您的帮助。我会稍微修改一下,看看我是否可以让这样的事情起作用。

以上是关于R中多维度的聚类/匹配的主要内容,如果未能解决你的问题,请参考以下文章

R语言中不同类型的聚类方法比较

如何将集群标签与 Matlab 中的“基本事实”标签匹配

第一节:基于网格的聚类算法概述

R中DBSCAN的聚类中心平均值?

集群标签比较 - 标签匹配

高维数据的聚类小记