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