R-вычислить разницу (меру сходства) между похожими наборами данных


Я видел много вопросов, которые касаются этой темы, но пока не нашел ответа. Если я пропустил вопрос, который действительно отвечает на этот вопрос, пожалуйста, отметьте это и укажите нам на вопрос.

Сценарий: у нас есть эталонный набор данных, у нас есть методы вменения, мы систематически удаляем значения из эталона и используем два различных метода вменения. Таким образом, мы имеем эталон, imputedData1 и imputedData2.

Вопрос: существует ли функция, которая может произвести число, представляющее собой разницу между эталоном и imputedData1 или / и разницу между эталоном и imputedData2. Т. е. функция (benchmark, imputedData1) = 3.3 и функция (benchmark, imputedData2) = 2.8

Примечание: наборы данных являются числовыми, наборы данных имеют одинаковый размер, метод должен работать на уровне данных, если это возможно (т. е. не создавать регрессию и сравнивать регрессии - если только он не может работать с любым числовым набором данных).

Воспроизводимые наборы данных, они имеют изменено только в первом ряду:

Бенчмарк:

> head(mtcars,n=10)
                   mpg cyl  disp  hp drat    wt  qsec vs am gear carb
Mazda RX4         21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag     21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
Datsun 710        22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive    21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
Valiant           18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
Duster 360        14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
Merc 240D         24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
Merc 230          22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
Merc 280          19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4

ImputedData1:

> head(mtcars,n=10)
                   mpg cyl  disp  hp drat    wt  qsec vs am gear carb
Mazda RX4         22.0   4 108.0 100 3.90 2.200 16.46  0  1    4    4
Mazda RX4 Wag     21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
Datsun 710        22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive    21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
Valiant           18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
Duster 360        14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
Merc 240D         24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
Merc 230          22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
Merc 280          19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4

ImputedData2:

> head(mtcars,n=10)
                   mpg cyl  disp  hp drat    wt  qsec vs am gear carb
Mazda RX4         18.0   6 112.0 105 3.90 2.620 16.46  0  0    3    4
Mazda RX4 Wag     21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
Datsun 710        22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive    21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
Valiant           18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
Duster 360        14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
Merc 240D         24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
Merc 230          22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
Merc 280          19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4

Я пытался использовать RMSE (root mean squared error), но это не очень хорошо работало, поэтому я пытаюсь найти другие способы решения этой проблемы.

4 2

4 ответа:

Вы также можете проверить пакет ftsa. Он имеет около 20 мер погрешности , которые могут быть вычислены. В вашем случае масштабируемая ошибка будет иметь смысл, поскольку единицы измерения отличаются от столбца к столбцу.

library(ftsa)
error(forecast=unlist(imputedData1),true=unlist(bench), 
          insampletrue = unlist(bench), method = "mase")
[1] 0.035136

error(forecast=unlist(imputedData2),true=unlist(bench), 
          insampletrue = unlist(bench), method = "mase")
[1] 0.031151

Данные

bench <- read.table(text='mpg cyl  disp  hp drat    wt  qsec vs am gear carb
21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4',header=TRUE,stringsAsFactors=FALSE)

imputedData1 <- read.table(text='mpg cyl  disp  hp drat    wt  qsec vs am gear carb
22.0   4 108.0 100 3.90 2.200 16.46  0  1    4    4
21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4',header=TRUE,stringsAsFactors=FALSE)

imputedData2 <- read.table(text='mpg cyl  disp  hp drat    wt  qsec vs am gear carb
18.0   6 112.0 105 3.90 2.620 16.46  0  0    3    4
21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4',header=TRUE,stringsAsFactors=FALSE)

Один из возможных способов-вычислить норму их разности и предпочесть метод вменения, который минимизирует это значение. Существуют различные матричные нормы для различных целей. Я укажу вам на Википедию в качестве отправной точки - https://en.wikipedia.org/wiki/Matrix_norm .

В отсутствие каких-либо конкретных сведений о ваших данных я не могу точно сказать, что вы должны выбрать, но один из методов может заключаться в создании собственного индекса, который усредняет различные нормы матрицы и выберите метод вменения, который минимизирует это среднее значение. Или вы можете просто посмотреть на них, и если повезет, один из методов будет явным победителем в большинстве или во всех матричных нормах.

Простая реализация того, что обсуждалось в комментариях, которая дает результат с тем же порядком величины, что и ответ P Лапуэнта, просто FYI.

library(magrittr)
center_and_reduce_df <- function(df,bm){
  centered <- mapply('-',df,sapply(bm,mean)) %>% as.data.frame(stringsAsFactors= FALSE)
  reduced <- mapply('/',centered,sapply(bm,sd)) %>% as.data.frame(stringsAsFactors= FALSE)
}
mean((center_and_reduce_df(id1,bm) - center_and_reduce_df(bm,bm))^2) # 0.03083166

Не совсем понятно, что вы подразумеваете под" разницей", но если вы просто хотите знать, насколько каждая ячейка отличается от каждой ячейки в среднем (учитывая, что матрицы имеют одинаковую форму и имеют индентичные cols/rows), вы можете сделать абсолютную разность, или использовать евклидово расстояние, или расстояние Колмогорова-Смирнова - опять же в зависимости от того, что вы подразумеваете под"разницей".

abs(head(mtcars) - (head(mtcars)*0.5)) # differences by cell
mean( as.matrix(abs(head(mtcars) - (head(mtcars)*0.5)))) # mean abs difference
dist( t(data.frame(as.vector(as.matrix(head(mtcars))), (as.vector(as.matrix(head(mtcars)*0.5)))))) # Euclidean; remove t() to see element by element
ks.test( as.vector(as.matrix(head(mtcars))), (as.vector(as.matrix(head(mtcars)*0.5))))$statistic  # K-S