vectores valores sumar mostrar inicializar estructura elementos con codigo clase java arraylist outliers

valores - mostrar elementos de un arraylist java



Cómo detectar valores atípicos en una ArrayList (6)

Estoy tratando de pensar en algún código que me permita buscar en mi ArrayList y detectar cualquier valor fuera del rango común de "buenos valores".

Ejemplo: 100 105 102 13 104 22 101

¿Cómo podría escribir el código para detectar que (en este caso) 13 y 22 no caen dentro de los "buenos valores" de alrededor de 100?


Es solo una implementación muy simple que obtiene la información cuyos números no están dentro del rango:

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); } }

Además, dentro del método isInRange debe definir qué quiere decir con ''buenos valores'' . A continuación encontrará una implementación ejemplar.

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; }


Existen varios criterios para detectar valores atípicos. Los más simples, como el criterio de Chauvenet , usan la media y la desviación estándar calculada a partir de la muestra para determinar un rango "normal" para los valores. Cualquier valor fuera de este rango se considera un valor atípico.

Otros criterios son la prueba de Grubb y la prueba Q de Dixon, y pueden dar mejores resultados que los de Chauvenet, por ejemplo, si la muestra proviene de una distribución oblicua.


  • encuentra el valor medio para tu lista
  • crea un Map que mapea el número a la distancia de la media
  • ordenar los valores por la distancia de la media
  • y diferenciar el último n número, asegurándote de que no haya injusticia con la distancia

Usa este algoritmo. Este algoritmo usa el promedio y la desviación estándar. Estos 2 valores opcionales numéricos (2 * desviación estándar).

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; }


Una implementación de la prueba de Grubb se puede encontrar en MathUtil.java . Encontrará un valor atípico único, que puede eliminar de su lista y repetir hasta que haya eliminado todos los valores atípicos.

Depende de commons-math , así que si estás usando Gradle:

dependencies { compile ''org.apache.commons:commons-math:2.2'' }


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); } }

Salida: [20.0]

Explicación:

  • Ordena una lista de enteros, de menor a mayor
  • Divida una lista de enteros en 2 partes (por un medio) y colóquelos en 2 nuevos ArrayLists separados (llámelos "izquierda" y "derecha")
  • Encuentra un número medio (mediana) en las nuevas ArrayLists
  • Q1 es una mediana desde el lado izquierdo, y Q3 es la mediana desde el lado derecho
  • Aplicando fórmula matemática:
  • IQR = Q3 - Q1
  • LowerFence = Q1 - 1.5 * IQR
  • UpperFence = Q3 + 1.5 * IQR
  • Más información sobre esta fórmula: http://www.mathwords.com/o/outlier.htm
  • Pasa por todos mis elementos originales, y si alguno de ellos es más bajo que una valla inferior, o más alto que una valla superior, agrégalos a ArrayList de "salida".
  • Esta nueva ArrayList de "salida" contiene los valores atípicos