2017-12-31 67 views
0

私はJavaで非負多重線形回帰問題を解こうとしています。 そして、スカラーで記述されたソルバークラスorg.apache.spark.mllib.optimization.NNLSが見つかりました。 しかし、私はこれを使う方法を知らない。NNLSを非負多重線形回帰に使用するにはどうすればよいですか?

私が混乱させる原因は、次の方法のインターフェイスが奇妙に思えることです。 AはMxN行列であり、bはMベクトルであり、引数ataatbはそれぞれNxN行列とNベクトルでなければならないと考えました。 ただし、ataの実際のタイプはdouble[]です。

public static double[] solve(double[] ata, double[] atb, NNLS.Workspace ws) 

例コードを検索しましたが見つかりませんでした。 誰も私にサンプルコードを教えてもらえますか? ライブラリはScalaで書かれていますが、可能であればJavaコードが必要です。

答えて

1

免責私はNNLSを使用しないと、非負多重線形回帰についてのアイデアを得たことがありません。

Spark 2.1.1のNNLSは、あなたが望むことをしますが、the latest Spark 2.2.1 marked as private[spark]以降に行く方法ではありません。

private[spark] object NNLS { 

さらに重要なことは、スパーク2.0のような、org.apache.spark.mllibパッケージ(税込NNLSが属するorg.apache.spark.mllib.optimization)がmaintenance modeである:

MLlib RDDベースのAPIは、メンテナンスモードになっています。

spark 2.0では、spark.mllibパッケージのRDDベースのAPIがメンテナンスモードに入っています。 Sparkの主要なLearning APIは、Spark.mlパッケージのDataFrameベースのAPIになりました。

つまり、特にパッケージから離れて、NNLSを避けてください。

代わりに何がありますか?

NNLSというテストを見ることができます。答えは、NNLSSuiteです。回答が見つかることがあります。

ただし、実際のataのタイプはdouble []です。

これは要素が再び倍になるように行列です。

dgemvのが

y := alpha*A*x + beta*y, or y := alpha*A**T*x + beta*y, 
行列 - ベクトル演算の一

アルファ実行:実際の問題として、ataLAPACKドキュメントに記載されているBLASのdgemvherehere)に直接渡されます。ベータはスカラー、xとyはベクトル、Aは m×n行列です。

十分な回答が得られるはずです。


もう一つの問題は、NNLS様な計算のSpark MLlibで推奨される方法が何であるかでしょうか?

Spark MLLibのALSアルゴリズムusesNNLSのように見えます(マシン学習実践者にとって驚くべきことではないかもしれません)。

nonnegativeパラメータがオンになっているモデル、つまりtrue(デフォルトでは無効)でALSがモデルをトレーニングするように設定されている場合は、その部分が使用されます。

非負非負制約を適用するかどうかを指定するParam。

デフォルト:false

最小二乗ため

を非負制約を使用するかどうか、私は非負線形回帰問題を解決するためのNNLSの用途に深く得るためにスパークMLlibの一部を見直す推薦します。

+0

ありがとうございました。 「特にパッケージとNNLSから離れてください。」 現時点でNNLSを使用しないでください。 とにかく[NNLSSuite](https://github.com/apache/spark/blob/master/mllib/src/test/scala/org/apache/spark/mllib/optimization/NNLSSuite.scala#L27)と'ata'が平坦化されていることがわかりました。私はいくつかのテストコードを書いており、うまくいくようです。だから私はそれを声に出して掲示するでしょう。 – takoyaki9n

+0

_「現時点でNNLSを使用すべきではないでしょうか?」と思われます。それが助けられたら、答えを受け入れるか(少なくともupvote)。それは他の人があなたを助けたものを見つけるのを助けるでしょう。ありがとう! –

0

私はテストコードを書いた。 Failed to load implementation from: com.github.fommil.netlib.NativeSystemBLASのような警告が表示されますが、単純なケースではうまく動作しますが、mが非常に大きい場合(約3000)、betaは0になることがよくあります。

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); 
    } 
} 
関連する問題