Prosty algorytm do wykrywania wartości odstających online ogólnych szeregów czasowych


88

Pracuję z dużą ilością szeregów czasowych. Te szeregi czasowe są w zasadzie pomiarami sieci przychodzącymi co 10 minut, a niektóre z nich są okresowe (tj. Przepustowość), a inne nie (tj. Wielkość ruchu routingu).

Chciałbym prosty algorytm do przeprowadzania online „wykrywania wartości odstających”. Zasadniczo chcę zachować w pamięci (lub na dysku) całe dane historyczne dla każdej serii czasowej i chcę wykryć wszelkie wartości odstające w scenariuszu na żywo (za każdym razem, gdy rejestrowana jest nowa próbka). Jaki jest najlepszy sposób na osiągnięcie tych wyników?

Obecnie używam średniej ruchomej, aby usunąć trochę hałasu, ale co dalej? Proste rzeczy, takie jak odchylenie standardowe, szalenie, ... w stosunku do całego zestawu danych nie działa dobrze (nie mogę założyć, że szeregi czasowe są nieruchome) i chciałbym czegoś bardziej „dokładnego”, najlepiej czarnej skrzynki, takiej jak:

double outlier_detection (double * vector, double value);

gdzie wektor jest tablicą podwójnej zawierającej dane historyczne, a zwracana wartość jest wynikiem anomalii dla nowej „wartości” próbki.


1
Dla jasności, oto oryginalne pytanie na SO: stackoverflow.com/questions/3390458/...
Matt Parker

1
Myślę, że powinniśmy zachęcać plakatów do zamieszczania linków jako części pytania, jeśli opublikowali to samo pytanie na innej stronie SE.

tak, masz całkowitą rację. Następnym razem wspomnę, że wiadomość jest przekreślona.
gianluca,

Sugeruję również sprawdzenie innych powiązanych linków po prawej stronie strony. To popularne pytanie, które wcześniej pojawiło się w różnych pytaniach. Jeśli nie są zadowalające, najlepiej zaktualizuj swoje pytanie dotyczące specyfiki Twojej sytuacji.
Andy W

Dobry chwyt, @Andy! Połączmy to pytanie z drugim.
whuber

Odpowiedzi:


75

Oto prosta funkcja R, która znajdzie wartości odstające szeregu czasowego (i opcjonalnie pokaże je na wykresie). Będzie obsługiwał sezonowe i nie sezonowe szeregi czasowe. Podstawową ideą jest znalezienie wiarygodnych oszacowań trendu i składników sezonowych i odjęcie ich. Następnie znajdź wartości odstające w resztkach. Test resztkowych wartości odstających jest taki sam, jak w przypadku standardowego wykresu pudełkowego - przyjmuje się, że punkty większe niż 1,5 IQR powyżej lub poniżej górnego i dolnego kwartylu są wartościami odstającymi. Liczba IQR powyżej / poniżej tych progów jest zwracana jako „wynik” odstający. Tak więc wynik może być dowolną liczbą dodatnią i będzie wynosił zero dla wartości nietypowych.

Zdaję sobie sprawę, że nie wdrażasz tego w języku R, ale często uważam, że funkcja R jest dobrym miejscem do rozpoczęcia. Następnie zadaniem jest przetłumaczenie tego na dowolny wymagany język.

tsoutliers <- function(x,plot=FALSE)
{
    x <- as.ts(x)
    if(frequency(x)>1)
        resid <- stl(x,s.window="periodic",robust=TRUE)$time.series[,3]
    else
    {
        tt <- 1:length(x)
        resid <- residuals(loess(x ~ tt))
    }
    resid.q <- quantile(resid,prob=c(0.25,0.75))
    iqr <- diff(resid.q)
    limits <- resid.q + 1.5*iqr*c(-1,1)
    score <- abs(pmin((resid-limits[1])/iqr,0) + pmax((resid - limits[2])/iqr,0))
    if(plot)
    {
        plot(x)
        x2 <- ts(rep(NA,length(x)))
        x2[score>0] <- x[score>0]
        tsp(x2) <- tsp(x)
        points(x2,pch=19,col="red")
        return(invisible(score))
    }
    else
        return(score)
}

