Primo approccio
Potresti provare questo approccio in Mathematica.
Generiamo alcuni dati bivariati:
data = Table[RandomVariate[BinormalDistribution[{50, 50}, {5, 10}, .8]], {1000}];
Quindi dobbiamo caricare questo pacchetto:
Needs["MultivariateStatistics`"]
E adesso:
ellPar=EllipsoidQuantile[data, {0.9}]
fornisce un output che definisce un'ellisse di confidenza al 90%. I valori ottenuti da questo output sono nel seguente formato:
{Ellipsoid[{x1, x2}, {r1, r2}, {{d1, d2}, {d3, d4}}]}
x1 e x2 specificano il punto in cui l'ellisse in posizione centrale, r1 e r2 specificano i raggi del semiasse e d1, d2, d3 e d4 specificano la direzione di allineamento.
Puoi anche tracciare questo:
Show[{ListPlot[data, PlotRange -> {{0, 100}, {0, 100}}, AspectRatio -> 1], Graphics[EllipsoidQuantile[data, 0.9]]}]
La forma parametrica generale dell'ellisse è:
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]}
E puoi tracciarlo in questo modo:
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}}]
È possibile eseguire un controllo basato su informazioni geometriche pure: se la distanza euclidea tra il centro dell'ellisse (ellPar [[1,1]]) e il punto dati è maggiore della distanza tra il centro dell'ellisse e il bordo di l'ellisse (ovviamente, nella stessa direzione in cui si trova il punto), quindi quel punto dati si trova all'esterno dell'ellisse.
Secondo approccio
Questo approccio si basa sulla distribuzione regolare del kernel.
Questi sono alcuni dati distribuiti in modo simile ai tuoi dati:
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];
Otteniamo una distribuzione uniforme del kernel su questi valori di dati:
skd = SmoothKernelDistribution[data];
Otteniamo un risultato numerico per ciascun punto dati:
eval = Table[{data[[i]], PDF[skd, data[[i]]]}, {i, Length[data]}];
Fissiamo una soglia e selezioniamo tutti i dati superiori a questa soglia:
threshold = 1.2;
dataIn = Select[eval, #1[[2]] > threshold &][[All, 1]];
Qui otteniamo i dati che non rientrano nella regione:
dataOut = Complement[data, dataIn];
E ora possiamo tracciare tutti i dati:
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]]
I punti di colore verde sono quelli sopra la soglia e i punti di colore rosso sono quelli sotto la soglia.