реализация функции расстояния Гауэра - PullRequest
4 голосов
/ 28 ноября 2010

У меня есть матрица (размер: 28 столбцов и 47 строк) с числами.Эта матрица имеет дополнительную строку, которая содержит заголовки для столбцов («порядковый» и «номинальный»).

Я хочу использовать функцию расстояния Гауэра в этой матрице. Здесь говорит, что:

Окончательное различие между i-м и j-м единицами получается как взвешенная сумма различий для каждой переменной:

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

В частности, d_ijk представляет расстояние между i-й и j-й единицами, вычисленное с учетом k-й переменной.Это зависит от природы переменной:

  • столбцы фактора или символа считаются категориальными номинальными переменными и d_ijk = 0, если

    x_ik = x_jk, 1 в противном случае;

  • упорядоченные столбцы рассматриваются как категориальные порядковые переменные, а
    значения заменяются на
    соответствующий индекс положения, r_ik в уровнях фактора.Эти позиции
    индексов (которые отличаются от выходных данных ранга функции R)
    преобразуются следующим образом

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

Эти новые значения, z_ik, обрабатываются как наблюдения масштабированной переменной с интервалом
.

Что касается веса delta_ijk:

  • delta_ijk = 0, если x_ik = NA или x_jk = NA;
  • 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}

Но я получил ошибку.Так что я застрял и не могу сделать все остальное.

PS Извините, если я допускаю ошибки, но английский язык не очень часто встречается.

Ответы [ 3 ]

3 голосов
/ 29 ноября 2010

Почему вы хотите изобрести велосипед?В R есть несколько функций / пакетов, которые рассчитают это для вас, в том числе daisy() в кластере пакетов, который поставляется с R.

Прежде всего, сначала извлеките эти заголовки «типа данных» из ваших данных.Если это действительно матрица, то символьная информация в этой строке заголовка сделает всю матрицу символьной матрицей.Если это фрейм данных, то все столбцы, вероятно, будут факторами.То, что вы хотите сделать, это кодировать тип данных в каждом столбце (компоненте вашего фрейма данных) как '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

Вы говорите, что не можете сделать это таким образом?Можете ли вы объяснить, почему нет?Поскольку вы, похоже, будете прилагать определенные усилия, чтобы сделать что-то, что другие люди уже закодировали для вас.Это не домашняя работа, не так ли?

0 голосов
/ 02 декабря 2010

Спасибо Гевину и Д.В. за вашу помощь. Мне удалось решить проблему и найти правильную матрицу расстояний. Я использовал daisy () после того, как перекодировал класс данных, и это сработало.

P.S. Решение, которое вы предложили в другой моей теме для изменения класса столбцов:

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

не сработало. Изменился только первый именной и порядковый столбец.

Еще раз спасибо за вашу помощь.

0 голосов
/ 28 ноября 2010

Я не уверен, что делает твоя логика, но ты вкладываешь слишком много "{" для твоего же блага.Обычно я использую пары {} для окружения последующего предложения:

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}
                  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...