+1 ode mnie, doskonale. Czy więc> 1,5 X międzykwartylowy jest konsensusową definicją wartości odstającej dla szeregów zależnych od czasu? Byłoby miło mieć odniesienie niezależne od skali.
doug

Test odstający dotyczy reszt, więc mam nadzieję, że zależność czasowa jest niewielka. Nie wiem o konsensusie, ale wykresy pudełkowe są często używane do wykrywania wartości odstających i wydają się działać całkiem dobrze. Istnieją lepsze metody, jeśli ktoś chciałby, aby funkcja była nieco bardziej wyszukana.
Rob Hyndman,

Naprawdę dziękuję za pomoc, naprawdę to doceniam. Jestem teraz dość zajęty w pracy, ale jak najszybciej przetestuję podejście takie jak twoje i wrócę z moimi ostatnimi przemyśleniami na ten temat. Jedna tylko myśl: w twojej funkcji, z tego, co widzę, muszę ręcznie określić częstotliwość szeregów czasowych (podczas konstruowania jej), a składnik sezonowości jest brany pod uwagę tylko wtedy, gdy częstotliwość jest większa niż 1. Czy istnieje solidny sposób poradzić sobie z tym automatycznie?
gianluca

1
Tak, założyłem, że częstotliwość jest znana i określona. Istnieją metody automatycznego szacowania częstotliwości, ale znacznie skomplikowałoby to funkcję. Jeśli chcesz oszacować częstotliwość, spróbuj zadać osobne pytanie na ten temat - prawdopodobnie zapewnię odpowiedź! Ale potrzebuje więcej miejsca niż mam w komentarzu.
Rob Hyndman,

2
@Marcin, polecam zrobić sobie dźgnięcie. Może wklej swoje rozwiązanie na gist.github.com i opublikuj pytanie SO, gdy skończysz, aby inni mogli sprawdzić Twoją pracę?
Ken Williams

27

Dobre rozwiązanie będzie miało kilka składników, w tym:

  • Użyj odpornego, ruchomego okna gładkiego, aby usunąć niestabilność.

  • Ponownie wyraż oryginalne dane, aby reszty względem gładkiego były w przybliżeniu symetrycznie rozmieszczone. Biorąc pod uwagę naturę twoich danych, prawdopodobne jest, że ich pierwiastki kwadratowe lub logarytmy dawałyby symetryczne reszty.

  • Zastosuj metody kart kontrolnych lub przynajmniej myślenie kart kontrolnych do reszt.

O ile to ostatnie, myślenie na podstawie tabeli kontrolnej pokazuje, że „konwencjonalne” progi, takie jak 2 SD lub 1,5-krotność IQR poza kwartylami, działają słabo, ponieważ wyzwalają zbyt wiele fałszywych sygnałów wymykających się spod kontroli. Ludzie zwykle używają 3 SD w pracy na karcie kontrolnej, skąd 2,5 (lub nawet 3) razy IQR poza kwartylami byłoby dobrym punktem wyjścia.

Mniej więcej nakreśliłem naturę rozwiązania Roba Hyndmana, dodając do niego dwa główne punkty: potencjalną potrzebę ponownego wyrażenia danych i mądrość bycia bardziej konserwatywnym w sygnalizowaniu wartości odstającej. Nie jestem jednak pewien, czy Loess nadaje się do wykrywania online, ponieważ nie działa dobrze w punktach końcowych. Zamiast tego możesz użyć czegoś tak prostego jak ruchomy filtr środkowy (jak w przypadku wygładzania opornego Tukeya). Jeśli wartości odstające nie występują w seriach, możesz użyć wąskiego okna (być może 5 punktów danych, które rozpadnie się tylko w przypadku serii 3 lub więcej wartości odstających w grupie 5).

