Ana içeriğe geç

R ile Anomalize kullanarak anomalileri tespit edin

Büyük zaman serisi veri kümelerinde anomalileri nasıl tespit edeceğinizi ve içgörüleri çok daha basit bir şekilde nasıl sunacağınızı öğrenin.
· 9 dk. oku

Yapay Zeka ile Keşfedin

Anaomalize: Kısa Açıklama

Anomalilerden bahsettiğimizde, aykırı değer olan veya istisnai bir olayı temsil eden veri noktalarını dikkate alırız. Bu olayları küçük veri kümelerinde belirlemek kolaydır ve kutu grafikleri gibi bazı basit analiz grafiklerle yapılabilir. Ancak özellikle zaman serilerinde büyük veri kümelerine geçildiğinde işler aynı anda karmaşıklaşır. Zaman serisi, belirli aralıklarla bir zaman dönemi boyunca toplanan ve analiz edildiğinde bir eğilim veya mevsimsellik gösteren veridir. Bu durumlarda anomalileri belirlemek biraz zorlayıcıdır.

İşte bu noktada zaman serisi analizinde anomali tespiti için anomalize paketi devreye girer; bu, zamana dayalı ve tek bir zaman serisinden birçok zaman serisine ölçeklenebilir, düzenli bir anomali tespit algoritmasıdır.

Geliştirilmesine yardımcı olan bazı paketler ve yöntemler vardır; bir bakıma, ölçeklenebilir bir yaklaşımla mevcut kaynakların bir bileşimidir.

Yardımcı olan açık kaynak çalışmalar şunlardır:

  • Twitter’ın AnomalyDetection paketi: Github’da mevcut (CRAN’daki anaomalyDetection farklı bir çalışmadır).
  • Rob Hyndman’ın forecast paketinde bulunan forecast::tsoutliers() işlevi.
  • Javier Lopez-de-lacalle’in CRAN’daki tsoutliers paketi.

Bu paketler ve işlevlerin tümü, ölçeklenebilir bir iş akışına entegre edilmek için kullanılır.

Anomalize iş akışından bahsedersek, üç bölüme ayrılır:

  • time_decompose() ile zaman serisi ayrıştırma.
  • anomalize() ile artık terimin (remainder) anomali tespiti.
  • time_recompose() ile anomali alt ve üst sınırlarının yeniden bileşimi.

Anomali Tespiti İş Akışı

Zaman Serisi Ayrıştırma

İlk adım, time_decompose() kullanılarak zaman serisinin ayrıştırılmasıdır. Belirli bir grup için tespitin yapılacağı ölçülen değer veya sayısal değer, observed, season, trend ve remainder olmak üzere dört sütuna ayrıştırılır. Ayrıştırma için varsayılan yöntem stl’dir; bu, Loess yumuşatıcısı kullanan mevsimsel bir ayrıştırmadır.

Loess regresyonu, dalgalı bir zaman serisini yumuşatmak için en yaygın kullanılan yöntemdir; yerel komşulukta çoklu regresyonlar uydurur, başka bir deyişle veri bölünür ve her parçaya regresyon uygulanır. Bu, zaman serilerinde faydalıdır çünkü X değişkeninin zaman olduğu bu durumda sınırı biliriz. Bu yöntem, zaman serisinde eğilimin mevsimselliğe baskın olduğu durumlarda iyi çalışır.

Burada eğilim, birçok gözlem boyunca gerçekleşen uzun vadeli büyüme; mevsimsellik ise dakikalık, saatlik veya haftalık döngüde ortaya çıkan çevrimsel örüntüdür.

İkinci bir teknik olarak, mediana dayalı mevsimsel ayrıştırma için Twitter yöntemi vardır; bu yöntem AnomalyDetection paketinde de kullanılır. Mevsimsel bileşeni kaldırma açısından STL ile aynıdır. Fark, eğilimi kaldırırken bir yumuşatıcı uydurmak yerine verinin parça bazlı medyanını (belirli aralıklarla bir veya birkaç medyan bölmesi) kullanmasıdır. Bu yöntem, zaman serisinde mevsimselliğin eğilime baskın olduğu durumlarda iyi çalışır.

time_decompose() işlevinin çıktısından bahsedelim; yukarıda tartışıldığı gibi 4 sütun üretir:

  • observed: Gerçek değerler.
  • season: Mevsimsel veya çevrimsel eğilim. Varsayılan haftalık mevsimselliktir.
  • trend: Uzun vadeli eğilim. Varsayılan 3 aylık bir aralıktır.
  • remainder: Aykırı değerleri analiz etmek için kullanılır. Basitçe, observed değerinden hem season hem de trend çıkarılmış halidir.

