Frage

Ich versuche, die Konvertierung eines R-Skripts in Java mit dem zu berechnen Apache.Commons.Mathematik Bibliothek.Kann ich verwenden Organisierungstafel.Apache.Commons.Mathematik.Analyse.Interpolation.Lössinterpolator anstelle von R Löss ?Ich kann nicht das gleiche Ergebnis erzielen.

BEARBEITEN.

hier ist ein Java-Programm, das ein zufälliges Array (x, y) erstellt und den Löss mit dem Lössinterpolator oder durch Aufrufen von R berechnet.Am Ende werden die Ergebnisse gedruckt.

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();
        }
    }

kompilierung & Ausführung:

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

Ausgabe:

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

die Ausgabewerte für y sind zwischen R und Java eindeutig nicht gleich;Sie.Die R-Spalte sieht gut aus (sie liegt nahe an der ursprünglichen Y-Spalte).Wie soll ich das ändern, um zu bekommen Y.java - J.R. ?

War es hilfreich?

Lösung

Sie müssen die Standardwerte von drei Eingabeparametern ändern, um die Java- und R-Versionen identisch zu machen:

  1. Der Java-Lössinterpolator führt nur eine lineare lokale Polynomregression durch, aber R unterstützt lineare (Grad = 1), quadratische (Grad = 2) und eine seltsame Option Grad = 0.Sie müssen also angeben degree=1 in R identisch mit Java zu sein.

  2. Lössinterpolator gibt die Anzahl der Iterationen vor DEFAULT_ROBUSTNESS_ITERS=2, aber R ist standardmäßig iterations=4.Sie müssen also einstellen control = loess.control(iterations=X) in R (X ist die Anzahl der Iterationen).

  3. Lössinterpolator-Standardwerte DEFAULT_BANDWIDTH=0.3 aber R ist standardmäßig span=0.75.

Andere Tipps

Ich kann nicht für die Java-Implementierung sprechen, aber lowess hat eine Reihe von Parametern, die die Bandbreite der Anpassung steuern.Sofern Sie nicht mit denselben Steuerparametern anpassen, sollten Sie erwarten, dass sich die Ergebnisse unterscheiden.Meine Empfehlung bei der Glättung von Daten ist, sowohl die Originaldaten als auch die Anpassung zu zeichnen und selbst zu entscheiden, welche Steuerparameter den gewünschten Kompromiss zwischen der Genauigkeit der Daten und der Glättung (auch Rauschentfernung genannt) ergeben.

Hier gibt es zwei Probleme.Erstens, wenn Sie die von Ihnen erzeugenden Daten aufzeichnen, sieht es fast zufällig aus, und der von Löss-in R erzeugte Fit ist sehr arm, z. B.

generasacodicetagpre.

Diagramm der Daten, die vom Java-Code oben mit einem von R

erzeugten Lösssitz erzeugt werden.

Dann schreiben Sie in Ihrem R-Skript die Residuen nicht die Vorhersagen in dieser Linie

generasacodicetagpre.

Sie müssen den generationspflichtigen Code in den residuals(T2) ändern.

generasacodicetagpre.

Es war also reiner Chance in Ihrem Codebeispiel, dass die ersten paar von R-RES-Linien von R, die von R erzeugt wurden, eine gute Passform aussah.

Für mich, wenn ich versuche, mit einigen geeigneteren Daten einzustellen, dann kehren Java und R ähnliche, aber nicht identische Ergebnisse zurück.Ich fand auch, dass die Ergebnisse näher waren, wenn ich die Standardeinstellungen Robustnessiter nicht an eingestellt habe.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top