001/*
002 * Copyright (c) 2009 The openGion Project.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013 * either express or implied. See the License for the specific language
014 * governing permissions and limitations under the License.
015 */
016package org.opengion.penguin.math.statistics;
017
018import java.util.Arrays;
019import org.apache.commons.math3.stat.regression.SimpleRegression;
020
021/**
022 * apache.commons.mathを利用した線形単回帰計算のクラスです。
023 * f(x)=ax+bの形で線形回帰を行います。
024 */
025public class HybsSimpleRegression implements HybsRegression {
026        private final double[] cnst = new double[3] ;           // 係数(0次、1次、2次は常に0)
027
028        private double rsquare;         // 決定係数
029
030        /**
031         * コンストラクタ。
032         * 与えた二次元データを元に回帰直線を計算します。
033         * {x,y}の配列でデータを与えます。
034         *
035         * @param data xとyの組み合わせの配列
036         */
037        public HybsSimpleRegression( final double[][] data ) {
038                // ここで単回帰計算
039                train( data );
040        }
041
042        /**
043         * dataを与えて回帰直線を求める。
044         *
045         * @param data {x,y}の配列
046         */
047        private void train( final double[][] data ) {
048                final SimpleRegression regression = new SimpleRegression();
049                regression.addData( data );
050
051                cnst[2] = 0 ;                                                   // 2次係数は、常に0
052                cnst[1] = regression.getSlope();
053                cnst[0] = regression.getIntercept();
054
055                rsquare = regression.getRSquare();
056        }
057
058        /**
059         * 決定係数の取得。
060         *
061         * @return 決定係数
062         */
063        @Override
064        public double getRSquare() {
065                return rsquare;
066        }
067
068        /**
069         * 係数(0次、1次、2次は常に0)の順にセットした配列を返します。
070         *
071         * @return 係数の配列
072         */
073        @Override
074        public double[] getCoefficient() {
075                return Arrays.copyOf( cnst,cnst.length );
076        }
077
078        /**
079         * a + bxを計算。
080         *
081         * @param in_x 必要な大きさの変数配列
082         * @return 計算結果
083         */
084        @Override
085        public double predict( final double... in_x ) {
086                return cnst[1] * in_x[0] + cnst[0];
087        }
088
089        // ================ ここまでが本体 ================
090
091        /**
092         * ここからテスト用mainメソッド 。
093         *
094         * @param args 引数
095         */
096        public static void main( final String[] args ) {
097                final double[][] data = {{1, 2.3}, {2, 3.4}, {3, 6.1}, {4, 8.2}};
098
099                final HybsSimpleRegression sr = new HybsSimpleRegression(data);
100
101                final double[] cnst = sr.getCoefficient();
102
103                System.out.println(cnst[2]);
104                System.out.println(cnst[1]);
105                System.out.println(cnst[0]);
106
107                System.out.println(sr.predict( 5 ));
108        }
109}
110