Po przeprowadzeniu analizy w celu ustalenia dobrego ponownego wyrażenia danych, jest mało prawdopodobne, że będziesz musiał zmienić to wyrażenie. Dlatego twój wykrywacz online naprawdę musi tylko odwoływać się do najnowszych wartości (ostatnie okno), ponieważ w ogóle nie użyje wcześniejszych danych. Jeśli masz naprawdę długie szeregi czasowe, możesz przejść dalej, aby przeanalizować autokorelację i sezonowość (takie jak powtarzające się codzienne lub tygodniowe wahania), aby usprawnić procedurę.


3
To niezwykła odpowiedź na praktyczne analizy. Nigdy nie pomyślałbym, że trzeba wypróbować 3 IQR poza kwartylami.
John Robertson,

3
@John, 1,5 IQR to oryginalna rekomendacja Tukeya dla najdłuższych wąsów na wykresie pudełkowym, a 3 IQR to jego zalecenie do oznaczania punktów jako „daleko odbiegających” (riff na popularnym frazie z lat 60-tych). Jest to wbudowane w wiele algorytmów wykresów. Zalecenie jest analizowane teoretycznie w Hoaglin, Mosteller i Tukey, Understanding
whuber

Potwierdza to dane szeregów czasowych, które próbowałem analizować. Średnie okno, a także standardowe odchylenia okna. ((x - avg) / sd)> 3 wydają się być punktami, które chcę oznaczyć jako wartości odstające. Cóż, przynajmniej ostrzegam jako wartości odstające, zaznaczam wszystko powyżej 10 sd jako wartości skrajne błędów. Problem, na który wpadam, to jaka jest idealna długość okna? Gram z czymkolwiek pomiędzy 4-8 punktami danych.
Josh Peak

1
@Neo Najlepszym rozwiązaniem może być eksperymentowanie z podzbiorem danych i potwierdzenie wniosków testami na pozostałej części. Można również przeprowadzić bardziej formalną walidację krzyżową (ale należy zachować szczególną ostrożność w przypadku danych szeregów czasowych ze względu na współzależność wszystkich wartości).
whuber

17

(Ta odpowiedź stanowi odpowiedź na zduplikowane (teraz zamknięte) pytanie w Wykrywanie zaległych zdarzeń , które przedstawiało niektóre dane w formie graficznej.)


Wykrywanie wartości odstających zależy od charakteru danych i tego, co chcesz o nich założyć. Metody ogólnego zastosowania opierają się na solidnych statystykach. Ideą tego podejścia jest scharakteryzowanie dużej ilości danych w sposób, na który nie mają wpływu żadne wartości odstające, a następnie wskazanie dowolnych indywidualnych wartości, które nie mieszczą się w tej charakterystyce.

Ponieważ jest to szereg czasowy, komplikuje to konieczność (ponownego) wykrywania wartości odstających na bieżąco. Jeśli ma to być zrobione, gdy seria się rozwija, to wolno nam wykorzystywać tylko starsze dane do wykrywania, a nie przyszłe dane! Ponadto, jako ochronę przed wieloma powtarzanymi testami, chcielibyśmy zastosować metodę, która ma bardzo niski odsetek wyników fałszywie dodatnich.

Te rozważania sugerują przeprowadzenie prostego, niezawodnego testu danych odstających od ruchomego okna na danych . Istnieje wiele możliwości, ale jedna prosta, łatwa do zrozumienia i łatwa do wdrożenia oparta jest na działającym MAD: absolutna mediana odchylenia od mediany. Jest to bardzo solidna miara zmienności danych, podobna do odchylenia standardowego. Źródło nadmiernych szczyt będzie kilka Mads lub bardziej większy niż mediana.

