2016-10-26 23 views
2

각 관찰에 대해 가장 가까운 클러스터를 찾기 위해 두 데이터 프레임의 행 사이의 거리 (비 유사성)를 계산하고 싶습니다. 요인과 수치 변수가 있으므로 Gower 거리를 사용하고 있습니다. 하나의 행렬의 행 사이의 차이점이 아닌 두 개의 데이터 프레임을 비교하려는 경우 gower.dist가 필요한 함수가됩니다. 그러나 구현할 때 데이지의 거버 (gower)를 사용할 때 결과가 다르다는 것을 깨달았습니다. 행을 묶고 관심있는 비평 행렬 부분을 살펴 보았습니다.R - 다른 결과 gower.dist 및 daisy (..., metric = "gower")

여기서는 내 데이터 샘플 만 제공하지만 모든 데이터와 비 유사성을 계산할 때 gower.dist는 해당 행이 서로 같지 않아도 0의 비 유사성을 가져 오는 경우가 많았습니다. 왜? 그리고 그 결과가 다른 이유는 무엇일까요? 제 생각에, daisys의 집은 올바르게 작동하고 gower.dist는 (이 예제에서는) 작동하지 않습니다. 다음 데이터

df <- structure(list(searchType = structure(c(NA, 1L, 1L, 1L, 1L), .Label = c("1", "2"), class = "factor"), roomMin = structure(c(4L, 1L, 1L, 6L, 6L), .Label = c("10", "100", "150", "20", "255", "30", "40", "50", "60", "70", "Missing[NoInput]"), class = "factor"), roomMax = structure(c(8L, 8L, NA, 10L, 9L), .Label = c("10", "100", "120", "150", "160", "20", "255", "30", "40", "50", "60", "70", "80", "90", "Missing[NoInput]"), class = "factor"), priceMin = c(NA, 73, 60, 29, 11), priceMax = c(35, 11, 1, 62, 23), sizeMin = structure(c(5L, 5L, 5L, 6L, 6L), .Label = c("100", "125", "150", "250", "50", "75", "Missing[NoInput]"), class = "factor"), sizeMax = structure(c(1L, 6L, 5L, 3L, 1L), .Label = c("100", "125", "150", "250", "50", "75", "Missing[NoInput]"), class = "factor"), longitude = c(6.6306, 7.47195, 8.5562, NA, 8.569), latitude = c(46.52425, 46.9512, 47.37515, NA, 47.3929), specificSearch = structure(c(1L, 1L, 1L, 1L, 1L), .Label = c("0", "1"), class = "factor"), objectType = structure(c(NA, 2L, 2L, 2L, 2L), .Label = c("1", "2", "3", "Missing[]"), class = "factor")), .Names = c("searchType", "roomMin", "roomMax", "priceMin", "priceMax", "sizeMin", "sizeMax", "longitude", "latitude", "specificSearch", "objectType"), row.names = c(112457L, 94601L, 78273L, 59172L, 117425L), class = "data.frame")                                         
cent <- structure(list(searchType = structure(c(1L, 1L, 1L), .Label = c("1", "2"), class = "factor"), roomMin = structure(c(1L, 4L, 4L), .Label = c("10", "100", "150", "20", "255", "30", "40", "50", "60", "70", "Missing[NoInput]"), class = "factor"), roomMax = structure(c(6L, 9L, 8L), .Label = c("10", "100", "120", "150", "160", "20", "255", "30", "40", "50", "60", "70", "80", "90", "Missing[NoInput]"), class = "factor"), priceMin = c(60, 33, 73), priceMax = c(103, 46, 23), sizeMin = structure(c(1L, 5L, 5L), .Label = c("100", "125", "150", "250", "50", "75", "Missing[NoInput]"), class = "factor"), sizeMax = structure(c(1L, 2L, 1L), .Label = c("100", "125", "150", "250", "50", "75", "Missing[NoInput]"), class = "factor"), longitude = c(8.3015, 7.42765, 7.6104), latitude = c(47.05485, 46.9469, 46.75125), specificSearch = structure(c(1L, 1L, 1L), .Label = c("0", "1"), class = "factor"), objectType = structure(c(2L, 2L, 2L), .Label = c("1", "2", "3", "Missing[]"), class = "factor")), .Names = c("searchType", "roomMin", "roomMax", "priceMin", "priceMax", "sizeMin", "sizeMax", "longitude", "latitude", "specificSearch", "objectType"), row.names = c(60656L, 66897L, 130650L), class = "data.frame") 

은 감사와

