2012-10-03 19 views
11

Tôi đang cố tính toán chuyển đổi tập lệnh R thành java bằng cách sử dụng thư viện apache.commons.math. Tôi có thể sử dụng org.apache.commons.math.analysis.interpolation.LoessInterpolator thay cho R loess không? Tôi không thể nhận được kết quả tương tự.Sự khác biệt giữa R.loess và org.apache.commons.math LoessInterpolator

EDIT.

đây là một chương trình java tạo một mảng ngẫu nhiên (x, y) và tính toán phần tử với LoessInterpolator hoặc bằng cách gọi R. Cuối cùng, kết quả được in.

import java.io.*; 
import java.util.Random; 

import org.apache.commons.math.analysis.interpolation.LoessInterpolator; 


public class TestLoess 
    { 
    private String RScript="/usr/local/bin/Rscript"; 
    private static class ConsummeInputStream 
     extends Thread 
     { 
     private InputStream in; 
     ConsummeInputStream(InputStream in) 
      { 
      this.in=in; 
      } 
     @Override 
     public void run() 
      { 
      try 
       { 
       int c; 
       while((c=this.in.read())!=-1) 
        System.err.print((char)c); 
       } 
      catch(IOException err) 
       { 
       err.printStackTrace(); 
       } 
      } 
     } 
    TestLoess() 
     { 

     } 
    private void run() throws Exception 
     { 
     int num=100; 
     Random rand=new Random(0L); 
     double x[]=new double[num]; 
     double y[]=new double[x.length]; 
     for(int i=0;i< x.length;++i) 
      { 
      x[i]=rand.nextDouble()+(i>0?x[i-1]:0); 
      y[i]=Math.sin(i)*100; 
      } 
     LoessInterpolator loessInterpolator=new LoessInterpolator(
      0.75,//bandwidth, 
      2//robustnessIters 

      ); 
     double y2[]=loessInterpolator.smooth(x, y); 

     Process proc=Runtime.getRuntime().exec(
      new String[]{RScript,"-"} 
      ); 
     ConsummeInputStream errIn=new ConsummeInputStream(proc.getErrorStream()); 
     BufferedReader stdin=new BufferedReader(new InputStreamReader(proc.getInputStream())); 
     PrintStream out=new PrintStream(proc.getOutputStream()); 
     errIn.start(); 
     out.print("T<-as.data.frame(matrix(c("); 
     for(int i=0;i< x.length;++i) 
      { 
      if(i>0) out.print(','); 
      out.print(x[i]+","+y[i]); 
      } 
     out.println("),ncol=2,byrow=TRUE))"); 
     out.println("colnames(T)<-c('x','y')"); 
     out.println("T2<-loess(y ~ x, T)"); 
     out.println("write.table(residuals(T2),'',col.names= F,row.names=F,sep='\\t')"); 
     out.flush(); 
     out.close(); 
     double y3[]=new double[x.length]; 
     for(int i=0;i< y3.length;++i) 
      { 
      y3[i]=Double.parseDouble(stdin.readLine()); 
      } 
     System.out.println("X\tY\tY.java\tY.R"); 
     for(int i=0;i< y3.length;++i) 
      { 
      System.out.println(""+x[i]+"\t"+y[i]+"\t"+y2[i]+"\t"+y3[i]); 
      } 
     } 

    public static void main(String[] args) 
     throws Exception 
     { 
     new TestLoess().run(); 
     } 
    } 

biên soạn & exec:

javac -cp commons-math-2.2.jar TestLoess.java && java -cp commons-math-2.2.jar:. TestLoess 

đầu ra:

X Y Y.java Y.R 
0.730967787376657 0.0 6.624884763714674 -12.5936186703287 
0.9715042030481429 84.14709848078965 6.5263049649584 71.9725380029913 
1.6089216283982513 90.92974268256818 6.269100654071115 79.839773167581 
2.159358633515885 14.112000805986721 6.051308261720918 3.9270340708818 
2.756903911313087 -75.68024953079282 5.818424835586378 -84.9176311089431 
3.090122310789737 -95.89242746631385 5.689740879461759 -104.617807889069 
3.4753114955304554 -27.941549819892586 5.541837854229562 -36.0902352062634 
4.460153035730264 65.6986598718789 5.168028655980764 58.9472823439219 
5.339335553602744 98.93582466233818 4.840314399516663 93.3329030534449 
6.280584733084859 41.21184852417566 4.49531113985498 36.7282165788057 
6.555538699120343 -54.40211108893698 4.395343460231256 -58.5812856445538 
6.68443584999412 -99.99902065507035 4.348559404444451 -104.039069260889 
6.831037507640638 -53.657291800043495 4.295400167908642 -57.5419313320511 
6.854275630124528 42.016703682664094 4.286978656933373 38.1564179414478 
7.401015387322993 99.06073556948704 4.089252482141094 95.7504087842369 
8.365502247999844 65.02878401571168 3.7422883733498726 62.5865641279576 
8.469992934250815 -28.790331666506532 3.704793544880599 -31.145867173504 
9.095139297716374 -96.13974918795569 3.4805388562453574 -98.0047896609079 
9.505935493207435 -75.09872467716761 3.3330472034239405 -76.6664588290508 

