Differenza tra r.loess e org.apache.commons.math loessinterpoolator
-
13-12-2019 - |
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?
Soluzione
È necessario modificare i valori predefiniti di tre parametri di input per rendere identiche le versioni Java e R:
- .
-
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. -
Loessinterpoolator Defaults Numero di valori predefiniti di Iterazioni
DEFAULT_ROBUSTNESS_ITERS=2
, ma R Defaultiterations=4
.Quindi è necessario impostarecontrol = loess.control(iterations=X)
in R (X è il numero di iterazioni). -
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)
.
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 .