Cmmons Math a. は 、Apache のトッププロジェクトである Apache Commons にある Apache Commons#Commons Proper に属する、数学と統計学の軽量コンポーネントです b.。Apache License Version 2.0 に従って配布されています。いろいろなコンポーネントを利用できますが、まずは、今までの流れで多項式係数を最小二乗法で求めてみます。
JLAPACK の時と同じサンプル、100000 組の x と y が対になっているデータ 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 × x0 の x0 をモデル行列 X に含める必要はありません。含める場合は、setNoIntercept を true にする必要があります 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 には劣ると言ったところです。しかし、線形問題ばかりでなく、他の機能もいろいろと揃っているので使い甲斐がありそうです。
0 件のコメント:
コメントを投稿