    001package org.opengion.penguin.math.statistics;
    002
    003import org.apache.commons.math3.linear.MatrixUtils;
    004import org.apache.commons.math3.linear.RealMatrix;
    005import org.apache.commons.math3.stat.correlation.PearsonsCorrelation;
    006
    007/**
    008 * apache.commons.mathを利用した相関計算及びその周辺機能を利用するためのクラスです。
    009 *
    010 * とりあえず通常のピアソン積率相関のみを利用可能としておきます。
    011 *
    012 */
    013public class HybsCorrelation {
    014        private String[] names;
    015        private double[][] pearsonsMatrix;
    016        private RealMatrix corrMatrix;
    017
    018
    019        /**
    020         * コンストラクタ。
    021         * 与えたデータマトリクスを元にピアソン積率相関を計算します。
    022         * 名称 = { "数学" , "英語", "国語" }
    023         * データ = { { 90 ,60 ,70 }, {70, 90, 80 } }
    024         * のような形としてデータを与えます。
    025         * @param name ラベル
    026         * @param matrix 値のデータ
    027         */
    028        public HybsCorrelation(String[] name, double[][] matrix){
    029                // 一応元データをセットしておく
    030                this.names = name;
    031                this.pearsonsMatrix = matrix;
    032
    033                // ここで相関係数行列を作成してしまう
    034                corrMatrix = (new PearsonsCorrelation()).computeCorrelationMatrix(pearsonsMatrix);
    035        }
    036
    037        /**
    038         * コンストラクタ。
    039         * 計算後の相関係数行列をdouble[][]型で直接与えられるようにしておきます。
    040         * 以前に計算した行列を使って行列の積を算出する場合に利用します。
    041         *
    042         * @param matrix 相関係数行列
    043         */
    044        public HybsCorrelation( double[][] matrix){
    045                corrMatrix = MatrixUtils.createRealMatrix( matrix );
    046        }
    047
    048        /**
    049         * コンストラクタで算出した相関値行列に対して与えた行列を掛け算します。
    050         * 例えば以下のような算出を行う事が可能です。
    051         * 各商品を何回購入したかというデータを人数分用意し、相関係数行列を作成し、
    052         * 　それに対してある人の今まで購入した履歴を掛け算する事で相関の高い商品を導出します。
    053         * 　つまり、購入した事のないもので有意な相関係数を持つものは購入可能性が高いと言えます。
    054         * @param data 掛け算する行列
    055         * @return 行列積の結果マトリクス
    056         */
    057        public double[][] multiply(double[][] data){
    058                RealMatrix dataMatrix = MatrixUtils.createRealMatrix(data);
    059            RealMatrix scores = dataMatrix.multiply(corrMatrix);
    060
    061                return scores.getData();
    062        }
    063
    064        /**
    065         * 相関値行列取得。
    066         * @return 相関マトリクス
    067         */
    068        public double[][] getCorrMatrix(){
    069                return corrMatrix.getData();
    070        }
    071
    072        /**
    073         * 指定行の相関値配列取得。
    074         * @param x ROW番号
    075         * @return 行方向の相関ベクトル
    076         */
    077        public double[] getCorrMatrixRow(int x){
    078                return corrMatrix.getRow(x);
    079        }
    080
    081        /**
    082         * 指定列の相関値配列取得。
    083         * @param x COL番号
    084         * @return 列方向の相関ベクトル
    085         */
    086        public double[] getCorrMatrixCol(int x){
    087                return corrMatrix.getColumn(x);
    088        }
    089
    090        /**
    091         * 名称配列の取得。
    092         * @return 名称配列
    093         */
    094        public String[] getNames(){
    095                return names;
    096        }
    097
    098        /**
    099         * 名称配列のセット。
    100         * @param name 名称配列
    101         */
    102        public void setNames( String[] name){
    103                this.names = name;
    104        }
    105
    106        /*** ここまでが本体 ***/
    107        /*** ここからテスト用mainメソッド ***/
    108        /**
    109         * @param args *****************************************/
    110        public static void main(final String [] args) {
    111                String[] name = {"A", "B", "C", "D","E"};
    112            double[][] data = {
    113              {3, 1, 0, 0 , 1},
    114              {1, 0, 0, 0 , 1},
    115              {0, 0, 2, 2 , 2},
    116              {2, 2, 1, 0 , 0},
    117              {1, 0, 2, 4 , 1},
    118            };
    119
    120                HybsCorrelation rtn = new HybsCorrelation(name,data);
    121
    122                for( int i = 0; i< rtn.getCorrMatrix().length; i++ ){
    123                        System.out.println(java.util.Arrays.toString(rtn.getCorrMatrix()[i]));
    124                }
    125
    126                // オススメ度計算
    127                System.out.println(java.util.Arrays.toString(rtn.multiply( new double[][] { {0, 1, 0, 0 , 0}})[0]));
    128
    129        }
    130}
    131