Java - иногда возвращает NaN при расчете расстояния Махаланобиса

Я использую org.apache.mahout.common.distance.MahalanobisDistanceMeasure, чтобы вычислить расстояние между строками в матрице и средним вектором, но иногда он возвращает NaN. Я попытался отладить, и кажется, что NullPointerException выбрасывается в классе Object. Но для других рядов все хорошо. Я был бы признателен, если бы кто-то мог дать мне некоторое руководство.

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

centroid () - это метод, который вычисляет центроид матрицы, возвращает int[2](первый элемент - координата x, а второй - y). dataSet - это матрица, на которой я сосредоточен.

1 ответ

"NaN" означает "не число". "Nan" создается, если операция с плавающей запятой (Double/Float) имеет некоторые входные параметры, которые приводят к тому, что операция дает какой-то неопределенный результат. Например, 0,0, деленное на 0,0, арифметически не определено. Получение квадратного корня из отрицательного числа также не определено.

NaN является статической переменной в классах-оболочках Double и Float. Это не числовое значение, поэтому в вашем сценарии, когда вы пытаетесь измерить расстояние между двумя координатами, он возвращает Double.NaN, затем он пытается преобразовать его в примитивное число, чтобы он даст вам исключение NullPointerException.

Другие вопросы по тегам