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