Ausreißer auf einem Streudiagramm finden

9

Ich habe eine Reihe von Datenpunkten, die auf einem Ort sitzen und einem Muster folgen sollen, aber es gibt einige Streupunkte vom Hauptort, die in meiner endgültigen Analyse Unsicherheit verursachen. Ich möchte einen ordentlichen Ort erhalten, um ihn später für meine Analyse anzuwenden. Die blauen Punkte sind mehr oder weniger die Streupunkte, die ich finden und auf raffinierte Weise ausschließen möchte, ohne dies manuell zu tun.Geben Sie hier die Bildbeschreibung ein

Ich habe überlegt, so etwas wie die Regression der nächsten Nachbarn zu verwenden, bin mir aber nicht sicher, ob dies der beste Ansatz ist, oder ich bin nicht sehr vertraut, wie er implementiert werden sollte, um ein angemessenes Ergebnis zu erzielen. Übrigens möchte ich es ohne Anpassungsverfahren machen.

Die transponierte Version der Daten lautet wie folgt:

X=array([[ 0.87 , -0.01 ,  0.575,  1.212,  0.382,  0.418, -0.01 ,  0.474,
         0.432,  0.702,  0.574,  0.45 ,  0.334,  0.565,  0.414,  0.873,
         0.381,  1.103,  0.848,  0.503,  0.27 ,  0.416,  0.939,  1.211,
         1.106,  0.321,  0.709,  0.744,  0.309,  0.247,  0.47 , -0.107,
         0.925,  1.127,  0.833,  0.963,  0.385,  0.572,  0.437,  0.577,
         0.461,  0.474,  1.046,  0.892,  0.313,  1.009,  1.048,  0.349,
         1.189,  0.302,  0.278,  0.629,  0.36 ,  1.188,  0.273,  0.191,
        -0.068,  0.95 ,  1.044,  0.776,  0.726,  1.035,  0.817,  0.55 ,
         0.387,  0.476,  0.473,  0.863,  0.252,  0.664,  0.365,  0.244,
         0.238,  1.203,  0.339,  0.528,  0.326,  0.347,  0.385,  1.139,
         0.748,  0.879,  0.324,  0.265,  0.328,  0.815,  0.38 ,  0.884,
         0.571,  0.416,  0.485,  0.683,  0.496,  0.488,  1.204,  1.18 ,
         0.465,  0.34 ,  0.335,  0.447,  0.28 ,  1.02 ,  0.519,  0.335,
         1.037,  1.126,  0.323,  0.452,  0.201,  0.321,  0.285,  0.587,
         0.292,  0.228,  0.303,  0.844,  0.229,  1.077,  0.864,  0.515,
         0.071,  0.346,  0.255,  0.88 ,  0.24 ,  0.533,  0.725,  0.339,
         0.546,  0.841,  0.43 ,  0.568,  0.311,  0.401,  0.212,  0.691,
         0.565,  0.292,  0.295,  0.587,  0.545,  0.817,  0.324,  0.456,
         0.267,  0.226,  0.262,  0.338,  1.124,  0.373,  0.814,  1.241,
         0.661,  0.229,  0.416,  1.103,  0.226,  1.168,  0.616,  0.593,
         0.803,  1.124,  0.06 ,  0.573,  0.664,  0.882,  0.286,  0.139,
         1.095,  1.112,  1.167,  0.589,  0.3  ,  0.578,  0.727,  0.252,
         0.174,  0.317,  0.427,  1.184,  0.397,  0.43 ,  0.229,  0.261,
         0.632,  0.938,  0.576,  0.37 ,  0.497,  0.54 ,  0.306,  0.315,
         0.335,  0.24 ,  0.344,  0.93 ,  0.134,  0.4  ,  0.223,  1.224,
         1.187,  1.031,  0.25 ,  0.53 , -0.147,  0.087,  0.374,  0.496,
         0.441,  0.884,  0.971,  0.749,  0.432,  0.582,  0.198,  0.615,
         1.146,  0.475,  0.595,  0.304,  0.416,  0.645,  0.281,  0.576,
         1.139,  0.316,  0.892,  0.648,  0.826,  0.299,  0.381,  0.926,
         0.606],
       [-0.154, -0.392, -0.262,  0.214, -0.403, -0.363, -0.461, -0.326,
        -0.349, -0.21 , -0.286, -0.358, -0.436, -0.297, -0.394, -0.166,
        -0.389,  0.029, -0.124, -0.335, -0.419, -0.373, -0.121,  0.358,
         0.042, -0.408, -0.189, -0.213, -0.418, -0.479, -0.303, -0.645,
        -0.153,  0.098, -0.171, -0.066, -0.368, -0.273, -0.329, -0.295,
        -0.362, -0.305, -0.052, -0.171, -0.406, -0.102,  0.011, -0.375,
         0.126, -0.411, -0.42 , -0.27 , -0.407,  0.144, -0.419, -0.465,
        -0.036, -0.099,  0.007, -0.167, -0.205, -0.011, -0.151, -0.267,
        -0.368, -0.342, -0.299, -0.143, -0.42 , -0.232, -0.368, -0.417,
        -0.432,  0.171, -0.388, -0.319, -0.407, -0.379, -0.353,  0.043,
        -0.211, -0.14 , -0.373, -0.431, -0.383, -0.142, -0.345, -0.144,
        -0.302, -0.38 , -0.337, -0.2  , -0.321, -0.269,  0.406,  0.223,
        -0.322, -0.395, -0.379, -0.324, -0.424,  0.01 , -0.298, -0.386,
         0.018,  0.157, -0.384, -0.327, -0.442, -0.388, -0.387, -0.272,
        -0.397, -0.415, -0.388, -0.106, -0.504,  0.034, -0.153, -0.32 ,
        -0.271, -0.417, -0.417, -0.136, -0.447, -0.279, -0.225, -0.372,
        -0.316, -0.161, -0.331, -0.261, -0.409, -0.338, -0.437, -0.242,
        -0.328, -0.403, -0.433, -0.274, -0.331, -0.163, -0.361, -0.298,
        -0.392, -0.447, -0.429, -0.388,  0.11 , -0.348, -0.174,  0.244,
        -0.182, -0.424, -0.319,  0.088, -0.547,  0.189, -0.216, -0.228,
        -0.17 ,  0.125, -0.073, -0.266, -0.234, -0.108, -0.395, -0.395,
         0.131,  0.074,  0.514, -0.235, -0.389, -0.288, -0.22 , -0.416,
        -0.777, -0.358, -0.31 ,  0.817, -0.363, -0.328, -0.424, -0.416,
        -0.248, -0.093, -0.28 , -0.357, -0.348, -0.298, -0.384, -0.394,
        -0.362, -0.415, -0.349, -0.08 , -0.572, -0.07 , -0.423,  0.359,
         0.4  ,  0.099, -0.426, -0.252, -0.697, -0.508, -0.348, -0.254,
        -0.307, -0.116, -0.029, -0.201, -0.302, -0.25 , -0.44 , -0.233,
         0.274, -0.295, -0.223, -0.398, -0.298, -0.209, -0.389, -0.247,
         0.225, -0.395, -0.124, -0.237, -0.104, -0.361, -0.335, -0.083,
        -0.254]])
