001package org.opengion.penguin.math.statistics;
002
003import org.apache.commons.math3.stat.regression.SimpleRegression;
004
005/**
006 * apache.commons.mathを利用した線形単回帰計算のクラスです。
007 * f(x)=ax+bの形で線形回帰を行います。
008 */
009public class HybsSimpleRegression implements HybsRegression {
010        private double slope;           // 傾き
011        private double intercept;       // 切片
012        private double rsquare;         // 決定係数
013                
014        /**
015         * コンストラクタ。
016         * 与えた二次元データを元に回帰直線を計算します。
017         * {x,y}の配列でデータを与えます。
018         * @param data xとyの組み合わせの配列
019         */
020        public HybsSimpleRegression(final double[][] data){
021                // ここで単回帰計算
022                train(data);
023        }
024        
025        /**
026         * コンストラクタ。
027         * 計算後の傾き、切片を与えられるようにしておきます。
028         * (以前に計算したものを利用)
029         * @param slope 
030         * @param intercept 
031         * 
032         */
033        public HybsSimpleRegression( final double slope, final double intercept ){
034                this.slope = slope;
035                this.intercept = intercept;
036        }
037        
038        /**
039         * コンストラクタ
040         * このコンストラクタを利用した場合はtrainを実施して学習するか、setCoefficientで係数をセットする。
041         */
042        public HybsSimpleRegression(){
043                //何もしない
044        }
045        
046        /**
047         * dataを与えて回帰直線を求める。
048         * 
049         * @param data x,yの配列
050         */
051        public void train(final double[][] data){
052                SimpleRegression regression = new SimpleRegression();
053                regression.addData(data);
054                slope = regression.getSlope();
055                intercept = regression.getIntercept();
056                rsquare = regression.getRSquare();
057        }
058        
059        /**
060         * このクラスでは未使用。
061         * 
062         * @param opt オプション
063         */
064        public void setOption(final double[] opt){
065                // 特にオプションなし
066        }
067        
068        /**
069         * 傾きの取得。
070         * @return 傾き
071         */
072        public double getSlope(){
073                return slope;
074        }
075        
076        /**
077         * 切片の取得。
078         * @return 切片
079         */
080        public double getIntercept(){
081                return intercept;
082        }
083        
084        /**
085         * 決定係数の取得。
086         * @return 決定係数
087         */
088        public double getRSquare(){
089                return rsquare;
090        }
091        
092        /**
093         * 傾き、切片、決定係数の順にセットした配列を返します。
094         * @return 係数の配列
095         */
096        public double[] getCoefficient(){
097                double[] rtn = {slope,intercept,rsquare};
098                return rtn;
099        }
100        
101        /**
102         * 傾き、切片の順に配列の内容をセットします。
103         * 3番目に決定係数が入っていても無視します。
104         * 
105         * @param c 係数配列
106         */
107        public void setCoefficient(final double[] c){
108                slope = c[0];
109                intercept = c[1];
110        }
111        
112        /**
113         * a + bxを計算。
114         * @param in_x 変数X
115         * @return 計算結果
116         */
117        public double predict(final double... in_x){
118                return intercept + slope * in_x[0];
119        }
120
121        /*** ここまでが本体 ***/
122        /*** ここからテスト用mainメソッド ***/
123        /**
124         * @param args *****************************************/
125        public static void main(final String [] args) {
126                double[][] data = {{1, 2.3}, {2, 3.4}, {3, 6.1}, {4, 8.2}}; 
127                
128                
129                HybsSimpleRegression sr = new HybsSimpleRegression(data);
130                System.out.println(sr.getIntercept());
131                System.out.println(sr.getSlope());
132                System.out.println(sr.getRSquare());
133                
134                System.out.println(sr.predict( 5 ));
135        }
136}
137