Rx=(1,2),,n)n=1150y

# Parameters to tune to the circumstances:
window <- 30
threshold <- 5

# An upper threshold ("ut") calculation based on the MAD:
library(zoo) # rollapply()
ut <- function(x) {m = median(x); median(x) + threshold * median(abs(x - m))}
z <- rollapply(zoo(y), window, ut, align="right")
z <- c(rep(z[1], window-1), z) # Use z[1] throughout the initial period
outliers <- y > z

# Graph the data, show the ut() cutoffs, and mark the outliers:
plot(x, y, type="l", lwd=2, col="#E00000", ylim=c(0, 20000))
lines(x, z, col="Gray")
points(x[outliers], y[outliers], pch=19)

Zastosowany do zestawu danych, takiego jak czerwona krzywa zilustrowana w pytaniu, daje następujący wynik:

Wątek

Dane są pokazane na czerwono, 30-dniowe okno mediany + 5 * progów MAD na szaro, a wartości odstające - które są po prostu wartościami danych powyżej szarej krzywej - na czarno.

(Próg można obliczyć dopiero na końcu początkowego okna. Dla wszystkich danych w tym początkowym oknie stosuje się pierwszy próg: dlatego szara krzywa jest płaska między x = 0 a x = 30).

Skutkami zmiany parametrów są (a) zwiększenie wartości windowbędzie miało tendencję do wygładzania szarej krzywej i (b) zwiększenie thresholdspowoduje podniesienie szarej krzywej. Wiedząc o tym, można wziąć początkowy segment danych i szybko zidentyfikować wartości parametrów, które najlepiej oddzielają odległe szczyty od reszty danych. Zastosuj te wartości parametrów, aby sprawdzić resztę danych. Jeśli wykres pokazuje, że metoda pogarsza się z czasem, oznacza to, że charakter danych się zmienia i parametry mogą wymagać ponownego dostrojenia.

Zauważ, jak mało ta metoda zakłada o danych: nie muszą one być normalnie dystrybuowane; nie muszą wykazywać żadnej częstotliwości; nie muszą nawet być nieujemne. Wszystko to zakłada się, że dane zachowują się w podobny sposób uzasadniony w czasie i że Dalekie szczyty są wyraźnie wyższe niż w pozostałej części danych.


Jeśli ktoś chciałby eksperymentować (lub porównać jakieś inne rozwiązanie z oferowanym tutaj), oto kod, którego użyłem do wygenerowania danych takich jak te pokazane w pytaniu.

n.length <- 1150
cycle.a <- 11
cycle.b <- 365/12
amp.a <- 800
amp.b <- 8000

set.seed(17)
x <- 1:n.length
baseline <- (1/2) * amp.a * (1 + sin(x * 2*pi / cycle.a)) * rgamma(n.length, 40, scale=1/40)
peaks <- rbinom(n.length, 1,  exp(2*(-1 + sin(((1 + x/2)^(1/5) / (1 + n.length/2)^(1/5))*x * 2*pi / cycle.b))*cycle.b))
y <- peaks * rgamma(n.length, 20, scale=amp.b/20) + baseline

To naprawdę ciekawe rozwiązanie i doceniam to, że mogę je wdrożyć bez użycia R (po prostu zwykłego JavaScript w aplikacji internetowej). Dzięki!
hgoebl,

15

Jeśli martwisz się założeniami z jakimś konkretnym podejściem, jednym z podejść jest wyszkolenie wielu uczniów na różnych sygnałach, a następnie użycie metod grupowania i zsumowanie „głosów” od twoich uczniów, aby dokonać klasyfikacji odstającej.

BTW, może to być warte przeczytania lub przeglądania, ponieważ odnosi się do kilku podejść do problemu.


5

