    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] ;           // 係数(０次、１次、２次は常に０)
    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 ;                                                   // ２次係数は、常に０
    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         * 係数(０次、１次、２次は常に０)の順にセットした配列を返します。
    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