time_decompose() işlevi bir merge bağımsız değişkeni içerir; bunu TRUE yaparak üretilen sütunlarla birlikte özgün veriyi de tutabiliriz.

# Using data package provided in the anomalize package and taking single time series of package purrr

purrr_package = tidyverse_cran_downloads%>%
  filter(package == "purrr")%>%
  ungroup()

purrr_anomaly  = purrr_package %>%
  time_decompose(count)

purrr_anomaly%>% glimpse()
 ## Observations: 425
## Variables: 5
## $ date      <date> 2017-01-01, 2017-01-02, 2017-01-03, 2017-01-04, 201...
## $ observed  <dbl> 550, 1012, 1515, 1702, 1696, 1613, 860, 796, 2008, 2...
## $ season    <dbl> -2158.8893, 692.6571, 1087.5708, 1052.3294, 939.9377...
## $ trend     <dbl> 1496.712, 1511.009, 1525.307, 1539.604, 1553.901, 15...
## $ remainder <dbl> 1212.1777, -1191.6661, -1097.8773, -889.9334, -797.8...

Artıklarda anomalilerin tespiti

Zaman serisi analizi tamamlandıktan ve remainder anomali tespiti yapmak için istenen özelliklere sahip olduktan sonra, tekrar üç yeni sütun oluşturulur.

  • remainder_l1: Remainder için alt sınır.
  • remainder_l2: Remainder için üst sınır.
  • anaomaly: Gözlemin anomali olup olmadığını belirten sütun.

Anomaliler, dağılımı bozan yüksek etkili noktalardır. Anomalize, yüksek etkili noktalara dayanıklı iki yöntemi uygular:

  • IQR: İç Çeyrekler Aralığı
  • GESD: Genelleştirilmiş Aşırı Studentized Sapma Testi

IQR

Forecast paketindeki tsoutliers() işlevinde kullanılan yönteme benzerdir. IQR’de bir dağılım alınır ve remainder’ın dağılımını belirlemek için %25 ve %75 iç çeyrek değerleri kullanılır. Sınırlar varsayılan olarak iç çeyrek aralığının 3 katı faktörle üstte ve altta ayarlanır; bu sınırların ötesindeki herhangi bir remainder anomali olarak kabul edilir.

GESD

GESD’de anomaliler, en kötü sapkınları çıkarıp test istatistiklerini ve kritik değerleri yeniden hesaplayarak aşamalı olarak değerlendirilir; daha basitçe söylemek gerekirse, anomaliler yinelemeli biçimde belirlendikten sonra aralık yeniden hesaplanır.

IQR ve GESD’nin her ikisinin de artıları ve eksileri vardır; IQR, döngüler içermediği için nispeten daha hızlıdır, ancak anomaliler medianı saptırdığı için GESD kadar isabetli değildir; GESD’de bu etki azaltılır.

purrr_anomaly = purrr_anomaly%>%
  anomalize(remainder)

purrr_anomaly%>% glimpse()
## Observations: 425
## Variables: 8
## $ date         <date> 2017-01-01, 2017-01-02, 2017-01-03, 2017-01-04, ...
## $ observed     <dbl> 550, 1012, 1515, 1702, 1696, 1613, 860, 796, 2008...
## $ season       <dbl> -2158.8893, 692.6571, 1087.5708, 1052.3294, 939.9...
## $ trend        <dbl> 1496.712, 1511.009, 1525.307, 1539.604, 1553.901,...
## $ remainder    <dbl> 1212.1777, -1191.6661, -1097.8773, -889.9334, -79...
## $ remainder_l1 <dbl> -4330.511, -4330.511, -4330.511, -4330.511, -4330...
## $ remainder_l2 <dbl> 4400.459, 4400.459, 4400.459, 4400.459, 4400.459,...
## $ anomaly      <chr> "No", "No", "No", "No", "No", "No", "No", "No", "...

Anomali alt ve üst sınır dönüşümü

İş akışının son adımı, time_recompose ile gözlenen değerlerin çevresinde alt ve üst sınırlar oluşturmaktır. Bu işlev, season, trend, remainder_l1 ve remainder_l2’yi şu yeni sınırlara yeniden bileşenler:

  • recomposed_l1: Gözlenen değerler etrafındaki aykırı değerlerin alt sınırı.
  • recomposed_l2: Gözlenen değerler etrafındaki aykırı değerlerin üst sınırı.
purrr_anomaly = purrr_anomaly%>%
  time_recompose()

