2014-11-14 99 views
0

今天我試圖調試我的代碼,偶然發現一些讓我的解決方案無用的東西。我通常試圖計算的是以下兩個矩陣的多維L2範數。只要我不使用scale(),一切工作都正常。儘管如此,一旦我縮放矩陣,三種使用方法的解決方案就不再一樣了。我在這裏錯過了什麼?規模問題()和多維Lp規範問題

set.seed(655) 
df.a <- data.frame(A = sample(100:124, 24), B = sample(1:24, 24), C = sample(1:24, 24), D = rep(0, times=24)) 
df.b <- data.frame(A = sample(125:148, 24), B = sample(25:48, 24), C = sample(1:24, 24), D = sample(1:100, 24)) 

爲此,我有三個不同的方法:

  1. sapply功能和rowSums的開方

    sse <- function(x1, x2) sum((x1 - x2)^2) 
    
    distanceChangeByTech <- function(x) { 
        sse(df.a[,x], df.b[,x]) 
    } 
    help1 <- t(data.frame(sapply(colnames(df.a), distanceChangeByTech))) 
    dist_sap <- sqrt(rowSums(help1)) 
    
  2. 使用多維歐幾里得距離RCPP:

    multiEucl <- cxxfunction(signature(x="matrix", y="matrix"), plugin="Rcpp", 
            body=' 
            Rcpp::NumericMatrix dx(x); 
            Rcpp::NumericMatrix dy(y); 
    
            const int N = dx.nrow(); 
            const int M = dx.ncol(); 
    
            double sum = 0; 
    
            for(int i=0; i<N; i++){ 
            for(int j=0; j<M; j++){ 
            sum = sum + pow(dx(i,j) - dy(i,j), 2); 
            } 
            } 
    
            return wrap(sqrt(sum)); 
            ') 
    
  3. 多維LP-規範使用RCPP:

    multiPNorm <- cxxfunction(signature(x="matrix", y="matrix", p="numeric"), plugin="Rcpp", 
            body=' 
            Rcpp::NumericMatrix dx(x); 
            Rcpp::NumericMatrix dy(y); 
            double dp = Rcpp::as<double>(p); 
    
            const int N = dx.nrow(); 
            const int M = dx.ncol(); 
    
            double sum = 0; 
            double rsum = 0; 
    
            for(int i=0; i<N; i++){ 
            for(int j=0; j<M; j++){ 
            sum = sum + pow(abs(dx(i,j) - dy(i,j)), dp); 
            } 
            } 
    
            rsum = pow(sum, 1/dp); 
            return wrap(rsum); 
            ') 
    

當我試圖在此首先運作良好。

> multiEucl(as.matrix(df.a), as.matrix(df.b)) 
[1] 366.1543 
> multiPNorm(as.matrix(df.a), as.matrix(df.b), 2) 
[1] 366.1543 
> sqrt(rowSums(help1)) sapply.colnames.df.a...distanceChangeByTech. 
366.1543 

但只要我縮放矩陣,這是我想要做的,因爲我會做基於這些distancemeasures一個羣集,存在故障。解決方案不再一樣了!這是什麼造成的?我正在使用這些命令進行縮放。

df.a <- as.data.frame(scale(df.a)) 
df.a[is.na(df.a)] <- 0 
df.b <- as.data.frame(scale(df.b)) 
df.b[is.na(df.b)] <- 0 

> multiEucl(as.matrix(df.a), as.matrix(df.b)) 
[1] 12.51781 
> multiPNorm(as.matrix(df.a), as.matrix(df.b), 2) 
[1] 8.944272 
> sqrt(rowSums(help1)) 
sapply.colnames.df.a...distanceChangeByTech. 
            12.51781 

回答

0

看來,abs()在這裏沒有做正確的事情。相反,我改變了我的multiPNorm編碼,這些改變似乎有效。

multiPNorm <- cxxfunction(signature(x="matrix", y="matrix", p="numeric"), plugin="Rcpp", 
         body=' 
         Rcpp::NumericMatrix dx(x); 
         Rcpp::NumericMatrix dy(y); 
         double dp = Rcpp::as<double>(p); 

         const int N = dx.nrow(); 
         const int M = dx.ncol(); 

         double sum = 0; 
         double rsum = 0; 
         double help = 0; 

         for(int i=0; i<N; i++){ 
         for(int j=0; j<M; j++){ 
         help = dx(i,j) - dy(i,j); 
         if (help < 0) { 
          help = - help; 
         } 
         sum = sum + pow(help, dp); 
         } 
         } 

         rsum = pow(sum, 1/dp); 
         return wrap(rsum); 
         ')