Diferencia entre R. loess y org.apache.commons.matemáticas LoessInterpolator
-
13-12-2019 - |
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 ?
Solución
Necesita cambiar los valores predeterminados de tres parámetros de entrada para que el Java y R versiones idénticas:
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.LoessInterpolator valores predeterminados número de iteraciones
DEFAULT_ROBUSTNESS_ITERS=2
, pero R valores predeterminadositerations=4
.Por lo que necesita para establecercontrol = loess.control(iterations=X)
en R (X es el número de iteraciones).LoessInterpolator valores predeterminados
DEFAULT_BANDWIDTH=0.3
pero R valores predeterminadosspan=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)
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.