Zgaduję, że wyrafinowany model szeregów czasowych nie będzie dla ciebie działał z powodu czasu potrzebnego na wykrycie wartości odstających przy użyciu tej metodologii. Dlatego oto obejście:

  1. Najpierw określ bazowe „normalne” wzorce ruchu na rok na podstawie ręcznej analizy danych historycznych uwzględniających porę dnia, dzień tygodnia w weekend i miesiąc, rok itp.

  2. Użyj tej linii bazowej wraz z prostym mechanizmem (np. Średnią ruchomą sugerowaną przez Carlosa), aby wykryć wartości odstające.

Możesz także przejrzeć literaturę dotyczącą statystycznego sterowania procesem w celu uzyskania pomysłów.


1
Tak, właśnie to robię: do tej pory ręcznie dzieliłem sygnał na okresy, aby dla każdego z nich mógł zdefiniować przedział ufności, w którym sygnał ma być stacjonarny, i dlatego mogę zastosować standardowe metody, takie jak jako odchylenie standardowe ... Prawdziwy problem polega na tym, że nie mogę zdecydować o oczekiwanym wzorze dla wszystkich sygnałów, które muszę analizować, i dlatego szukam czegoś bardziej inteligentnego.
gianluca,

Oto jeden pomysł: Krok 1: Wdrożenie i oszacowanie ogólnego modelu szeregów czasowych jednorazowo na podstawie danych historycznych. Można to zrobić offline. Krok 2: Użyj wynikowego modelu do wykrycia wartości odstających. Krok 3: Przy pewnej częstotliwości (być może co miesiąc?) Ponownie skalibruj model szeregów czasowych (można to zrobić offline), aby wykrycie wartości odstających w kroku 2 nie wykraczało zbyt daleko poza obecne wzorce ruchu. Czy to zadziała w twoim kontekście?

Tak, to może działać. Myślałem o podobnym podejściu (przeliczanie linii bazowej co tydzień, co może być bardzo obciążające procesor, jeśli masz do analizy setki szeregów czasowych jednowymiarowych). BTW, naprawdę trudne pytanie brzmi: „jaki jest najlepszy algorytm typu czarnej skrzynki do modelowania całkowicie ogólnego sygnału, biorąc pod uwagę szum, oszacowanie trendu i sezonowość?”. AFAIK, każde podejście w literaturze wymaga naprawdę trudnej fazy „dostrajania parametrów”, a jedyną automatyczną metodą, jaką znalazłem, jest model ARIMA firmy Hyndman ( robjhyndman.com/software/forecast ). Czy coś brakuje?
gianluca,

Proszę pamiętać, że nie jestem zbyt leniwy, by badać te parametry, chodzi o to, że te wartości należy ustawić zgodnie z oczekiwanym wzorcem sygnału, aw moim scenariuszu nie mogę przyjąć żadnego założenia.
gianluca,

Modele ARIMA to klasyczne modele szeregów czasowych, których można użyć do dopasowania danych szeregów czasowych. Zachęcam do zapoznania się z zastosowaniem modeli ARIMA. Możesz poczekać, aż Rob będzie online, a może wpadnie na kilka pomysłów.

5

Sezonowo dostosowuj dane, aby normalny dzień wyglądał bardziej płasko. Możesz pobrać dzisiejszą próbkę o 17:00 i odjąć lub podzielić średnią z poprzednich 30 dni o 17:00. Następnie spójrz na odchylenia standardowe N (mierzone przy użyciu wstępnie dostosowanych danych) na wartości odstające. Można to zrobić osobno dla tygodniowych i codziennych „pór roku”.


Ponownie działa to całkiem dobrze, jeśli sygnał ma mieć taką sezonowość, ale jeśli użyję zupełnie innych szeregów czasowych (tj. Średniego czasu podróży w obie strony TCP w czasie), ta metoda nie będzie działać (ponieważ byłoby lepiej do obsługi tego z prostą średnią globalną i odchyleniem standardowym za pomocą przesuwanego okna zawierającego dane historyczne).
gianluca,