Dalek
quelle
Wie identifizieren Sie diese blauen Punkte?
Dan
@ Dan Setzen Sie einfach einige Grenzen xund yund bestimmen Sie sie. Aber ich habe viele solcher Diagramme mit unterschiedlichen Merkmalen und unterschiedlichen Streupunkten und möchte einen zuverlässigen Weg finden, um sie auszuschließen, ohne sie durch Betrachten der Diagramme zu definieren.
Dalek
1
Wie definieren Sie ein "ordentliches Muster"? Ich sehe keine Begründung dafür, warum diese blauen Punkte neben der Sichtprüfung ausgeschlossen würden. Wenn Sie ein Ausschlusskriterium hätten, wäre dies sinnvoller.
Dan
@Dan basierend auf der Anwendung, nach der ich suche, werden die blauen Punkte für mich als Ausreißer und Streuungen der Hauptfunktion betrachtet.
Dalek
ok also was hat dann das "Hauptmerkmal" definiert?
Dan

Antworten:

10

Zu Beginn der Identifizierung der "gestreuten" Punkte sollten Sie sich auf Orte konzentrieren, an denen eine Schätzung der Kerneldichte relativ niedrig ist.

Dieser Vorschlag geht davon aus, dass zunächst wenig oder gar nichts über den "Ort" der Punkte bekannt ist oder sogar vermutet wird - die Kurve oder Kurven, entlang der die meisten von ihnen fallen werden - und er wurde im Geiste einer halbautomatischen Untersuchung der Daten erstellt (anstatt Hypothesen zu testen).

