【问题标题】:implementation of the Gower distance function高尔距离函数的实现
【发布时间】:2011-05-16 23:30:45
【问题描述】:

我有一个带有数字的矩阵(大小:28 列和 47 行)。该矩阵有一个额外的行,其中包含列的标题(“序数”和“标称”)。

我想在这个矩阵上使用 Gower 距离函数。 Here 说:

第 i 个和第 j 个单元之间的最终差异作为每个变量差异的加权和获得:

    d(i,j) = sum_k(delta_ijk * d_ijk ) / sum_k( delta_ijk )

特别是,d_ijk 表示考虑第 k 个变量计算的第 i 个和第 j 个单元之间的距离。这取决于变量的性质:

  • 因子或字符列是 被视为分类名义 变量和d_ijk = 0 if

    x_ik =x_jk,否则为 1;

  • 有序列被视为 分类序数变量和
    这些值被替换为
    对应的位置索引,r_ik in 因子水平。这些位置
    索引(不同于 R 函数等级的输出)是
    转化为如下方式

z_ik = (r_ik - 1)/(max(r_ik) - 1)

这些新值 z_ik 被视为对一个
区间标度变量。

就权重delta_ijk而言:

  • delta_ijk = 0 如果 x_ik = NA 或 x_jk = 不适用;
  • delta_ijk = 1 在所有其他情况下。

我知道有一个 gower.dist 函数,但我必须这样做。 所以,对于“d_ijk”、“delta_ijk”和“z_ik”,我尝试制作函数,因为我没有找到更好的方法。

我从“delta_ijk”开始,我尝试了这个:

Delta=function(i,j){for (i in 1:28){for (j in 1:47){  
+{if (MyHeader[i,j]=="nominal")
+ result=0
+{else if (MyHeader[i,j]=="ordinal") result=1}}}}
+;result}

但我得到了错误。所以我被卡住了,我不能做剩下的事情。

附:如果我犯了错误,请见谅,但英语不是我经常使用的语言。

【问题讨论】:

  • 您能否将您的数据重新发布为 zip 或 tar.gz 文件。我的 linux 盒子不会打开 rar 档案,除非我不遗余力地找出什么应用程序会打开它们。如果你这样做,我很乐意看看。

标签: function r


【解决方案1】:

为什么要重新发明轮子billyt? R 中有几个函数/包可以为你计算,包括 R 附带的包集群中的daisy()

首先,从数据中获取那些“数据类型”标头。如果这确实是一个矩阵,那么这个标题行中的字符信息将使整个矩阵成为一个字符矩阵。如果它是一个数据框,那么所有列都可能是因子。您要做的是将每列(数据框的组件)中的数据类型编码为'factor''ordered'

df <- data.frame(A = c("ordinal",1:3), B = c("nominal","A","B","A"),
                 C = c("nominal",1,2,1))

这给出了这一点 --- 请注意,由于额外的信息,所有都被存储为因子。

> head(df)
        A       B       C
1 ordinal nominal nominal
2       1       A       1
3       2       B       2
4       3       A       1
> str(df)
'data.frame':   4 obs. of  3 variables:
 $ A: Factor w/ 4 levels "1","2","3","ordinal": 4 1 2 3
 $ B: Factor w/ 3 levels "A","B","nominal": 3 1 2 1
 $ C: Factor w/ 3 levels "1","2","nominal": 3 1 2 1

如果我们去掉第一行并重新编码成正确的类型,我们可以很容易地计算出高尔系数。

> headers <- df[1,]
> df <- df[-1,]
> DF <- transform(df, A = ordered(A), B = factor(B), C = factor(C))
> ## We've previously shown you how to do this (above line) for lots of columns!
> str(DF)
'data.frame':   3 obs. of  3 variables:
 $ A: Ord.factor w/ 3 levels "1"<"2"<"3": 1 2 3
 $ B: Factor w/ 2 levels "A","B": 1 2 1
 $ C: Factor w/ 2 levels "1","2": 1 2 1