1
O ile nie jesteś skłonny wdrożyć ogólnego modelu szeregów czasowych (który ma swoje wady pod względem opóźnień itp.) Jestem pesymistą, że znajdziesz ogólną implementację, która jednocześnie jest wystarczająco prosta do pracy dla wszystkich rodzajów szeregów czasowych.

Kolejny komentarz: wiem, że dobrą odpowiedzią może być „więc możesz oszacować okresowość sygnału i zdecydować, który algorytm użyć zgodnie z nim”, ale nie znalazłem naprawdę dobrego rozwiązania tego drugiego problemu (grałem bit z analizą spektralną za pomocą DFT i analizą czasową za pomocą funkcji autokorelacji, ale moje szeregi czasowe zawierają dużo szumu i takie metody dają większość zwariowanych rezultatów przez większość czasu)
gianluca

Komentarz do twojego ostatniego komentarza: dlatego szukam bardziej ogólnego podejścia, ale potrzebuję pewnego rodzaju „czarnej skrzynki”, ponieważ nie mogę przyjąć żadnego założenia dotyczącego analizowanego sygnału, a zatem nie mogę utworzyć „najlepszy zestaw parametrów dla algorytmu uczenia się”.
gianluca,

@gianluca Jak już poinformowałeś, podstawowa struktura ARIMA może maskować anomalię. Nieprawidłowe sformułowanie możliwych zmiennych przyczyn, takich jak godzina dnia, dzień tygodnia, efekty wakacji itp. Może również maskować anomalię. Odpowiedź jest dość jasna, że ​​musisz dobrze zachowywać ostrożność, aby skutecznie wykrywać anomalie. Cytując Bacona: „Każdy bowiem, kto zna drogi Natury, z łatwością zauważy jej odchylenia, a z drugiej strony, kto zna jej odchylenia, dokładniej opisa swoje obyczaje”.
IrishStat,

3

Alternatywą dla podejścia nakreślonego przez Roba Hyndmana byłoby zastosowanie Prognozy Holta-Wintersa . Pasma ufności pochodzące z Holta-Wintersa można wykorzystać do wykrywania wartości odstających. Oto artykuł opisujący, jak używać Holt-Winters do „Wykrywania nieprawidłowych zachowań w szeregach czasowych do monitorowania sieci”. Implementacja dla RRDTool można znaleźć tutaj .


2

Analiza spektralna wykrywa okresowość w stacjonarnych szeregach czasowych. Podejście w dziedzinie częstotliwości oparte na estymacji gęstości widmowej to podejście, które poleciłbym jako pierwszy krok.

Jeżeli dla niektórych okresów nieregularność oznacza znacznie wyższy pik niż typowy dla tego okresu, wówczas szereg takich nieregularności nie byłby stacjonarny, a analiza spektralna nie byłaby odpowiednia. Zakładając, że określiłeś okres, w którym występują nieregularności, powinieneś być w stanie określić w przybliżeniu normalną wysokość piku, a następnie ustawić próg na pewnym poziomie powyżej tej średniej, aby wyznaczyć nieregularne przypadki.


2
Czy możesz wyjaśnić, w jaki sposób to rozwiązanie wykryłoby „lokalne nieprawidłowości”? Przedstawienie działającego przykładu byłoby niezwykle pomocne. (Szczerze mówiąc, sugeruję, aby to zrobić, ponieważ przeprowadzając takie ćwiczenie, wierzę, że odkryjesz, że twoja sugestia nie jest skuteczna w wykrywaniu wartości odstających. Ale mogę się mylić ...)
whuber