library(cluster) 
library(StatMatch) 

# Calculate distance using daisy's gower 
daisyDist <- daisy(rbind(df,cent),metric="gower") 
daisyDist <- as.matrix(daisyDist) 
daisyDist <- daisyDist[(nrow(df)+1):nrow(daisyDist),1:nrow(df)] #only look at part where rows from df are compared to (rows of) cent 

# Calculate distance using dist.gower 
gowerDist <- gower.dist(cent,df) 

!

EDIT : 숫자 열에 NAs가 있기 때문에 오류/차이가 발생하고 다르게 처리되는 것으로 보입니다. 데이지의 GA 처리 방법을 gower.dist에 어떻게 적용 할 수 있습니까?

+0

HTTP : //stats.stackexchange.c om/questions/123624/gower-distance-with-r-functions-gower-dist-and-daisy가 도움이 될 것입니다. –

+0

링크를 이용해 주셔서 감사합니다. 그러나, 그것은 정말로 도움이되지 않습니다. 문제는 다른 것입니다. 그리고 같은 거리 행렬을 가져야한다는 것을 알고 있다는 것도 도움이되지 않습니다. 제 변수는 타입 요소와 숫자로되어 있습니다. 둘 다 데이지와 고어에서 동등하게 취급되어야합니다. .dist – Vanessa

답변

2

데이터 프레임의 숫자 열에있는 NA 값 때문입니다. 두 기능을 NA 값을 갖는 숫자 열로 완전히 다르게 동작 방법을보기 위하여 다음과 같은 코드를 고려한다 (데이지 더 강력하다 gower.dist) gower.dist 함수 파라미터 된 RNG와

df1 <- rbind(df,cent) 
head(df1) 
     searchType roomMin roomMax priceMin priceMax sizeMin sizeMax longitude latitude specificSearch objectType 
112457  <NA>  20  30  NA  35  50  100 6.63060 46.52425    0  <NA> 
94601   1  10  30  73  11  50  75 7.47195 46.95120    0   2 
78273   1  10 <NA>  60  1  50  50 8.55620 47.37515    0   2 
59172   1  30  50  29  62  75  150  NA  NA    0   2 
117425   1  30  40  11  23  75  100 8.56900 47.39290    0   2 
60656   1  10  20  60  103  100  100 8.30150 47.05485    0   2 

# only use the numeric column priceMin (4th column) to compute the distance 
class(df1[,4]) 
# [1] "numeric" 
df2 <- df1[4] 

# daisy output 
as.matrix(daisy(df2,metric="gower")) 
     112457  94601  78273  59172 117425  60656  66897 130650 
112457  0  NA  NA   NA  NA  NA   NA  NA 
94601  NA 0.0000000 0.2096774 0.70967742 1.0000000 0.2096774 0.64516129 0.0000000 
78273  NA 0.2096774 0.0000000 0.50000000 0.7903226 0.0000000 0.43548387 0.2096774 
59172  NA 0.7096774 0.5000000 0.00000000 0.2903226 0.5000000 0.06451613 0.7096774 
117425  NA 1.0000000 0.7903226 0.29032258 0.0000000 0.7903226 0.35483871 1.0000000 
60656  NA 0.2096774 0.0000000 0.50000000 0.7903226 0.0000000 0.43548387 0.2096774 
66897  NA 0.6451613 0.4354839 0.06451613 0.3548387 0.4354839 0.00000000 0.6451613 
130650  NA 0.0000000 0.2096774 0.70967742 1.0000000 0.2096774 0.64516129 0.0000000 

# gower.dist output 
gower.dist(df2) 
    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] 
[1,] NaN NaN NaN NaN NaN NaN NaN NaN 
[2,] NaN 0 0 0 0 0 0 0 
[3,] NaN 0 0 0 0 0 0 0 
[4,] NaN 0 0 0 0 0 0 0 
[5,] NaN 0 0 0 0 0 0 0 
[6,] NaN 0 0 0 0 0 0 0 
[7,] NaN 0 0 0 0 0 0 0 
[8,] NaN 0 0 0 0 0 0 0 

수정이 : 따라서

gower.dist(df2, rngs=max(df2, na.rm=TRUE) - min(df2, na.rm=TRUE)) 
    [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8] 
