Primer enfoque
Puede probar este enfoque en Mathematica.
Generemos algunos datos bivariados:
data = Table[RandomVariate[BinormalDistribution[{50, 50}, {5, 10}, .8]], {1000}];
Entonces necesitamos cargar este paquete:
Needs["MultivariateStatistics`"]
Y ahora:
ellPar=EllipsoidQuantile[data, {0.9}]
da una salida que define una elipse de confianza del 90%. Los valores que obtiene de esta salida tienen el siguiente formato:
{Ellipsoid[{x1, x2}, {r1, r2}, {{d1, d2}, {d3, d4}}]}
x1 y x2 especifican el punto en el que la elipse en el centro, r1 y r2 especifican los radios del semieje, y d1, d2, d3 y d4 especifican la dirección de alineación.
También puedes trazar esto:
Show[{ListPlot[data, PlotRange -> {{0, 100}, {0, 100}}, AspectRatio -> 1], Graphics[EllipsoidQuantile[data, 0.9]]}]
La forma paramétrica general de la elipse es:
ell[t_, xc_, yc_, a_, b_, angle_] := {xc + a Cos[t] Cos[angle] - b Sin[t] Sin[angle],
yc + a Cos[t] Sin[angle] + b Sin[t] Cos[angle]}
Y puedes trazarlo de esta manera:
ParametricPlot[
ell[t, ellPar[[1, 1, 1]], ellPar[[1, 1, 2]], ellPar[[1, 2, 1]], ellPar[[1, 2, 2]],
ArcTan[ellPar[[1, 3, 1, 2]]/ellPar[[1, 3, 1, 1]]]], {t, 0, 2 \[Pi]},
PlotRange -> {{0, 100}, {0, 100}}]
Puede realizar una verificación basada en información geométrica pura: si la distancia euclidiana entre el centro de la elipse (ellPar [[1,1]]) y su punto de datos es mayor que la distancia entre el centro de la elipse y el borde de la elipse (obviamente, en la misma dirección en la que se encuentra su punto), entonces ese punto de datos está fuera de la elipse.
Segundo enfoque
Este enfoque se basa en la distribución fluida del núcleo.
Estos son algunos datos distribuidos de manera similar a sus datos:
data1 = RandomVariate[BinormalDistribution[{.3, .7}, {.2, .3}, .8], 500];
data2 = RandomVariate[BinormalDistribution[{.6, .3}, {.4, .15}, .8], 500];
data = Partition[Flatten[Join[{data1, data2}]], 2];
Obtenemos una distribución de kernel suave en estos valores de datos:
skd = SmoothKernelDistribution[data];
Obtenemos un resultado numérico para cada punto de datos:
eval = Table[{data[[i]], PDF[skd, data[[i]]]}, {i, Length[data]}];
Arreglamos un umbral y seleccionamos todos los datos que son más altos que este umbral:
threshold = 1.2;
dataIn = Select[eval, #1[[2]] > threshold &][[All, 1]];
Aquí obtenemos los datos que quedan fuera de la región:
dataOut = Complement[data, dataIn];
Y ahora podemos trazar todos los datos:
Show[ContourPlot[Evaluate@PDF[skd, {x, y}], {x, 0, 1}, {y, 0, 1}, PlotRange -> {{0, 1}, {0, 1}}, PlotPoints -> 50],
ListPlot[dataIn, PlotStyle -> Darker[Green]],
ListPlot[dataOut, PlotStyle -> Red]]
Los puntos de color verde son los que están por encima del umbral y los puntos de color rojo son los que están por debajo del umbral.