Unterschied zwischen R.Löss und org.Apache.Commons.mathe Lössinterpolator
-
13-12-2019 - |
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. ?
Lösung
Sie müssen die Standardwerte von drei Eingabeparametern ändern, um die Java- und R-Versionen identisch zu machen:
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.Lössinterpolator gibt die Anzahl der Iterationen vor
DEFAULT_ROBUSTNESS_ITERS=2
, aber R ist standardmäßigiterations=4
.Sie müssen also einstellencontrol = loess.control(iterations=X)
in R (X ist die Anzahl der Iterationen).Lössinterpolator-Standardwerte
DEFAULT_BANDWIDTH=0.3
aber R ist standardmäßigspan=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.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.
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.