2017-12-31 29 views
0

Ich versuche nicht-negative multiple lineare Regression Problem in Java zu lösen. Und ich fand eine Löserklasse org.apache.spark.mllib.optimization.NNLS in Scala geschrieben. Allerdings weiß ich nicht, wie man das benutzt.Wie NNLS für nicht negative multiple lineare Regression verwenden?

Was mich verwirrt, ist, dass die Schnittstelle der folgenden Methode seltsam scheint. Ich dachte, dass A ist eine MxN-Matrix und b ist ein M-Vektor, und die Argumente ata und atb sollten eine NxN-Matrix bzw. N-Vektor sein. Der tatsächliche Typ ata ist jedoch double[].

Ich suchte nach einem Beispielcode, aber ich konnte nicht finden. Kann mir jemand einen Beispielcode geben? Die Bibliothek ist in Scala geschrieben, aber ich möchte Java-Code, wenn möglich.

Antwort

1

DISCLAIMER Ich habe nie NNLS verwendet und habe keine Ahnung über nicht-negative multiple lineare Regression.

Sie betrachten Spark 2.1.1 NNLS, die das tut, was Sie wollen, aber ist nicht der Weg zu gehen seit the latest Spark 2.2.1 marked as private[spark].

private[spark] object NNLS { 

Noch wichtiger ist, als Spark 2.0, org.apache.spark.mllib Paket (inkl. org.apache.spark.mllib.optimization dass NNLS gehört) ist in maintenance mode:

Die MLlib RDD-basierte API ist jetzt in den Wartungsmodus.

Ab Spark 2.0 sind die RDD-basierten APIs im Paket spark.mllib in den Wartungsmodus gewechselt. Die primäre Machine Learning-API für Spark ist jetzt die DataFrame-basierte API im Paket spark.ml.

Mit anderen Worten, Sie sollten sich von dem Paket und NNLS insbesondere fern bleiben.

Was sind die Alternativen dann?

Sie könnten die Tests von NNLS betrachten, d. H. NNLSSuite wo Sie einige Antworten finden konnten.

Der tatsächliche Typ von ATA ist jedoch doppelt [].

Das ist eine Matrix, so dass die Elemente wieder verdoppelt werden. Als eine Tatsache wird atadgemv direkt an BLAS des bestanden (here und here), die in den LAPACK docs beschrieben:

DGEMV führt eine der Matrix-Vektor

y := alpha*A*x + beta*y, or y := alpha*A**T*x + beta*y, 

Operationen, bei denen alpha und Beta sind Skalare, x und y sind Vektoren und A ist eine m-n-Matrix.

Das sollte Ihnen genug Antworten geben.


Eine andere Frage wäre, was werden die empfohlene Art und Weise in Funken MLlib für NNLS -ähnlichen Berechnungen ist?

Es sieht aus wie Spark MLLib ALS-Algorithmus usesNNLS unter der Decke (was für Maschinen lernen Praktiker nicht so überraschend sein kann).

Dieser Teil des Codes wird verwendet, wenn ALS zum Trainieren eines Modells mit aktiviertem nonnegative-Parameter konfiguriert ist, d. H. true (standardmäßig deaktiviert).

nichtnegativ Param für ob Nichtnegativitätsbedingungen anzuwenden.

Default: false

ob nicht negative Einschränkung für kleinste Quadrate verwenden

Ich würde empfehlen, dass ein Teil der Funken MLlib Überprüfung tiefer in die Verwendungen von NNLS zu bekommen für nicht-negative lineare Regression zur Problemlösung .

+0

Vielen Dank für die detaillierte Beschreibung. 'Mit anderen Worten, Sie sollten weg von der Verpackung und insbesondere NNLS bleiben. Also, sollte ich nicht NNLS im Moment verwenden? Wie auch immer, ich lese [NNLSSuite] (https://github.com/apache/spark/blob/master/mllib/src/test/scala/org/apache/spark/mllib/optimization/NNLSSuite.scala#L27) und festgestellt, dass 'ata' abgeflacht ist. Ich habe einige Testcodes geschrieben und es scheint gut zu funktionieren. Also werde ich es unten posten. – takoyaki9n

+0

_ "Also, sollte ich nicht NNLS im Moment verwenden?" _ Das scheint so. Akzeptieren Sie die Antwort (oder zumindest den Upvote), wenn es geholfen hat. Das wird anderen helfen zu finden, was dir geholfen hat. Vielen Dank! –

0

Ich schrieb einen Testcode. Obwohl ich einige Warnungen wie Failed to load implementation from: com.github.fommil.netlib.NativeSystemBLAS bekam, funktioniert es gut für einfache Fälle, aber beta wird oft 0, wenn m sehr groß ist (ungefähr 3000).

package test; 

import org.apache.spark.mllib.optimization.NNLS; 

public class NNLSTest { 
    public static void main(String[] args) { 
     int n = 6, m = 300; 
     ExampleInMatLabDoc(); 
     AllPositiveBetaNoiseInY(n, m); 
     SomeNegativesInBeta(n, m); 
     NoCorrelation(n, m); 
    } 

    private static void test(double[][] X, double[] y, double[] b) {   
     int m = X.length; int n = X[0].length; 

     double[] Xty = new double[n]; 
     for (int i = 0; i < n; i++) { 
      Xty[i] = 0.0; 
      for (int j = 0; j < m; j++) Xty[i] += X[j][i] * y[j]; 
     } 
     double[] XtX = new double[n * n]; 
     for (int i = 0; i < n; i++) { 
      for (int j = 0; j < n; j++) { 
       XtX[n * i + j] = 0.0; 
       for (int k = 0; k < m; k++) XtX[n * i + j] += X[k][i] * X[k][j]; 
      } 
     } 

     double[] beta = NNLS.solve(XtX, Xty, NNLS.createWorkspace(n)); 
     System.out.println("\ntrue beta\tbeta"); 
     for (int i = 0; i < beta.length; i++) System.out.println(b[i] + "\t" + beta[i]); 

    } 

    private static void ExampleInMatLabDoc() { 
     // https://jp.mathworks.com/help/matlab/ref/lsqnonneg.html 
     double[] y = new double[] { 0.8587, 0.1781, 0.0747, 0.8405 }; 
     double[][] x = new double[4][]; 
     x[0] = new double[] { 0.0372, 0.2869 }; 
     x[1] = new double[] { 0.6861, 0.7071 }; 
     x[2] = new double[] { 0.6233, 0.6245 }; 
     x[3] = new double[] { 0.6344, 0.6170 }; 
     double[] b = new double[] { 0.0, 0.6929 }; 
     test(x, y, b); 
    } 

    private static void AllPositiveBetaNoiseInY(int n, int m) { 
     double[] b = new double[n]; 
     for (int i = 0; i < n; i++) b[i] = Math.random() * 100.0;  // random value in [0:100] 
     double[] y = new double[m]; 
     double[][] x = new double[m][]; 
     for (int i = 0; i < m; i++) { 
      x[i] = new double[n]; 
      x[i][0] = 1.0; 
      y[i] = b[0]; 
      for (int j = 1; j < n; j++) { 
       x[i][j] = (2.0 * Math.random() - 1.0) * 100.0; // random value in [-100:100] 
       y[i] += x[i][j] * b[j]; 
      } 
      y[i] *= 1.0 + (2.0 * Math.random() - 1.0) * 0.1; // add noise 
     } 
     test(x, y, b); 
    } 

    private static void SomeNegativesInBeta(int n, int m) { 
     double[] b = new double[n]; 
     for (int i = 0; i < n; i++) b[i] = (2.0 * Math.random() - 1.0) * 100.0; // random value in [-100:100] 
     double[] y = new double[m]; 
     double[][] x = new double[m][]; 
     for (int i = 0; i < m; i++) { 
      x[i] = new double[n]; 
      x[i][0] = 1.0; 
      y[i] = b[0]; 
      for (int j = 1; j < n; j++) { 
       x[i][j] = (2.0 * Math.random() - 1.0) * 100.0; // random value in [-100:100] 
       y[i] += x[i][j] * b[j]; 
      } 
     } 
     test(x, y, b); 
    } 

    private static void NoCorrelation(int n, int m) { 
     double[] y = new double[m]; 
     double[][] x = new double[m][]; 
     for (int i = 0; i < m; i++) { 
      x[i] = new double[n]; 
      x[i][0] = 1.0; 
      for (int j = 1; j < n; j++) 
       x[i][j] = (2.0 * Math.random() - 1.0) * 100.0; // random value in [-100:100] 
      y[i] = (2.0 * Math.random() - 1.0) * 100.0; 
     } 
     double[] b = new double[n]; 
     for (int i = 0; i < n; i++) b[i] = 0; 
     test(x, y, b); 
    } 
} 
Verwandte Themen