Ash*_*ton 4 java arraylist outliers
我正在尝试一些代码,这些代码允许我搜索我的ArrayList并检测"好值"的常见范围之外的任何值.
示例:100 105 102 13 104 22 101
我怎样才能编写代码来检测(在这种情况下)13和22不在100左右的"良好值"范围内?
package test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Double> data = new ArrayList<Double>();
data.add((double) 20);
data.add((double) 65);
data.add((double) 72);
data.add((double) 75);
data.add((double) 77);
data.add((double) 78);
data.add((double) 80);
data.add((double) 81);
data.add((double) 82);
data.add((double) 83);
Collections.sort(data);
System.out.println(getOutliers(data));
}
public static List<Double> getOutliers(List<Double> input) {
List<Double> output = new ArrayList<Double>();
List<Double> data1 = new ArrayList<Double>();
List<Double> data2 = new ArrayList<Double>();
if (input.size() % 2 == 0) {
data1 = input.subList(0, input.size() / 2);
data2 = input.subList(input.size() / 2, input.size());
} else {
data1 = input.subList(0, input.size() / 2);
data2 = input.subList(input.size() / 2 + 1, input.size());
}
double q1 = getMedian(data1);
double q3 = getMedian(data2);
double iqr = q3 - q1;
double lowerFence = q1 - 1.5 * iqr;
double upperFence = q3 + 1.5 * iqr;
for (int i = 0; i < input.size(); i++) {
if (input.get(i) < lowerFence || input.get(i) > upperFence)
output.add(input.get(i));
}
return output;
}
private static double getMedian(List<Double> data) {
if (data.size() % 2 == 0)
return (data.get(data.size() / 2) + data.get(data.size() / 2 - 1)) / 2;
else
return data.get(data.size() / 2);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:[20.0]
解释:
检测异常值有几个标准.最简单的一个,如Chauvenet的标准,使用从样本计算的平均值和标准差来确定值的"正常"范围.超出此范围的任何值都被视为异常值.
其他标准是Grubb的测试和Dixon的Q测试,如果样本来自偏斜分布,可能会比Chauvenet更好的结果.
Grubb 测试的实现可以在MathUtil.java中找到。它将找到一个异常值,您可以将其从列表中删除并重复,直到删除所有异常值。
取决于commons-math,所以如果您使用 Gradle:
dependencies {
compile 'org.apache.commons:commons-math:2.2'
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11209 次 |
| 最近记录: |