[1,] NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN 
[2,] NaN 0.0000000 0.2096774 0.70967742 1.0000000 0.2096774 0.64516129 0.0000000 
[3,] NaN 0.2096774 0.0000000 0.50000000 0.7903226 0.0000000 0.43548387 0.2096774 
[4,] NaN 0.7096774 0.5000000 0.00000000 0.2903226 0.5000000 0.06451613 0.7096774 
[5,] NaN 1.0000000 0.7903226 0.29032258 0.0000000 0.7903226 0.35483871 1.0000000 
[6,] NaN 0.2096774 0.0000000 0.50000000 0.7903226 0.0000000 0.43548387 0.2096774 
[7,] NaN 0.6451613 0.4354839 0.06451613 0.3548387 0.4354839 0.00000000 0.6451613 
[8,] NaN 0.0000000 0.2096774 0.70967742 1.0000000 0.2096774 0.64516129 0.0000000 

NAS는 다음 중 하나가 될 수있는 숫자와 같은 변수에 존재할 때, 데이지 같은 기능 gower.dist 작동하게하는 방법 :

df1 <- rbind(df,cent) 

# compute the ranges of the numeric variables correctly 
cols <- which(sapply(df1, is.numeric)) 
rngs <- rep(1, ncol(df1)) 
rngs[cols] <- sapply(df1[cols], function(x) max(x, na.rm=TRUE) - min(x, na.rm=TRUE)) 

daisyDist <- as.matrix(daisy(df1,metric="gower")) 
gowerDist <- gower.dist(df1) 

daisyDist 
      112457  94601  78273  59172 117425  60656  66897 130650 
112457 0.0000000 0.3951059 0.6151851 0.7107843 0.6397059 0.6424374 0.3756990 0.1105551 
94601 0.3951059 0.0000000 0.2355126 0.5788530 0.5629176 0.4235379 0.3651002 0.2199324 
78273 0.6151851 0.2355126 0.0000000 0.5122549 0.4033046 0.3500130 0.3951874 0.3631533 
59172 0.7107843 0.5788530 0.5122549 0.0000000 0.2969639 0.5446623 0.4690421 0.5657812 
117425 0.6397059 0.5629176 0.4033046 0.2969639 0.0000000 0.4638003 0.4256891 0.4757460 
60656 0.6424374 0.4235379 0.3500130 0.5446623 0.4638003 0.0000000 0.5063082 0.4272755 
66897 0.3756990 0.3651002 0.3951874 0.4690421 0.4256891 0.5063082 0.0000000 0.2900150 
130650 0.1105551 0.2199324 0.3631533 0.5657812 0.4757460 0.4272755 0.2900150 0.0000000 

gowerDist 
      [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8] 
[1,] 0.0000000 0.3951059 0.6151851 0.7107843 0.6397059 0.6424374 0.3756990 0.1105551 
[2,] 0.3951059 0.0000000 0.2355126 0.5788530 0.5629176 0.4235379 0.3651002 0.2199324 
[3,] 0.6151851 0.2355126 0.0000000 0.5122549 0.4033046 0.3500130 0.3951874 0.3631533 
[4,] 0.7107843 0.5788530 0.5122549 0.0000000 0.2969639 0.5446623 0.4690421 0.5657812 
[5,] 0.6397059 0.5629176 0.4033046 0.2969639 0.0000000 0.4638003 0.4256891 0.4757460 
[6,] 0.6424374 0.4235379 0.3500130 0.5446623 0.4638003 0.0000000 0.5063082 0.4272755 
[7,] 0.3756990 0.3651002 0.3951874 0.4690421 0.4256891 0.5063082 0.0000000 0.2900150 
[8,] 0.1105551 0.2199324 0.3631533 0.5657812 0.4757460 0.4272755 0.2900150 0.0000000 
+0

친애하는 sandipan, 답장을 보내 주셔서 감사합니다! 숫자 열의 NA를 0으로 설정하면 두 행렬 간의 거리를 비교할 때 결과가 변경되지 않습니까? 내가 읽었을 때 NA가 셀에 존재하면 전체 행에 대해이 거리의 0-1 가중치가 0과 같습니다. 그러나 값 자체가 0이면 거리가 0 이외의 값이고 0-1 가중치가 1이므로 전체 행의 합계에서이 잘못된 거리를 제외하지 않을 수 있습니다. – Vanessa

+0

나는 당신이 말하는 것을 본다. @Vanessa, 나는 더 많은 생각들을 가지고 해결책을 업데이트하자. –

+0

@Vanessa가 수정 된 답변으로 업데이트되었으므로 gower.dist가 제대로 작동하도록 숫자 변수의 범위를 올바르게 지정해야합니다. 그렇지 않으면 이상한 일종의 NAs가 자동으로 제거되지 않습니다. 당신이 질문을 해줘서 다행입니다. –