Domanda

Sto cercando di calcolare la converti uno script r su Java utilizzando la libreria Apache.com.math . Posso usare org.apache. commons.math.analysysis.interpolation.loessinterpolator al posto di r loess ? Non riesco a ottenere lo stesso risultato.

Modifica .

Ecco un programma Java che crea un array casuale (x, y) e calcola la Loess con Loessinterpoolator o chiamando R. Alla fine, i risultati vengono stampati.

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

Compilation & Exec:

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

Uscita:

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
.

I valori di uscita per Y sono chiaramente non uguali tra R e Java; They.hr. La colonna sembra buona (è vicino alla colonna Y originale). Come dovrei cambiarlo per ottenere y.java ~ y.r?

È stato utile?

Soluzione

È necessario modificare i valori predefiniti di tre parametri di input per rendere identiche le versioni Java e R:

    .
  1. Il java loessinterpolator è solo la regressione polinomiale locale lineare, ma R supporta lineare (grado= 1), quadratico (grado= 2) e uno strano grado= 0 opzione.Quindi è necessario specificare degree=1 in R per essere identici a Java.

  2. Loessinterpoolator Defaults Numero di valori predefiniti di Iterazioni DEFAULT_ROBUSTNESS_ITERS=2, ma R Default iterations=4.Quindi è necessario impostare control = loess.control(iterations=X) in R (X è il numero di iterazioni).

  3. Loessinterpoolator Default generatoDicetagCode ma è il valore predefinito DEFAULT_BANDWIDTH=0.3.

Altri suggerimenti

Non posso parlare per l'implementazione Java, ma lowess ha un numero di parametri che controllano la larghezza di banda della vestibilità.A meno che non si adatti con gli stessi parametri di controllo che dovresti aspettarti che i risultati differiscano.La mia raccomandazione ogni volta che le persone stanno levigando i dati è di tracciare i dati originali e la vestibilità, e decidere per te quali parametri di controllo producono il compromesso desiderato tra fedeltà ai dati e levigatura (aka rimozione del rumore).

Ci sono due problemi qui.Innanzitutto Se traccia i dati che stai generando sembra quasi casuale e la vestibilità generata da Loess in R è molto scarsa E.G.

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

Trama dei dati generati dal codice Java sopra con una vestibilità di Loess generata da R

Poi nella tua script r stai scrivendo i residui non le previsioni così in questa riga

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

È necessario modificare residuals(T2) in predict(T2) E.G.

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

Così è stata pura possibilità nel tuo esempio di codice che la prima coppia di linee di residui generate da r sembrava una buona misura.

Per me se provo ad accedere con alcuni dati più appropriati, allora Java e R restituiscono risultati simili ma non identici.Inoltre ho trovato i risultati sono stati più vicini se non ho regolato le impostazioni predefinite robustiter .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top