các giá trị đầu ra cho y rõ ràng là không giống nhau giữa R và Java; Cột The.R.R có vẻ tốt (gần cột Y ban đầu). Làm thế nào tôi nên thay đổi điều này để có được Y.java ~ Y.R?

+1

có thể thêm 'span = 2/3' vào lệnh gọi' loess'? Tôi không biết nếu 'span' trong' loess' giống với tham số 'bandwidth' trong 'LoessInterpolator', nhưng giá trị mặc định cho 'span' cho' loess' là 0,75 và bạn đặt 'bandwidth' thành 2/3 . –

+0

Cảm ơn tất cả các bạn đã trả lời. Tôi ra khỏi công việc của tôi. Tôi sẽ khám phá các đề xuất của bạn vào ngày mai. – Pierre

+2

Nhận xét nhanh. Tôi chỉ kiểm tra xem việc thực hiện ess (w) ess trong R và Java là giống hệt nhau. Cả lowess() trong R và LoessInterpolator() trong Apache Commons Math đều tham khảo cùng một giấy Cleveland (1979) và có cùng các tham số. Tôi nhận được cùng một phù hợp từ cả hai triển khai. – user2065369

Trả lời

5

Bạn cần thay đổi các giá trị mặc định của ba thông số đầu vào để làm cho các phiên bản Java và R giống hệt nhau:

  1. Java LoessInterpolator chỉ thực hiện hồi quy đa thức địa phương tuyến tính, nhưng R hỗ trợ tuyến tính (độ = 1) , bậc hai (độ = 2), và một mức độ lạ = 0 tùy chọn. Vì vậy, bạn cần phải chỉ định degree=1 trong R giống với Java.

  2. LoessInterpolator mặc định số lần lặp DEFAULT_ROBUSTNESS_ITERS=2, nhưng R mặc định iterations=4. Vì vậy, bạn cần đặt control = loess.control(iterations=X) trong R (X là số lần lặp).

  3. Giá trị mặc định của trình chặn mặc định là DEFAULT_BANDWIDTH=0.3 nhưng giá trị mặc định R span=0.75.

3

Tôi không thể nói cho việc triển khai java, nhưng lowess có một số thông số kiểm soát băng thông phù hợp. Trừ khi bạn đang phù hợp với các thông số kiểm soát tương tự, bạn nên mong đợi kết quả khác nhau. Đề xuất của tôi bất cứ khi nào mọi người làm mịn dữ liệu là vẽ dữ liệu ban đầu cũng như phù hợp và tự quyết định thông số kiểm soát nào mang lại sự cân bằng mong muốn giữa độ trung thực với dữ liệu và làm mịn (còn gọi là xóa tiếng ồn).

1

Có hai vấn đề ở đây. Đầu tiên nếu bạn vẽ dữ liệu bạn tạo ra, nó trông gần như ngẫu nhiên và sự phù hợp được tạo ra bởi loess trong R rất kém, ví dụ:

plot(T$x, T$y) 
lines(T$s, T2$fitted, col="blue", lwd=3) 

plot of the data generated by the Java code above with a loess fit generated by R

Sau đó, trong kịch bản R của bạn bạn đang viết các phần dư không phải là dự đoán như vậy trong dòng này

out.println("write.table(residuals(T2),'', 
    col.names= F,row.names=F,sep='\\t')"); 

bạn cần thay đổi residuals(T2)-predict(T2) ví dụ

out.println("write.table(predict(T2),'', 
    col.names= F,row.names=F,sep='\\t')"); 

Vì vậy, đó là cơ hội thuần túy trong ví dụ mã của bạn rằng hai dòng đầu tiên của số dư tạo ra bởi R có vẻ phù hợp.

Đối với tôi nếu tôi thử kết hợp với một số dữ liệu thích hợp hơn thì Java và R sẽ trả lại kết quả tương tự nhưng không giống nhau. Ngoài ra, tôi thấy kết quả gần hơn nếu tôi không điều chỉnh cài đặt độ mạnh mẽ mặc định mặc định.

Các vấn đề liên quan