purrr_anomaly%>% glimpse()
## Observations: 425
## Variables: 10
## $ date          <date> 2017-01-01, 2017-01-02, 2017-01-03, 2017-01-04,...
## $ observed      <dbl> 550, 1012, 1515, 1702, 1696, 1613, 860, 796, 200...
## $ season        <dbl> -2158.8893, 692.6571, 1087.5708, 1052.3294, 939....
## $ trend         <dbl> 1496.712, 1511.009, 1525.307, 1539.604, 1553.901...
## $ remainder     <dbl> 1212.1777, -1191.6661, -1097.8773, -889.9334, -7...
## $ remainder_l1  <dbl> -4330.511, -4330.511, -4330.511, -4330.511, -433...
## $ remainder_l2  <dbl> 4400.459, 4400.459, 4400.459, 4400.459, 4400.459...
## $ anomaly       <chr> "No", "No", "No", "No", "No", "No", "No", "No", ...
## $ recomposed_l1 <dbl> -4992.689, -2126.845, -1717.634, -1738.578, -183...
## $ recomposed_l2 <dbl> 3738.281, 6604.125, 7013.336, 6992.392, 6894.298...

Anomalilerin Görselleştirilmesi

purrr_anomaly%>%
  plot_anomaly_decomposition()+
  ggtitle("Plotting Anomalies")
anomalilerin görselleştirilmesi

Parametreleri ayarlama

Bir anomali tespit ediciyi modellemek, veriye tamamen bağımlı olan parametreleri ayarlamadan eksik kalır.

Parametre ayarlamaya geçelim; iş akışının her düzeyinde parametreler farklıdır çünkü her düzey kendi görevini yerine getirir.

Ayrıştırma parametrelerini ayarlama

Daha önce tartışıldığı gibi eğilim ve mevsimsellik, bir zaman serisini ayrıştırmanın temelidir; dolayısıyla ayarlamalar, time_decompose işlevinin frequency ve trend değerlerinde yapılmalıdır. Varsayılan olarak, değerler otomatik atanır: her iki yöntemde (STL, Twitter) frekans için 7 gün; trend için ise STL’de 91 gün, Twitter’da 85 gün.

Her iki bağımsız değişkeni de ya da yalnızca birini ihtiyacınıza göre değiştirebilirsiniz; ancak gözlem yapmadan değişiklik yapmak, ayrıştırma sürecini aşırı uydurmaya veya yetersiz uydurmaya yol açabileceği için dikkatli olun.

purrr_package %>%
  time_decompose(count, frequency = "auto", trend = "2 weeks")%>%
  anomalize(remainder)%>%
  plot_anomaly_decomposition()+
  ggtitle("Trend = 2 Weeks / Frequency = auto ")
zaman serisi

Anomali tespiti için parametreleri ayarlama

Yukarıda tartışıldığı gibi burada anomali, remainder değerlerine göre aykırı değerleri sınıflandırmak için sınırlar hesaplanarak belirlenir. anomalize() işlevini iki parametre kontrol eder: alpha ve max_anoms. Basitçe söylemek gerekirse alpha, sınır bandını kontrol eder; varsayılan olarak 0.05’tir. Değerini azaltmak bant genişliğini artırır ve böylece bir noktanın anomali olmasını zorlaştırır.

purrr_package%>%
  time_decompose(count)%>%
  anomalize(remainder, alpha = 0.05)%>%
  time_recompose()%>%
  plot_anomalies(time_recompose = T)+
  ggtitle("alpha = 0.05")
zaman serisi
purrr_package%>%
  time_decompose(count)%>%
  anomalize(remainder, alpha = 0.025)%>%
  time_recompose()%>%
  plot_anomalies(time_recompose = T)+
  ggtitle("alpha = 0.025")
zaman serisi

max_anom parametresi, verinin anomali olabilecek yüzdesini kontrol eder. Bu parametre, alpha’nın ayarlanmasının zor olduğu ve en agresif anomalilere odaklanmak istediğiniz durumlarda kullanışlıdır.

purrr_package%>%
  time_decompose(count)%>%
  anomalize(remainder, alpha = 0.2, max_anoms = 0.2)%>%
  time_recompose()%>%
  plot_anomalies(time_recompose = T)+
  ggtitle("20% anomaly Allowed")
zaman serisi
purrr_package%>%
  time_decompose(count)%>%
  anomalize(remainder, alpha = 0.2, max_anoms = 0.05)%>%
  time_recompose()%>%
  plot_anomalies(time_recompose = T)+
  ggtitle("5% anomaly Allowed")
zaman serisi

Kaynaklar

R hakkında daha fazla bilgi edinmek isterseniz, DataCamp’in Introduction to Time Series Analysis kursunu alın.

R kullanarak Zaman Serisi Analizi: Eğitim içeriğimize göz atın.

Konular

İlgili