2017-09-11 42 views
0

私はorg.apache.mahout.common.distance.MahalanobisDistanceMeasureを使って行列の行と平均ベクトルの距離を計算しますが、時にはNaNを返します。デバッグしようとしましたが、NullPointerExceptionがObjectクラスにスローされているようです。しかし、他の行についてはすべてが問題ありません。誰かが私に何か指導を与えることができれば、私は感謝しています。Java - マハラノビスの距離を計算するときにNaNを返す場合があります

import com.opencsv.CSVReader; 

import java.io.FileNotFoundException; 
import java.io.FileReader; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.util.ArrayList; 

import com.opencsv.CSVWriter; 
import org.apache.commons.math.MathException; 
import org.apache.mahout.common.distance.MahalanobisDistanceMeasure; 
import org.apache.mahout.math.*; 
import org.apache.mahout.math.Matrix; 
import org.apache.commons.math3.linear.RealMatrix; 
import org.apache.commons.math3.stat.correlation.Covariance; 
import org.apache.commons.math.distribution.ChiSquaredDistributionImpl; 

public class FindMultivariateOutliers { 
    public static void main(String[] args) { 
     String url = "VIC_20160401_201606301.csv"; 
     double[][] data = extractRealData(readCSV(url), 3); 
     double[][] dataSet = new double[30][49]; 
     for (int i = 30; i < 60; i++) { 
      dataSet[i-30] = data[i]; 
     } 

     double[] mean = calculateMeanVector(dataSet); 
     Vector meanVector = new DenseVector(mean); 
     Matrix covarianceMatrix = covarianceMatrix(dataSet); 

     MahalanobisDistanceMeasure measure = new MahalanobisDistanceMeasure(); 
     measure.setMeanVector(meanVector); 
     measure.setCovarianceMatrix(covarianceMatrix); 

     for (int i = 0; i < dataSet.length; i++) { 
      DenseVector ve = new DenseVector(dataSet[i]); 
      double x = measure.distance(dataSet[centroid(dataSet)[0]][centroid(dataSet)[1]],meanVector,ve); 
      System.out.println(i+" "+x); 
     } 
} 

出力:

0 NaN 
1 NaN 
2 1.3382137932701006 
3 5.140281428741069 
4 5.448118335171329 
5 4.658774790167001 
6 3.055235041048766 
7 5.577659807980593 
8 2.9899726295069784 
9 6.095988936666251 
10 5.188517209151716 
11 3.2929774499538014 
12 5.090550175124932 
13 5.801822265633947 
14 4.714239296215186 
15 5.02905587450129 
16 4.981122780626051 
17 5.195044166268684 
18 5.325097238194922 
19 4.7899888250142375 
20 5.506442897174045 
21 5.266585564849615 
22 5.403384368592266 
23 4.110229775894713 
24 5.960687924915147 
25 4.5745629099807745 
26 5.0580441561885205 
27 5.146058878694013 
28 5.1375323540721425 
29 3.7919178679466015 

重心()、マトリックスの重心を計算する方法であって、intを返し、[2](第1要素は、x座標であり、第二はYです)。 dataSetは私が注目している行列です。

+0

検証可能な例はありますか?あなたのプログラムはファイルからデータを読み込んでいますが、残念ながらそのファイルはありません。おそらく問題のあるデータセットを抽出してコードに入れるだけでしょうか? –

+0

@LukeLeeデータには49の次元があるので、例を示すのは難しいです。私は自分のコードの出力を更新しました。一見することができます。 –

+0

「NaN」が表す値が正または負の無限大とは別のものであることがわからない場合は、「すべてのコンピュータ科学者が浮動小数点演算について知っておくべきこと」(https://docs.oracle.com/)を停止して読んでください。 cd/E19957-01/806-3568/ncg_goldberg.html)。その後、Javadocの 'Double.NaN'、' Double.POSITIVE_INFINITY'と 'Double.NEGATIVE_INFINITY'の定義を見てください。ヒント: 'NaN'は' 0.0d/0.0d'と定義されています。 –

答えて

0

「NaN」は「数字ではありません」を表します。浮動小数点演算(Double/Float)に、何らかの未定義の結果を生成する演算を引き起こす入力パラメータがある場合、 "Nan"が生成されます。たとえば、0.0で割った0.0は算術的に定義されていません。負の数の平方根をとることも未定義です。

NaNはDoubleおよびFloatラッパークラスの静的変数です。シナリオでは数値ではないため、2つの座標の間の距離を測定するとDouble.NaNが返されます。プリミティブナンバーであるため、NullPointerExceptionが発生します。

+1

プリミティブ浮動小数点数はNaN値を保持することができ、NPEはスローされません。 –

+0

これは、double/0.0を計算したコードのスライスがあることを意味しているので、このNaNが出力に表示されますか? –

+0

はい、出力にNaNを与えるコードです。 – vikas

関連する問題