ArrayList を検索して、「適切な値」の一般的な範囲外の値を検出できるコードを考えようとしています。
例: 100 105 102 13 104 22 101
(この場合) 13 と 22 が約 100 の「適切な値」に収まらないことを検出するコードを作成するにはどうすればよいでしょうか?
外れ値を検出する基準はいくつかあります。ショーヴネの基準のような最も単純なものは、サンプルから計算された平均と標準偏差を使用して、値の「正常な」範囲を決定します。この範囲外の値は異常値と見なされます。
他の基準はGrubb の検定とDixon の Q 検定であり、たとえばサンプルが歪んだ分布からのものである場合、Chauvenet の Q 検定よりも良い結果が得られる可能性があります。
このアルゴリズムを使用します。このアルゴリズムは、平均と標準偏差を使用します。これらの 2 つの数値オプション値 (2 * standardDeviation)。
public static List<int> StatisticalOutLierAnalysis(List<int> allNumbers)
{
if (allNumbers.Count == 0)
return null;
List<int> normalNumbers = new List<int>();
List<int> outLierNumbers = new List<int>();
double avg = allNumbers.Average();
double standardDeviation = Math.Sqrt(allNumbers.Average(v => Math.Pow(v - avg, 2)));
foreach (int number in allNumbers)
{
if ((Math.Abs(number - avg)) > (2 * standardDeviation))
outLierNumbers.Add(number);
else
normalNumbers.Add(number);
}
return normalNumbers;
}
Map
数値を平均からの距離にマッピングする を作成しますn
数を微分し、距離に不公平がないことを確認しますこれは、数値が範囲外の情報を取得する非常に単純な実装です。
List<Integer> notInRangeNumbers = new ArrayList<Integer>();
for (Integer number : numbers) {
if (!isInRange(number)) {
// call with a predefined factor value, here example value = 5
notInRangeNumbers.add(number, 5);
}
}
さらに、isInRange
メソッド内で、 「適切な値」の意味を定義する必要があります。以下に、実装例を示します。
private boolean isInRange(Integer number, int aroundFactor) {
//TODO the implementation of the 'in range condition'
// here the example implementation
return number <= 100 + aroundFactor && number >= 100 - aroundFactor;
}