2017-12-31 81 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 용 주요 Machine 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의 dgemv (herehere)에 직접 전달되고 beta는 스칼라이고, x와 y는 벡터이고, A는m × n 행렬입니다.

충분한 답변을 제공해야합니다.


것이 NNLS -like 계산을위한 스파크 MLlib에 권장되는 방법은 무엇인가 할 또 다른 질문?

Spark MLLib의 ALS 알고리즘 usesNNLS처럼 보이지만 (기계 학습자에게는 그리 놀랄 일이 아닙니다).

ALS가 nonnegative 매개 변수가 사용 설정된 모델을 훈련 시키도록 설정 한 경우 코드의 해당 부분이 사용됩니다. 즉, true (기본적으로 사용 중지됨)입니다.

비 음수 비 - 제약 조건을 적용할지 여부를 지정하는 Param.

기본값 : 음이 아닌 제약 조건을 사용할지 여부를

거짓은 최소 제곱

위해 나는 음이 아닌 선형 회귀 문제를 해결하기위한 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); 
    } 
}