Tidy Zaman Serisi Analizi: Kısım 1

Tidy Zaman Serisi Analizi ile ilgili bu dizinin ilk kısmında CRAN indirmelerini araştırmak için tidyquard kullanacağız. Aklımıza gelen sorulardan ilki “Neden tidyquant?” Çoğu insan tidyquant ın tamamen bir finansal paket olduğunu düşünüyor ve bunun doğru olduğunu biliyoruz. Bununla birlikte “tidy” xts, zoo ve TTR entegrasyonları nedeniyle zaman serileri analizi için uygundur. Bu yazıda, tq_transmute () kullanarak zaman aralıklarına fonksiyonların “tidy” ile uygulanmasını kolaylaştıran xts paketindeki “dönem uygulama (period apply)” fonksiyonlarını tartışacağız!

Örnek olarak tq_transmute() ile dönem uygulama fonksiyonlarını kullanarak aşağıdaki gibi görselleştirmeler oluşturabiliriz.

Median tidyverse downloads by week

İhtiyacımız Olan Kütüphaneler

Bugün öncelikle iki kütüphane kullanacağız. Bunlar:

library(tidyquant)  # Loads tidyverse, tidquant, financial pkgs, xts/zoo
library(cranlogs)   # For inspecting package downloads over time

CRAN Tidyverse İndirmeleri

tidyverse paketleri süper kullanışlıdır, bu yüzden RDocumenation.org daki liderler sıralamasında neden en iyi indirmelerde sıralandığına şaşmamalı.

Bu paketlerdeki popülerlik eğilimlerini incelemenin iyi bir yolu, CRAN indirmelerini incelemektir. Öyleyse indirme verilerini nasıl alırız? Cranlogs paketi, çeşitli paketlerin günlük indirmelerini almamızı sağlayan cran_downloads() fonksiyonuna sahiptir. İndirme verilerini almak, analiz etmek istediğimiz paketlerin bir vektörünü oluşturmak ve cran_downloads() kullanmak kadar kolaydır. tidyquant için son altı aylık bir tarih aralığı ekledik. Çünkü bu makalenin yayınlanması tarihinden 6 ay önce tidyquant kullanıma başlanmıştı.

# Çeşitli tidyverse paketleri
pkgs <- c(
    "tidyr", "lubridate", "dplyr", 
    "broom", "tidyquant", "ggplot2", "purrr", 
    "stringr", "knitr"
    )

# Ayrı ayrı paketler için indirmelerin alınması
tidyverse_downloads <- cran_downloads(
    packages = pkgs, 
    from     = "2017-01-01", 
    to       = "2017-06-30") %>%
    tibble::as_tibble() %>%
    group_by(package)

tidyverse_downloads
## # A tibble: 1,629 x 3
## # Groups:   package [9]
##          date count package
##  *     <date> <dbl>   <chr>
##  1 2017-01-01   873   tidyr
##  2 2017-01-02  1840   tidyr
##  3 2017-01-03  2495   tidyr
##  4 2017-01-04  2906   tidyr
##  5 2017-01-05  2847   tidyr
##  6 2017-01-06  2756   tidyr
##  7 2017-01-07  1439   tidyr
##  8 2017-01-08  1556   tidyr
##  9 2017-01-09  3678   tidyr
## 10 2017-01-10  7086   tidyr
## # ... with 1,619 more rows</chr></dbl></date>

Ggplot2 kullanarak “tidyverse” indirmelerini kolaylıkla görselleştirebiliriz.

# Paket indirmelerinin görselleştirilmesi
tidyverse_downloads %>%
    ggplot(aes(x = date, y = count, color = package)) +
    geom_point() +
    labs(title = "tidyverse packages: Daily downloads", x = "") +
    facet_wrap(~ package, ncol = 3, scale = "free_y") +
    scale_color_tq() +
    theme_tq() +
    theme(legend.position="none")

İndirme grafiğinden neler olup bittiğini görmek zor. Verilerde bir miktar ayrım var gibi görünüyor (bu hafta sonlarına karşılık geliyor), ancak genel olarak trendi gürültüden ayırmak zor.

Günlük verilerin doğası budur: çok gürültülü olma eğilimindedir. Veri seti büyüdükçe sorun daha da kötüleşir. Neyse ki, trendleri çıkarmamıza ve görselleştirmeyi kolaylaştırmamıza yardımcı olacak bir dizi faydalı zaman serisi aracı var!

 

Zaman Serisi Fonksiyonları