> require(cluster)
> daisy(DF)
Dissimilarities :
          2         3
3 0.8333333          
4 0.3333333 0.8333333

Metric :  mixed ;  Types = O, N, N 
Number of objects : 3

这与 gower.dist() 给出的数据相同(尽管格式稍有不同 (as.matrix(daisy(DF))) 将是等效的):

> gower.dist(DF)
          [,1]      [,2]      [,3]
[1,] 0.0000000 0.8333333 0.3333333
[2,] 0.8333333 0.0000000 0.8333333
[3,] 0.3333333 0.8333333 0.0000000

你说你不能这样做?你能解释为什么不吗?因为您似乎要付出一定程度的努力来做其他人已经为您编写好的事情。这不是家庭作业,是吗?

【讨论】:

  • 首先,感谢 Gavin 和 Dwin 的回答。我使用了“gower.dist”函数,也使用了“daisy()”函数,虽然我不喜欢第二个函数,因为它使所有变量都变成数字,并且每个函数得到不同的结果。我知道我正在尝试做的是重做已经完成的事情,但我不能做其他事情。这是为了研究,我必须使用 R 来完成。
  • 我这个同事用matlab做验证。因为在 Matlab 中没有准备好 Gower 距离系数,所以她使用我在第一篇文章中发布的函数来实现。她的代码没问题,因为当我们在数字矩阵上测试她的代码和“gower.dist”函数时,我们得到了完全相同的矩阵。但是有了这些数据,我必须将序数列重新编码为有序,将名义值重新编码为因子,我们得到了不同的结果。我在这里(mediafire.com/?nx25hzxcmvq998o)上传了数据以及我和她的结果,以便自己进行测试。很抱歉给您添麻烦了。
  • @bilyt:关于 daisy() 将您的数据转换为数字,您再了。 daisy() 多年来一直是 R 的一部分,并且比您的同事 Matlab 代码更吸引眼球。
  • @billyt:高尔系数不仅仅适用于数字。您不能在仅数字的情况下针对daisy() 测试您的同事 Matlab 代码,然后假设 Matlab 代码是正确的,因为当与非数字数据一起使用时,它会得到与 daisy() 不同的答案。说真的,我已经在 R 中为另一个包编写了 Gower 的函数,我知道 daisy() 是正确的,因为它在一个小型测试数据集上给出了已发布的答案。
  • @Gavin:这是 .zip (mediafire.com/?u8mux3lg47t61h1) 中的数据。对于 daisy(),我的意思是虽然我已经将数据的类转换为“因子”和“有序因子”,但它给了我与 gower.dist 不同的结果,所以我假设它计算了默认类数据。
【解决方案2】:

我不确定你的逻辑在做什么,但是为了你自己的利益,你在里面放了太多的“{”。我通常使用 {} 对来围绕结果子句:

Delta=function(i,j){for (i in 1:28) {for (j in 1:47){  
       if (MyHeader[i,j]=="nominal") {
         result=0
    # the "{" in the next line before else was sabotaging your efforts
        } else if (MyHeader[i,j]=="ordinal") { result=1} }
      result}
                  }

【讨论】:

    【解决方案3】:

    感谢 Gavin 和 DWin 的帮助。我设法解决了这个问题并找到了正确的距离矩阵。我在重新编码数据的类后使用了 daisy() 并且它起作用了。

    附:您在我的另一个主题中建议的更改列类的解决方案:

    DF$nominal <- as.factor(DF$nominal)
    DF$ordinal <- as.ordered(DF$ordinal)
    

    没用。它只改变了第一个名义和序数列。

    再次感谢您的帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-02
      • 2019-08-21
      • 1970-01-01
      • 2018-04-02
      • 1970-01-01
      • 2023-03-08
      • 2011-06-19
      • 2018-10-07
      相关资源
      最近更新 更多