Möglicherweise müssen Sie mit der Kernelbreite und dem Schwellenwert "relativ niedrig" spielen. Es gibt gute automatische Möglichkeiten, die ersteren zu schätzen, während die letzteren durch eine Analyse der Dichten an den Datenpunkten identifiziert werden könnten (um einen Cluster niedriger Werte zu identifizieren).


Beispiel

X.

Zahl

Die Punkte mit relativ geringer Dichte wurden automatisch eingekreist . (Die Dichten an diesen Punkten betragen weniger als ein Achtel der mittleren Dichte unter allen Punkten.) Sie umfassen die meisten - aber nicht alle! - Punkte mit niedriger Genauigkeit und einige der Punkte mit hoher Genauigkeit (oben) Recht). Punkte mit geringer Genauigkeit, die in der Nähe der Kurve liegen (wie durch die Punkte mit hoher Genauigkeit extrapoliert), wurden nicht eingekreist. Das Kreisen der hochpräzisen Punkte unterstreicht die Tatsache, dass überall dort , wo Punkte spärlich sind, die Spur der zugrunde liegenden Kurve unsicher ist. Dies ist ein Merkmal des vorgeschlagenen Ansatzes, keine Einschränkung!


Code

RCode zur Erstellung dieses Beispiels folgt. Es verwendet die ksBibliothek, die die Anisotropie im Punktmuster bewertet, um eine orientierte Kernform zu entwickeln. Dieser Ansatz funktioniert gut in den Beispieldaten, deren Punktwolke tendenziell lang und dünn ist.

#
# Simulate some data.
#
f <- function(x) -0.55 + 0.45*x + 0.01/(1.2-x)^2 # The underlying curve

set.seed(17)
n1 <- 280; n2 <- 15
x <- c(1.2 - rbeta(n1,.9, .6), rep(0.1, n2))
y <- f(x)
d <- data.frame(x=x + c(rnorm(n1, 0, 0.025), rnorm(n2, 0, 0.1)),
                   y=y + c(rnorm(n1, 0, 0.025), rnorm(n2, 0, 0.33)),
                   group=c(rep(1, n1), rep(2, n2)))
d <- subset(d, subset=(y <= 1.0)) # Omit any high-y points
#
# Plot the density estimate.
#
require(ks)
p <- cbind(d$x, d$y)
dens <- kde(p)
n.levels <- 13
colors <- gray(seq(1, 0, length.out=n.levels))
plot(dens, display="filled.contour2", cont=seq(0, 100, length.out=n.levels),
     col=colors, xlab="X", ylab="Y")
#
# Evaluate densities at the data points.
#
dens <- kde(p, eval.points=p)
d$Density <- dens$estimate
#
# Plot the (correct) curve and the points.
#
curve(f(x), add=TRUE, to=1.2, col="Black")
points(d$x, d$y, ylim=c(-1,1), pch=19, cex=sqrt(d$Density/8),
     col=ifelse(d$group==1, "Red", "Blue"))
#
# Highlight some low-density points.
#
m <- mean(d$Density)
e <- subset(d, subset=(Density < m/10))
points(e$x, e$y, col="#00000080")
whuber
quelle
Der Grund, warum simulierte Daten bereitgestellt werden, ist, dass ich diese Analyse durchgeführt habe, bevor die Daten in der Frage veröffentlicht wurden. Der Simulationscode kann jedoch zum Testen dieses oder eines anderen Verfahrens nützlich sein und kann daher für sich genommen nützlich sein.
whuber
Um die zugrunde liegende Kurve zu erhalten, haben Sie den Anpassungskoeffizienten mithilfe eines Anpassungsverfahrens geschätzt, oder? Haben Sie eine Funktion für die Anpassung übernommen?
Dalek
Überhaupt keine: Siehe Code, der nur die Kernel-Dichteschätzung (wie von zurückgegeben kde) verwendet, um zu kreisende Punkte zu identifizieren. Wenn ich die Daten nicht aus einer bekannten Funktionsform (wie von f) simuliert hätte, hätte ich überhaupt keine Referenzkurve zeichnen können, da keine Anpassung durchgeführt wurde.
whuber
Ich meinte die Funktionalität von f(x).
Dalek
@whuber, super coole Handlung!
Dan