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