Xts, zoo ve TTR paketleri zaman serileriyle çalışmayı sağlayan bazı harika fonksiyonlara sahiptir. Bugün, xts paketinden dönem uygulama fonksiyonlarına odaklanacağız. Dönem uygulama (period apply) fonksiyonları, diğer fonksiyonların ortak aralıklarla uygulanmasını sağlayan yardımcı fonksiyonlardır.

Bu sağlanan diğer fonksiyonlar nelerdir?

Herhangi bir fonksiyon skalarlar (mean, median, sd, min, max, vb.) veya vektörler (quantile, summary, ve özel fonksiyonlar) gibi sayısal vektör döndürür. Dönem uygulama fonksiyonları [interval] günlük, haftalık, aylık, üç aylık ve yıllık olabilir apply.[interval] biçimindedir.

Zaman Serisi Fonksiyonlarının Tidy Uygulaması

Zaman serisi fonksiyonlarına “tidy” yöntemi uygulamak için tq_transmute() fonksiyonunu kullanacağız. tq_transmute() işlevi her zaman yeni bir data frame döndürür (mevcut data frame yapısına sütun eklemek yerine). Bu nedenle, rowwise (veya columnwise) boyut değişiklikleriyle sonuçlanan birleştirme görevleri için çok uygundur. Ve bu bir dizi entegre finansal ve zaman serisi paket entegrasyonu ile birlikte gelir. tq_transmute_fun_options() tarafından döndürülen kullanılabilir fonskiyonların listesini araştırarak hangi “apply” fonksiyonlarının işe yarayacağını görebiliriz.

# "apply" functions from xts
tq_transmute_fun_options()$xts %>%
    stringr::str_subset("^apply")
## [1] "apply.daily"     "apply.monthly"   "apply.quarterly"
## [4] "apply.weekly"    "apply.yearly"

Fonksiyonların Döneme Göre Uygulanması

Yukarıdaki tidyverse günlük indirme grafiğinde gördüğümüz gibi, sadece verileri görselleştirerek günlük verilerdeki eğilimleri anlamak zor olabilir. İstatistikleri zaman serisinin alt kümelerine uygulamak, gürültüyü gidermeyi ve altta yatan eğilimleri çıkarmayı / görselleştirmeyi kolaylaştırmaya yardımcı olabilir. xts paketiyle gelen dönem uygulama fonksiyonları bu durumlarda mükemmel cevap oluşturur.

Basit Bir Vaka Örneği: Ortalama günlük indirmelerin haftaya göre incelenmesi.

Paket indirmelerimizin artıp artmadığını araştırmak istediğimizi varsayalım. Bunu yapmanın bir yolu, bunları bir aralıkta birleştirerek araştırmaktır. Her gün görüntülemek yerine, her hafta ortalama günlük indirmeleri görüntüleyebiliriz, bu da aykırı değerlerin etkisini azaltır ve süreçteki veri noktalarının sayısını azaltır, böylece trendi görselleştirmeyi kolaylaştırır.

Haftalık toplama işlemini gerçekleştirmek için, un-tidy fonksiyonları “tidy” olarak uygulayan tq_transmute() yöntemini kullanacağız.

Kullanmak istediğimiz fonksiyon FUN (haftalık olarak uygulanacak fonksiyon) ve (FUN işlevine iletilen ek bağımsız değişkenler) bağımsız değişkenini alan application.weekly() fonksiyonudur.

Ortalama uygulamak için FUN =mean() ‘yi haftalık aralıklarla ayarlayacağız. Son olarak, hesaplama sırasında NA değerlerini kaldırmak için na.rm = TRUE değişkenini ileteceğiz.

mean_tidyverse_downloads_w <- tidyverse_downloads %>%
    tq_transmute(
        select     = count,
        mutate_fun = apply.weekly, 
        FUN        = mean,
        na.rm      = TRUE,
        col_rename = "mean_count"
    )
mean_tidyverse_downloads_w
## # A tibble: 243 x 3
## # Groups:   package [9]
##    package       date mean_count
##      <chr>     <date>      <dbl>
##  1   tidyr 2017-01-01    873.000
##  2   tidyr 2017-01-08   2262.714
##  3   tidyr 2017-01-15   4243.000
##  4   tidyr 2017-01-22   5118.714
##  5   tidyr 2017-01-29   4884.143
##  6   tidyr 2017-02-05   4974.286
##  7   tidyr 2017-02-12   4849.000
##  8   tidyr 2017-02-19   4570.857
##  9   tidyr 2017-02-26   4674.714
## 10   tidyr 2017-03-05   4179.429
## # ... with 233 more rows</dbl></date></chr>