1
@ whuber Analiza spektralna pozwoli jedynie ustalić, gdzie znajdują się wszystkie piki. Następnym krokiem byłoby dopasowanie modelu szeregów yime przy użyciu warunków sinus i cosinus z częstotliwościami określonymi na podstawie analizy widmowej i amplitudami oszacowanymi na podstawie danych. Jeśli nieregularności oznaczają szczyty o bardzo wysokich amplitudach, myślę, że odpowiedni byłby próg amplitudy. Jeżeli lokalne nieregularności oznaczają, że przez pewien czas amplituda jest czasami znacznie większa niż inna, to szereg nie jest stacjonarny, a analiza spektralna nie byłaby odpowiednia.
Michael Chernick,

1
Nie podążam za wnioskiem o braku stacjonarności. Na przykład suma regularnego przebiegu sinusoidalnego i zaznaczonego procesu punktu Poissona byłaby stacjonarna, ale nie wykazywałaby żadnej z okresowości, której szukasz. Niemniej jednak można znaleźć pewne silne piki w periodogramie, ale nie powiedzą one nic istotnego o nieregularnych pikach danych wprowadzonych przez komponent procesu Poissona.
whuber

1
Stacjonarne szeregi czasowe mają stałą średnią. Jeśli pik składnika okresowego może się zmieniać w czasie, może sprowadzić średnią zmianę w czasie, a zatem seiery byłyby niestacjonarne.
Michael Chernick,

2

Ponieważ są to dane szeregów czasowych, prosty filtr wykładniczy http://en.wikipedia.org/wiki/Exponential_smoothing wygładzi dane. Jest to bardzo dobry filtr, ponieważ nie trzeba gromadzić starych punktów danych. Porównaj każdą nowo wygładzoną wartość danych z jej niewygładzoną wartością. Gdy odchylenie przekroczy określony z góry próg (w zależności od tego, co uważasz za wartość odstającą w twoich danych), wtedy wartość odstająca może być łatwo wykryta.

