wykorzystując informacje o sąsiadach do przypisywania danych lub znajdowania danych niepowiązanych (w R)

13

Mam zestaw danych z założeniem, że najbliżsi sąsiedzi są najlepszymi predyktorami. Po prostu idealny przykład wizualizacji gradientu dwukierunkowego

wprowadź opis zdjęcia tutaj

Załóżmy, że mamy przypadek, w którym brakuje kilku wartości, możemy łatwo przewidzieć na podstawie sąsiadów i trendu.

wprowadź opis zdjęcia tutaj

Odpowiadająca macierz danych w R (przykładowy manekin do treningu):

miss.mat <- matrix (c(5:11, 6:10, NA,12, 7:13, 8:14, 9:12, NA, 14:15, 10:16),ncol=7, byrow = TRUE)
miss.mat 
    [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    5    6    7    8    9   10   11
[2,]    6    7    8    9   10   NA   12
[3,]    7    8    9   10   11   12   13
[4,]    8    9   10   11   12   13   14
[5,]    9   10   11   12   NA   14   15
[6,]   10   11   12   13   14   15   16

Uwagi: (1) Zakłada się , że właściwość brakujących wartości jest losowa , może się zdarzyć wszędzie.

(2) Wszystkie punkty danych pochodzą z jednej zmiennej, ale zakłada się, że na ich wartość ma wpływ neighborswiersz i kolumna obok nich. Zatem pozycja w macierzy jest ważna i może być uważana za inną zmienną.

Mam nadzieję, że w niektórych sytuacjach uda mi się przewidzieć pewne nieścisłości (mogą to być błędy) i skorygować błąd (tylko przykład, wygenerujmy taki błąd w danych fikcyjnych):

> mat2 <- matrix (c(4:10, 5, 16, 7, 11, 9:11, 6:12, 7:13, 8:14, 9:13, 4,15, 10:11, 2, 13:16),ncol=7, byrow = TRUE)
> mat2

    [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    4    5    6    7    8    9   10
[2,]    5   16    7   11    9   10   11
[3,]    6    7    8    9   10   11   12
[4,]    7    8    9   10   11   12   13
[5,]    8    9   10   11   12   13   14
[6,]    9   10   11   12   13    4   15
[7,]   10   11    2   13   14   15   16

Powyższe przykłady są tylko ilustracją (można na nie odpowiedzieć wizualnie), ale prawdziwy przykład może być bardziej mylący. Szukam, czy istnieje solidna metoda przeprowadzenia takiej analizy. Myślę, że to powinno być możliwe. Jaka metoda byłaby odpowiednia do przeprowadzenia tego rodzaju analizy? jakieś sugestie programu / pakietu R, aby wykonać tego rodzaju analizę?

wprowadź opis zdjęcia tutaj

rdorlearn
źródło
Czy możesz założyć, że brakujące dane to MAR (w terminologii Rubina (1976))?
user603
tak, można przyjąć, że wartości losowo brakuje (MAR). Zobacz moje ostatnie zmiany.
rdorlearn

Odpowiedzi:

7

Pytanie dotyczy sposobów korzystania z najbliższych sąsiadów w solidny sposób do identyfikowania i korygowania zlokalizowanych wartości odstających. Dlaczego nie zrobić dokładnie tego?

Procedura polega na obliczeniu solidnego lokalnego wygładzenia, ocenie reszt i zerowaniu wszystkich, które są zbyt duże. Spełnia to bezpośrednio wszystkie wymagania i jest wystarczająco elastyczne, aby dostosować się do różnych aplikacji, ponieważ można zmieniać wielkość lokalnego sąsiedztwa i próg rozpoznawania wartości odstających.

(Dlaczego elastyczność jest tak ważna? Ponieważ każda taka procedura ma dużą szansę zidentyfikowania niektórych zlokalizowanych zachowań jako „oddalających się”. W związku z tym wszystkie takie procedury można uznać za bardziej płynne . Eliminują one pewne szczegóły wraz z pozornymi wartościami odstającymi. Analityk potrzebuje pewnej kontroli nad kompromisem między zachowaniem szczegółów a niewykrywaniem lokalnych wartości odstających).

Kolejną zaletą tej procedury jest to, że nie wymaga ona prostokątnej matrycy wartości. W rzeczywistości można go nawet zastosować do nieregularnych danych za pomocą lokalnej wygładzacza odpowiedniej dla takich danych.

Rloess794940005%1/20

Ryciny

Zauważ, że (zgodnie z Rkonwencją) rzędy matryc są rysowane jako pionowe paski. Wszystkie obrazy, z wyjątkiem reszt, są zaznaczone na wzgórzu, aby pomóc w wyświetlaniu niewielkich zmian ich wartości. Bez tego prawie wszystkie lokalne wartości odstające byłyby niewidoczne!

(0,79)(49,30)

Plamki na wykresie „Pozostałości” pokazują oczywiste izolowane lokalne wartości odstające. Ten wykres pokazuje również inną strukturę (taką jak ten ukośny pasek), którą można przypisać danym bazowym. Można poprawić na tej procedury przy użyciu przestrzennego modelu danych ( za pomocą metod geostatystycznych), ale opisując że i ilustrujący zajęłoby nam zbyt daleko nią tutaj.

1022003600

#
# Create data.
#
set.seed(17)
rows <- 2:80; cols <- 2:50
y <- outer(rows, cols, 
           function(x,y) 100 * exp((abs(x-y)/50)^(0.9)) * sin(x/10) * cos(y/20))
y.real <- y
#
# Contaminate with iid noise.
#
n.out <- 200
cat(round(100 * n.out / (length(rows)*length(cols)), 2), "% errors\n", sep="")
i.out <- sample.int(length(rows)*length(cols), n.out)
y[i.out] <- y[i.out] + rnorm(n.out, sd=0.05 * sd(y))
#
# Process the data into a data frame for loess.
#
d <- expand.grid(i=1:length(rows), j=1:length(cols))
d$y <- as.vector(y)
#
# Compute the robust local smooth.
# (Adjusting `span` changes the neighborhood size.)
#
fit <- with(d, loess(y ~ i + j, span=min(1/2, 125/(length(rows)*length(cols)))))
#
# Display what happened.
#
require(raster)
show <- function(y, nrows, ncols, hillshade=TRUE, ...) {
  x <- raster(y, xmn=0, xmx=ncols, ymn=0, ymx=nrows)
  crs(x) <- "+proj=lcc +ellps=WGS84"
  if (hillshade) {
    slope <- terrain(x, opt='slope')
    aspect <- terrain(x, opt='aspect')
    hill <- hillShade(slope, aspect, 10, 60)
    plot(hill, col=grey(0:100/100), legend=FALSE, ...)
    alpha <- 0.5; add <- TRUE
  } else {
    alpha <- 1; add <- FALSE
  }
  plot(x, col=rainbow(127, alpha=alpha), add=add, ...)
}

par(mfrow=c(1,4))
show(y, length(rows), length(cols), main="Data")

y.res <- matrix(residuals(fit), nrow=length(rows))
show(y.res, length(rows), length(cols), hillshade=FALSE, main="Residuals")
#hist(y.res, main="Histogram of Residuals", ylab="", xlab="Value")

# Increase the `8` to find fewer local outliers; decrease it to find more.
sigma <- 8 * diff(quantile(y.res, c(1/4, 3/4)))
mu <- median(y.res)
outlier <- abs(y.res - mu) > sigma
cat(sum(outlier), "outliers found.\n")

# Fix up the data (impute the values at the outlying locations).
y.imp <- matrix(predict(fit), nrow=length(rows))
y.imp[outlier] <- y[outlier] - y.res[outlier]

show(y.imp, length(rows), length(cols), main="Imputed")
show(y.real, length(rows), length(cols), main="Real")
Whuber
źródło
whuber: Czy dobrze rozumiem, że zakładasz, że wartości odstające są izolowanymi komórkami? Jeśli tak, to czy wiesz, jak wrażliwe jest to podejście do naruszenia tego założenia?
użytkownik603
@ user603 Nie zakładam, że wartości odstające są izolowane - wiele z nich w tym przykładzie nie jest - ale zakładam, że odsetek wartości odstających w dowolnym sąsiedztwie lokalnym jest na tyle niski, że nie zepsują płynności lokalnej. Prawdopodobnie, jeśli istnieje jakaś dzielnica z bardzo dużą liczbą takich wartości odstających, nie można ich już uważać za wartości odstające!
whuber
1
@ user603 Oczywiście! Wydaje się jednak, że zabiera nas to z domniemanej sytuacji, w której „najbliżsi sąsiedzi są najlepszymi predyktorami”. W związku z tym wszystko, co robimy podczas przetwarzania danych, powinno zachować lokalną przewidywalność. Jeśli jedna kolumna ma „znacznie inną skalę” niż jej sąsiad, okoliczność ta stanowiłaby poważne naruszenie tego stwierdzenia. (Zastanawiam się również, jak skupiłeś się na kolumnach: po ponownym przeczytaniu pytania nie mogę wykryć żadnej asymetrii w rolach kolumn i wierszy.)
whuber
1
p
1
@ whuber to świetne rozwiązanie, dzięki - próbowałem wprowadzić przynajmniej niektóre brakujące wartości, co zawsze jest rzeczywistą sytuacją - połączenie brakujących (na przykład 50 brakujących wartości) i wartości odstających (100 wartości odstających). ekscytujące!
rdorlearn
4

Radzę zajrzeć do tego artykułu [0]. Problem, który ma rozwiązać, wydaje się raczej dobrze pasować do twojego opisu, z wyjątkiem tego, że metoda zaproponowana przez autora jest nieco bardziej dopracowana niż wprowadzanie NN (chociaż wykorzystuje coś podobnego jako punkt początkowy).

XXnp

k

Pierwszym krokiem każdej iteracji jest krok imputacji danych. Odbywa się to tak, jak w algorytmie EM: brakujące komórki są wypełniane wartością, którą powinny mieć (jest to krok E).

XXttRppkLLkkDDkp

Podsumowując artykuł, oto ogólny algorytm, który proponują:

  • l=0WW0XX

  • Następnie rób do momentu konwergencji:

    WWl(ttl,LLl,DDl)

    l=l+1

    YYl=LLl1(WWl1ttl1)(LLl1)

    WWlWWlN(ttl1,LLl1DDl1(LLl1))YYl

||WWl1WWl||F(tt,LL,DD)

(ttl1,LLl1DDl1)

N(ttl1,LLDD(LL))

Nie znam gotowej implementacji R dla tego podejścia, ale można łatwo wyprodukować z podskładników (głównie solidny algorytm PCA), a te są dobrze zaimplementowane w R, patrz pakiet rrcov (artykuł jest ciche informacje na ten temat).

  • [0] Serneels S. and Verdonck, T. (2008). Analiza głównego składnika dla danych zawierających wartości odstające i brakujące elementy. Statystyka obliczeniowa i analiza danych tom: 52 wydanie: 3 strony: 1712-1727.
użytkownik603
źródło
dzięki, moim celem jest tutaj nie przewidywanie wartości odstających (w sensie, że są one poza rozkładem), a raczej wartości niezgodne (wartości odstające), które nie pasują do wzorca.
rdorlearn
Myślę, że źle zrozumiałeś moją odpowiedź. Takie podejście spowoduje prognozowanie dla dowolnej wartości, ale wartości odstające nie zostaną dobrze przewidziane: dzieje się tak, ponieważ nie wolno im wpływać na dopasowanie PCA. Radzę przeczytać artykuł.
user603
dzięki, podejście wydaje się interesujące i zgadywanie może również dobrze działać. Ale bez odpowiednich kodów będzie trudne do wdrożenia - przynajmniej dla mnie zbyt wyrafinowane!
rdorlearn