Günlük indirme sayılarının her biri yerine her hafta ortalama günlük indirme sayısını grafik olarak göstererek, trendleri biraz daha kolay görselleştirebiliriz.

mean_tidyverse_downloads_w %>%
    ggplot(aes(x = date, y = mean_count, color = package)) +
    geom_point() +
    geom_smooth(method = "loess") + 
    labs(title = "tidyverse packages: Average daily downloads by week", x = "", 
         y = "Mean Daily Downloads by Week") +
    facet_wrap(~ package, ncol = 3, scale = "free_y") +
    expand_limits(y = 0) + 
    scale_color_tq() +
    theme_tq() +
    theme(legend.position="none")
 
plot of chunk unnamed-chunk-6

Yine de bir sorun var, ortalamayı tek başına çizmek hikayenin tamamını anlatmıyor. Eğilimleri (veya oynaklığı), özellikle aykırı değerlere karşı oldukça hassas olan eğilimleri de etkileyebilecek değişkenlik (veya değişkenlik) vardır. Bir sonraki adımda, tek bir istatistiğin ötesine geçmeyi göreceğiz.

Özel fonksiyonlar: tek bir istatistiğin ötesinde haftalık toplama

İstatistikçiler olarak, genellikle sadece ortalamaları elde etmekten daha fazlasını önemsiyoruz. Standart sapma, dağılım ve temel verilerin karakterize edilmesine yardımcı olan diğer unsurlarla ilgilenebiliriz. İyi haber, verileri daha ayrıntılı açıklayan sayısal değerleri döndüren özel fonksiyonlar uygulayabilmemizdir. Aşağıdakileri döndüren bir fonksiyon oluşturarak test edelim:

  • ortalama
  • standart sapma
  • min/max
  • % 95 orta için aralık (2.5% ve 97.5%)
  • % 50 orta için aralık (25% ve 75%, veya Q1 ve Q3)
  • medyan

Bunu yapmak gerçekten çok kolay. custom_stat_fun() özel fonksiyonumuz için sadece üç fonksiyon gerekir: mean, sd ve quantile.

Fonksiyonu x (sayısal vektör), na.rm (NA değerlerini istatistik hesaplamadan kaldırmak için arg) ve ile bağımsız değişkenlerini almak için quantile() işlevine ek bağımsız değişkenler iletecek şekilde ayarlayacağız. İşte burada:

# Custom function to return mean, sd, quantiles
custom_stat_fun <- function(x, na.rm = TRUE, ...) {
    # x     = numeric vector
    # na.rm = boolean, whether or not to remove NA's
    # ...   = additional args passed to quantile
    c(mean    = mean(x, na.rm = na.rm),
      stdev   = sd(x, na.rm = na.rm),
      quantile(x, na.rm = na.rm, ...)) 
}

Hadi özel stat fonksiyonunu test edelim. Dönüş biçiminin adlandırılmış bir numerik vektör olduğunu unutmayalım. Dönüş numerik olduğu sürece “tidy” birleştirmede kullanabiliriz. (Sonraki adımda gösterilecek)

# Testing custom_stat_fun
options(digits = 4)
set.seed(3366)
nums  <- c(10 + 1.5*rnorm(10), NA)
probs <- c(0, 0.025, 0.25, 0.5, 0.75, 0.975, 1)
custom_stat_fun(nums, na.rm = TRUE, probs = probs)
##   mean  stdev     0%   2.5%    25%    50%    75%  97.5%   100% 
##  8.824  1.752  5.316  5.616  8.285  9.189 10.118 10.746 10.877

Şimdi “tidy” birleştirmesini yapıyoruz. tq_transmute() yöntemini kullanan gruplara custom_stat_fun() yöntemini ve haftalık toplama işlevi apply.weekly() yöntemini uygulayalım. İşlem, haftalık aralıklarda mean() fonksiyonunun uygulama işlemiyle hemen hemen aynıdır. Tek fark, özel stat fonksiyonumuzun içindeki quantile() işlevine gönderilen olasılıkları (probs) da tedarik etmemizdir. Döndürülen çıktı, her bir istatistiki veri yayılımı ile ilgili olan bir tidy veri çerçevesidir.

# Applying the custom function by week
stats_tidyverse_downloads_w <- tidyverse_downloads %>%
    tq_transmute(
        select = count,
        mutate_fun = apply.weekly, 
        FUN = custom_stat_fun,
        na.rm = TRUE,
        probs = probs
    )