W CI zrobi to dla próbki 16-bitowej w czasie rzeczywistym (uważam, że można ją znaleźć gdzieś tutaj <Objaśnienie - https://dsp.stackexchange.com/questions/378/what-is-the-best-first-order -iir-przybliżenie-do-ruchomej średniej filtru >)

#define BITS2 2     //< This is roughly = log2( 1 / alpha ), depending on how smooth you want your data to be

short Simple_Exp_Filter(int new_sample) 
{static int filtered_sample = 0;
long local_sample = sample << 16; /*We assume it is a 16 bit sample */
filtered_sample += (local_sample - filtered_sample) >> BITS2;   
return (short) ((filtered_sample+0x8000) >> 16); //< Round by adding .5 and truncating.   
}


int main()
{
newly_arrived = function_receive_new_sample();
filtered_sample = Simple_Exp_Filter(newly_arrived);
if (abs(newly_arrived - filtered_sample)/newly_arrived > THRESHOLD)
    {
    //AN OUTLIER HAS BEEN FOUND
    }
 return 0;   
}

1

Możesz użyć odchylenia standardowego ostatnich N pomiarów (musisz wybrać odpowiedni N). Dobrym wynikiem anomalii byłoby to, ile standardowych odchyleń stanowi pomiar od średniej ruchomej.


Dziękuję za odpowiedź, ale co jeśli sygnał wykazuje wysoką sezonowość (tj. Wiele pomiarów sieciowych charakteryzuje się codziennym i tygodniowym wzorcem w tym samym czasie, na przykład noc w dzień lub w weekend lub w dni robocze)? W takim przypadku podejście oparte na odchyleniu standardowym nie zadziała.
gianluca,

Na przykład, jeśli dostaję nową próbkę co 10 minut i robię wykrywanie wartości odstających od wykorzystania przepustowości sieci przez firmę, w zasadzie o godzinie 18:00 miara ta spadnie (jest to oczekiwany całkowicie normalny wzór), i standardowe odchylenie obliczone dla przesuwanego okna zawiedzie (ponieważ na pewno wywoła alarm). Jednocześnie, jeśli miara spada o 16.00 (odbiegając od zwykłego poziomu wyjściowego), jest to prawdziwa wartość odstająca.
gianluca,

1

To, co robię, to grupowanie pomiarów według godziny i dnia tygodnia i porównanie standardowych odchyleń tego. Nadal nie poprawia takich rzeczy jak wakacje i sezonowość lato / zima, ale jest poprawna przez większość czasu.

Minusem jest to, że naprawdę musisz zebrać około roku danych, aby mieć wystarczająco dużo, aby stddev zaczął mieć sens.


Dziękuję, to jest dokładnie to, co starałem się unikać (o wiele próbek jak bazowej), ponieważ chciałbym naprawdę reaktywnego podejścia (np wykrywania on-line, może „brudne”, po 1-2 tygodniach bazowej)
gianluca

0

Sugeruję poniższy schemat, który powinien być możliwy do wdrożenia za około jeden dzień:

Trening

  • Zbierz jak najwięcej próbek, które możesz zachować w pamięci
  • Usuń oczywiste wartości odstające, używając standardowego odchylenia dla każdego atrybutu
  • Oblicz i przechowuj macierz korelacji, a także średnią każdego atrybutu
  • Oblicz i przechowuj odległości Mahalanobisa wszystkich próbek

Obliczanie „odstających wartości”:

W przypadku pojedynczej próbki, dla której chcesz poznać jej „nietypowość”:

  • Odzyskaj średnie, macierz kowariancji i dystans Mahalanobisa ze szkolenia
  • Oblicz odległość Mahalanobisa „d” dla swojej próbki
  • Zwraca percentyl, w którym spada „d” (używając odległości Mahalanobisa od treningu)

To będzie twój wynik odstający: 100% jest skrajnym wynikiem odstającym.


PS. Przy obliczaniu odległości Mahalanobisa używaj macierzy korelacji, a nie macierzy kowariancji. Jest to bardziej niezawodne, jeśli pomiary próbki różnią się pod względem jednostki i liczby.


0

W przypadku, gdy trzeba szybko obliczyć wartości odstające, można skorzystać z pomysłu Roba Hyndmana i Mahito Sugiyamy ( https://github.com/BorgwardtLab/sampling-outlier-detection , biblioteka (spoutlier), funkcja qsp) do obliczenia wartości odstające, takie jak:

library(spoutlier)
rapidtsoutliers <- function(x,plot=FALSE,seed=123)
{
    set.seed(seed)
    x <- as.numeric(x)
    tt <- 1:length(x)
    qspscore <- qsp(x)
    limit <- quantile(qspscore,prob=c(0.95))
    score <- pmax((qspscore - limit),0)
    if(plot)
    {
        plot(x,type="l")
        x2 <- ts(rep(NA,length(x)))
        x2[score>0] <- x[score>0]
        tsp(x2) <- tsp(x)
        points(x2,pch=19,col="red")
        return(invisible(score))
    }
    else
        return(score)
}

0

wykrywanie anomalii wymaga budowy równania opisującego oczekiwanie. Wykrywanie interwencji jest dostępne zarówno w przypadku przyczynowym, jak i przyczynowym. Jeśli ktoś ma szereg prognostyczny, taki jak cena, sprawy mogą się nieco skomplikować. Inne odpowiedzi tutaj nie wydają się uwzględniać możliwej do przypisania przyczyny przypisywanej określonej przez użytkownika serii predyktorów, takiej jak cena, a zatem mogą być wadliwe. Ilość sprzedana może zależeć od ceny, być może wcześniejszych cen i być może ilości sprzedanej w przeszłości. Podstawę wykrycia anomalii (impulsy, impulsy sezonowe, zmiany poziomów i trendy czasu lokalnego) można znaleźć na stronie https://pdfs.semanticscholar.org/09c4/ba8dd3cc88289caf18d71e8985bdd11ad21c.pdf


Link nie działa, czy możesz to naprawić? Dzięki
Pankaj Joshi

zrobione ..................
IrishStat
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.