Pregunta

Estoy tratando de calcular el convertir a R script de java con el apache.commons.matemáticas biblioteca.Puedo usar org.apache.commons.de matemáticas.análisis.la interpolación.LoessInterpolator en lugar de R loess ?No puedo conseguir el mismo resultado.

EDITAR.

aquí es un programa en java que crea una matriz aleatoria(x,y) y calcular el loess con LoessInterpolator o llamando R.Al final, los resultados se imprimen.

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

compilación & exec:

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

salida:

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

los valores de salida para y claramente no son las mismas entre R y Java;Ellos.R columna se ve bien (está cerca de la original Y de la columna).¿Cómo debo cambiar esto con el fin de obtener Y.java ~ Y. R ?

¿Fue útil?

Solución

Necesita cambiar los valores predeterminados de tres parámetros de entrada para que el Java y R versiones idénticas:

  1. El Java LoessInterpolator sólo no lineal local de regresión polinomial, pero R soporta lineal (grado=1), de segundo grado (grado=2), y un extraño grado=0 opción.Por lo que usted necesita especificar degree=1 en R para ser idéntica a la de Java.

  2. LoessInterpolator valores predeterminados número de iteraciones DEFAULT_ROBUSTNESS_ITERS=2, pero R valores predeterminados iterations=4.Por lo que necesita para establecer control = loess.control(iterations=X) en R (X es el número de iteraciones).

  3. LoessInterpolator valores predeterminados DEFAULT_BANDWIDTH=0.3 pero R valores predeterminados span=0.75.

Otros consejos

No puedo hablar por la implementación de java, pero lowess tiene una serie de parámetros que controlan el ancho de banda de ajuste.A menos que usted es montaje con los mismos parámetros de control debe esperar los resultados difieran.Mi recomendación siempre que las personas son el suavizado de datos para graficar los datos originales, así como el ajuste, y decidir por ti mismo lo que el control de los parámetros de rendimiento deseado equilibrio entre la fidelidad a los datos y suavizado (también conocido como la eliminación de ruido).

Hay dos problemas aquí.En primer lugar, si se hace una gráfica de los datos que se están generando que se ve casi al azar y el ajuste generado por loess en R es muy pobre, por ejemplo,

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

A continuación, en su R guión que está escribiendo los residuos no las predicciones por lo que en esta línea

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

necesita cambiar residuals(T2) a predict(T2) por ejemplo,

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

Así fue pura casualidad en el código de ejemplo que el primer par de líneas de los residuos generados por R lo miró un buen ajuste.

Para mí, si yo trato de montaje con algunos datos más adecuados, a continuación, Java y R ¿volver similares pero no idénticos resultados.También he encontrado los resultados fueron más si yo no ajustar el valor predeterminado robustnessIter los ajustes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top