stats_tidyverse_downloads_w
## # A tibble: 243 x 11
## # Groups:   package [9]
##    package       date  mean  stdev  `0%` `2.5%` `25%` `50%` `75%`
##      <chr>     <date> <dbl>  <dbl> <dbl>  <dbl> <dbl> <dbl> <dbl>
##  1   tidyr 2017-01-01   873     NA   873  873.0   873   873   873
##  2   tidyr 2017-01-08  2263  633.7  1439 1456.5  1698  2495  2802
##  3   tidyr 2017-01-15  4243 2643.6     0  428.1  2879  3678  6523
##  4   tidyr 2017-01-22  5119 1908.6  2432 2434.7  3939  5575  6486
##  5   tidyr 2017-01-29  4884 1600.8  2549 2564.1  3890  5588  6056
##  6   tidyr 2017-02-05  4974 1633.1  2522 2547.9  4146  5715  6016
##  7   tidyr 2017-02-12  4849 1530.8  2670 2675.6  3898  5331  5960
##  8   tidyr 2017-02-19  4571 1445.7  2463 2463.2  3804  5406  5472
##  9   tidyr 2017-02-26  4675 1508.1  2418 2443.9  3837  5297  5753
## 10   tidyr 2017-03-05  4179 1211.4  2679 2705.8  3048  4715  5172
## # ... with 233 more rows, and 2 more variables: `97.5%` <dbl>,
## #   `100%` <dbl></dbl></dbl></dbl></dbl></dbl></dbl></dbl></dbl></dbl></date></chr>

Daha önce olduğu gibi, veriler haftalara göre bölümlere ayrıldı, ancak şimdi eğilime ek olarak oynaklığı görselleştirmek için kullanılabilecek bir dizi ek özellik var. Eğilim medyan, volatilite birinci ve üçüncü çeyrek tarafından görselleştirilir. Ayrıca, 1. Çeyrek çizgi ile bazı yönlerdeki medyan noktalar arasındaki boşluktan hafta sonlarının neden olduğu çarpıklığı görsel olarak tanıyabiliriz. Bu, tahmin edilmesi gereken ayrı bir grup olabileceğinin bir göstergesidir.

stats_tidyverse_downloads_w %>%
    ggplot(aes(x = date, y = `50%`, color = package)) +
    # Ribbon
    geom_ribbon(aes(ymin = `25%`, ymax = `75%`), 
                color = palette_light()[[1]], fill = palette_light()[[1]], alpha = 0.5) +
    # Points
    geom_point() +
    geom_smooth(method = "loess", se = FALSE) + 
    # Aesthetics
    labs(title = "tidyverse packages: Median daily downloads by week", x = "",
         subtitle = "Range of 1st and 3rd quartile to show volatility",
         y = "Median Daily Downloads By Week") +
    facet_wrap(~ package, ncol = 3, scale = "free_y") +
    expand_limits(y = 0) + 
    scale_color_tq(theme = "dark") +
    theme_tq() +
    theme(legend.position="none") 
plot of chunk unnamed-chunk-10

Ortalama ve standart sapmanın birbiriyle nasıl ilişkili olduğunu da araştırabiliriz. Genel olarak, günlük indirmelerdeki daha yüksek oynaklığın, daha yüksek ortalama günlük indirmelerle örtüşme eğiliminde olduğu görülmektedir.


stats_tidyverse_downloads_w %>%
    ggplot(aes(x = stdev, y = mean, color = package)) +
    geom_point() +
    geom_smooth(method = "lm") + 
    labs(title = "tidyverse packages: Mean vs standard deviation of daily downloads by week") +
    facet_wrap(~ package, ncol = 3, scale = "free") +
    scale_color_tq() +
    theme_tq() +
    theme(legend.position="none") 
plot of chunk unnamed-chunk-11

Sonuçlar

Xts‘den alınan dönem uygulama fonksiyonları, haftalık, aylık, üç aylık ve yıllık gibi ortak zaman serileri aralıklarını kullanarak birleştirmeleri uygulamak için kullanılabilir. Tidyquant’ın tq_transmute() fonksiyonu, işlevlerin verimli ve “tidy” uygulamasını sağlar. Dönem uygulama fonksiyonlarını, eğilimleri ve oynaklığı görselleştirmek ve istatistiksel ölçümler arasındaki ilişkileri ortaya çıkarmak için kullanabildik.

Kaynak: https://www.r-bloggers.com/tidy-time-series-analysis-part-1/