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 ответа:
Вы также можете проверить пакет
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