値のグループのカーネル密度推定に apache commons math を使用しようとしています。たまたま 1 つのビンに 1 つの値しかないため、cumulativeProbability() を呼び出そうとすると、NotStrictlyPositiveException が発生します。これを防ぐ方法はありますか?すべてのビンに少なくとも 1 つの値があるかどうかはわかりません。
ありがとう。
値のグループのカーネル密度推定に apache commons math を使用しようとしています。たまたま 1 つのビンに 1 つの値しかないため、cumulativeProbability() を呼び出そうとすると、NotStrictlyPositiveException が発生します。これを防ぐ方法はありますか?すべてのビンに少なくとも 1 つの値があるかどうかはわかりません。
ありがとう。
ディストリビューションの 1 つで同じエラーが発生します。
このクラスの Javadoc を読むと、次のように書かれています。
USAGE NOTES:
The binCount is set by default to 1000. A good rule of thumb
is to set the bin count to approximately the length of the input
file divided by 10.
EmpiricalDistribution
初期データ長の 10% に等しい binCount で初期化したところ、すべて正常に動作しています。
double[] baseLine = getBaseLineValues();
...
// Initialise binCount
distribution = new EmpiricalDistribution(baseLine.length/10);
// Load base line data
distribution.load(baseLine);
// Now you can obtain random values based on this distribution
double randomValue = distribution.getNextValue();
このバグがまだ残っていることを考慮して、ガイドラインに従ってEmpiricalDistribution
クラスの独自の実装を作成しました。必要な機能、つまり分布のエントロピーの計算のみを再実装しましたが、必要に応じて簡単に拡張できます。
public class EmpiricalDistribution {
private double[] values;
private int[] binCountArray;
private double maxValue, minValue;
private double mean, stDev;
public EmpiricalDistribution(double[] values) {
this.values = values;
int binCount = NumberUtil.roundToClosestInt(values.length / 10.0);
binCountArray = new int[binCount];
maxValue = Double.NEGATIVE_INFINITY;
minValue = Double.POSITIVE_INFINITY;
for (double value : values) {
if (value > maxValue) maxValue = value;
if (value < minValue) minValue = value;
}
double binRange = (maxValue - minValue) / binCount;
for (double value : values) {
int bin = (int) ((value - minValue) / binRange);
bin = Math.min(binCountArray.length - 1, bin);
binCountArray[bin]++;
}
mean = (new Mean()).evaluate(values);
stDev = (new StandardDeviation()).evaluate(values, mean);
}
public double getEntropy() {
double entropy = 0;
for (int valuesInBin : binCountArray) {
if (valuesInBin == 0) continue;
double binProbability = valuesInBin / (double) values.length;
entropy -= binProbability * FastMath.log(2, binProbability);
}
return entropy;
}
public double getMean() {
return mean;
}
public double getStandardDeviation() {
return stDev;
}
}