2013-04-01

NetBeans IDE で Commons Math を試す

Cmmons Math a. は 、Apache のトッププロジェクトである Apache Commons にある Apache Commons#Commons Proper に属する、数学と統計学の軽量コンポーネントです b.Apache License Version 2.0 に従って配布されています。いろいろなコンポーネントを利用できますが、まずは、今までの流れで多項式係数を最小二乗法で求めてみます。

JLAPACK の時と同じサンプル、100000 組の xy が対になっているデータ fdata01.zip (fdata01.txt) を使って、JLAPACK の時と同じように c.、次の 4 次の多項式でフィッティングするために、その係数 c0,  c1,  c2,  c3,  c4 を最小二乗法で求めます。

y = c0 + c1x + c2x2 + c3x3 + c4x4

使用環境

  • OS : Fedora 18 (Linux)
  • JDK : jdk-1.7.0_17-fcs.x86_64
  • IDE : NetBeans IDE 7.3

以下が Commons Math を利用したサンプルプログラムです。なお、使用した Commons Math は Version 3.1.1 (09 January 2013) です。なお、Java 1.5 以上が必要です。

package commonsmathtest;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import org.apache.commons.math3.stat.regression.OLSMultipleLinearRegression;

public class CommonsMathTest {

    public static void main(String[] args) {
        int m = 100000, n = 5;
        double X[][], y[];
        X = new double[m][n];
        y = new double[m];

        File file = new File("/home/bitwalk/work/ex101_01/fdata01.txt");

        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            String str;
            int i = 0;
            while ((str = br.readLine()) != null) {
                double xValue = Double.parseDouble(str.substring(0, 6));
                y[i] = Double.parseDouble(str.substring(6, 20));
                for (int j = 0; j < n; j++) {
                    X[i][j] = Math.pow(xValue, (double) j);
                }
                i++;
            }
            br.close();
        } catch (FileNotFoundException e) {
            System.out.println(e);
        } catch (IOException e) {
            System.out.println(e);
        }

        OLSMultipleLinearRegression regression = new OLSMultipleLinearRegression();
        regression.setNoIntercept(true);
        regression.newSampleData(y, X);

        double[] c = regression.estimateRegressionParameters();
//        double[] residuals = regression.estimateResiduals();
//        double[][] parametersVariance = regression.estimateRegressionParametersVariance();
//        double regressandVariance = regression.estimateRegressandVariance();
        double rSquared = regression.calculateRSquared();
//        double sigma = regression.estimateRegressionStandardError();

        // Result
        System.out.println("# of DATA\t" + m);
        System.out.println("Coefficients");
        for (int j = 0; j < n; j++) {
            System.out.println("C(" + j + ") =  " + c[j]);
        }
        System.out.println("R-squared = " + rSquared);
    }
}

この線形重回帰式を求めるクラスでは、デフォルトでは切片項 c0 = c0 × x0x0 をモデル行列 X に含める必要はありません。含める場合は、setNoIntercepttrue にする必要があります d.。このサンプルでは他のサンプルとやり方を揃えるために true としています。

実行例を以下に示しました。ここでは R2 (決定係数)も計算しています。

run:
# of DATA 100000
Coefficients
C(0) =  37.76585776133079
C(1) =  0.04968384703750148
C(2) =  6.988983959849906E-6
C(3) =  -4.217424916004741E-7
C(4) =  2.686562674530066E-10
R-squared = 0.7654053656031088
ビルド成功(合計時間: 1秒)

同じ次数で比較した場合、JAMA より時間がかかっているように見えますが、n を大きくすると(すなわち、多項式の次数を大きくすると)計算速度に違いが見られ、JAMA よりは速いが、JLAPACK には劣ると言ったところです。しかし、線形問題ばかりでなく、他の機能もいろいろと揃っているので使い甲斐がありそうです。

参考サイト

  1. Commons Math: The Apache Commons Mathematics Library
  2. Apache Commons Math
  3. NetBeans IDE で JLAPACK を試す (2)
  4. The Commons Math User Guide - Statistics 1.5 Multiple linear regression
  5. bitWalk's workshop - CommonsMath

0 件のコメント: