Nick Mihailovski, Google Analytics API Ekibi – Ekim 2009
Bu makalede, Google Analytics Data Export API'den döndürülen verilerdeki eksik zaman serisi değerlerini nasıl tespit edip dolduracağınız açıklanmaktadır.
Başlamadan Önce
Makalede, Google Analytics Dışa Veri Aktarma API'sinin işleyiş şeklini bildiğiniz varsayılmaktadır. Örnek kod Java'dadır ancak kavramları dilediğiniz dilde kullanabilirsiniz. Bu makalenin kodu açık kaynak olarak sağlanır ve proje barındırmadan indirilebilir.
Bu makaleyi okuduktan sonra şunları öğreneceksiniz:
- Google Analytics Dışa Veri Aktarma API'sının tarih boyutlarını nasıl ele aldığı.
- Sonuçları gruplandırmak ve eksik tarihleri algılamak için sorgularınızı nasıl yapılandırabilirsiniz?
- Java kullanılarak eksik değerleri doldurma.
Giriş
Belirli bir zaman aralığına ait verilerin karşılaştırılması bağlam sağlar.
Örneğin, bir web sitesinin 1 milyon dolar gelir kazandırdığını belirtmek
pek bir şey ifade etmez. Ancak bir web sitesinin gelirini çeyrek veya yıldan yıla 10 kat artırdığını belirtmek gerçekten etkileyici. Google Analytics API ile ga:date
, ga:day
ve ga:month
boyutlarını kullanarak zaman içindeki verileri kolayca görüntüleyebilirsiniz.
Sorgunuz yalnızca tarih boyutu kullanıyorsa, tarih aralığındaki herhangi bir gün hiç veri toplamıyorsa Google Analytics API, metrikler için tarihleri ve 0
değerlerini doldurur.
ga:date | ga:sessions |
---|---|
2010-03-01 | 101 |
2010-03-02 | 0 |
2010-03-03 | 69 |
Ancak, tarihi diğer boyutlarla birlikte sorgularsanız karmaşık hale gelir. Tarihlerden birinde veri yoksa API, söz konusu tarih için bir giriş DÖNMEZ. Yalnızca veri içeren bir sonraki kullanılabilir tarihe atlanır.
ga:keyword | ga:date | ga:sessions |
---|---|---|
sandalye | 2010-03-01 | 55 |
sandalye | 2010-03-03 | 48 |
Analistler, ideal olarak yukarıdaki ilk örnekte olduğu gibi, belirli bir anahtar kelime için eksik tarihlerin doldurulmasını ister.
Bu makalede, verileri pragmatik şekilde doldurmayla ilgili bazı en iyi uygulamalar açıklanmaktadır.
Arka plan
Öncelikle bu sorunun neden var olduğuna bakalım. Bunun 2 nedeni vardır.
- Google Analytics yalnızca toplanan verileri işler. Belirli bir günde bir siteye kimse gelmediyse işlenecek veri olmaz, dolayısıyla hiçbir veri döndürülmez.
- Veri içermeyen tarihler için kaç ek boyutun ve hangi değerlerin kullanılması gerektiğini belirlemek çok zordur.
Böylece Google Analytics API'si, tüm kuralları yönetecek tek bir süreç tanımlamaya çalışmak yerine, birden çok boyutu olan sorgular için veri doldurma görevini geliştiriciye bırakır. Şanslısınız :)
Programa genel bakış
Yukarıdaki grafikte verileri doldurma adımlarını aşağıda bulabilirsiniz.
- Boyutların uygun şekilde sıralandığından emin olmak için sorguyu değiştirin.
- Tarih aralığından beklenen tarihleri belirler.
- Eksik tarihleri yineleyin ve doldurun.
- Kalan eksik değerleri doldurun.
Sorguyu Değiştirme
Tarihleri doldurmak için API'den döndürülen verilerin, eksik tarih olduğunda bunu kolayca tespit etmeyi kolaylaştıran bir biçimde olduğundan emin olmamız gerekir.
Aşağıda, Mart ayındaki ilk 5 gün için hem ga:keyword
hem de ga:date
değerinin alınmasıyla ilgili örnek bir sorgu verilmiştir:
DataQuery dataQuery = new DataQuery(new URL(BASE_URL)); dataQuery.setIds(TABLE_ID); dataQuery.setStartDate("2010-03-01"); dataQuery.setEndDate("2010-03-05"); dataQuery.setDimensions("ga:keyword,ga:date"); dataQuery.setMetrics("ga:entrances");
Sorgu API'ye gönderildikten sonra sonuçlar DataEntry
nesnelerinin bir listesini içerir. Her giriş nesnesi bir veri satırını temsil eder ve boyutlar/metrikler için adlar ve değerler içerir. Herhangi bir sıralama parametresi kullanılmadığından sonuçlar rastgele bir sırayla döndürülür.
ga:keyword | ga:date | ga:entrances |
---|---|---|
sandalye | 2010-03-04 | 14 |
sandalye | 2010-03-01 | 23 |
masa | 2010-03-04 | 18 |
masa | 2010-03-02 | 24 |
sandalye | 2010-03-03 | 13 |
Hangi tarihlerin eksik olduğunu belirlemeyi kolaylaştırmak için öncelikle tüm boyutları birlikte gruplandırmamız gerekir. Bu, sorgunun sıralama parametresini orijinal sorguda kullanılan boyutlara ayarlayarak yapılabilir.
dataQuery.setSort("ga:keyword,ga:date");
Sıralama parametresi eklendiğinde API, sonuçları istenen sırada döndürür.
ga:keyword | ga:date | ga:entrances |
---|---|---|
sandalye | 2010-03-01 | 23 |
sandalye | 2010-03-03 | 13 |
sandalye | 2010-03-04 | 14 |
masa | 2010-03-02 | 24 |
masa | 2010-03-04 | 18 |
İkinci adım, her boyut için tüm tarihlerin artan düzende döndürülmesini sağlamaktır. Google Analytics API çok sayıda tarih boyutu sağlar, ancak yalnızca ga:date
tarih sınırları içinde doğru bir şekilde sıralanabilir (ör. gün, ay, yıl). Bu nedenle, tarihleri doldurmak isterseniz sorgunuzun hem boyutlarda hem de sıralama sorgu parametrelerinde ga:date
boyutunu kullandığından emin olun.
Sıralanan sorgu yürütüldüğünde, aynı açılış sayfalarının tümü yan yana döndürülür ve tarihler sıralı olarak gösterilir. Tek bir açılış sayfasındaki tarih listesi, bir zaman serisi olarak düşünülebilir ve sıralı oldukları için eksik tarihleri tespit etmek çok daha kolaydır.
Beklenen Tarihleri Belirleyin
Eksik tarihleri tespit etmek için API'den döndürülen gerçek tarihleri her zaman serisinde beklenen tarihlerle karşılaştırmamız gerekir. Aşağıdakilerden nelerin beklendiğini anlayabiliriz:
- Beklenen başlangıç tarihi, API sorgusundan belirleniyor.
- Sorgu tarih aralığındaki beklenen gün sayısını sayma.
Her iki değer de tarih aralığındaki her gün için başlangıç tarihini 1 artırarak beklenen her bir tarihi belirlemek için birlikte kullanılabilir.
Beklenen Başlangıç Tarihini Belirleme
start-date
sorgu parametresini, dizinin beklenen başlangıç tarihi olarak kullanabiliriz. yyyyMMdd
API yanıtında döndürülen tarih biçimi, yyyy-MM-dd
sorgu parametresinin biçiminden farklı olduğundan, kullanabilmemiz için önce tarih biçimini dönüştürmemiz gerekir.
setExpectedStartDate
yöntemi, tarih biçimlerini dönüştürür.
private static SimpleDateFormat queryDateFormat = new SimpleDateFormat("yyyy-MM-dd"); private static SimpleDateFormat resultDateFormat = new SimpleDateFormat("yyyyMMdd"); public void setExpectedStartDate(String startDate) { try { calendar.setTime(queryDateFormat.parse(startDate)); expectedStartDate = resultDateFormat.format(calendar.getTime()); } catch (ParseException e) { handleException(e); } }
Beklenen Gün Sayısını Sayma
Program, tarih aralığındaki gün sayısını almak için başlangıç ve bitiş tarihlerini Java Date
nesnelerine ayrıştırır. Ardından, her iki tarih arasındaki saati anlamak için bir Calendar
nesnesi kullanır. Sayıyı dahil etmek için tarihlerdeki farka bir gün eklenir.
private static final long millisInDay = 24 * 60 * 60 * 1000; public void setNumberOfDays(DataQuery dataQuery) { long startDay = 0; long endDay = 0; try { calendar.setTime(queryDateFormat.parse(dataQuery.getStartDate())); startDay = calendar.getTimeInMillis() / millisInDay; calendar.setTime(queryDateFormat.parse(dataQuery.getEndDate())); endDay = calendar.getTimeInMillis() / millisInDay; } catch (ParseException e) { handleException(e); } numberOfDays = (int) (endDay - startDay + 1); }
Artık hangi tarihlerin eksik olduğunu anlamak için ihtiyacımız olan tüm verilere sahibiz.
Sonuçlardaki Her Zaman Serisini Tanımlayın
Sorgu yürütüldüğünde, program API yanıtındaki her bir DataEntry
nesnesini inceler. Sorgu başlangıçta sıralandığından, yanıtta her anahtar kelime için kısmi bir zaman serisi olur. Dolayısıyla, her zaman serisinin başlangıcını bulmamız, ardından her tarihin üzerinden geçip API tarafından döndürülmeyen eksik verileri doldurmamız gerekir.
Bu program, her bir dizinin başlangıcını algılamak için dimensionValue
ve tmpDimensionValue
değişkenlerini kullanır.
Yanıtı işlemek için gereken kodun tamamı aşağıda verilmiştir. Eksik verilerin doldurulması aşağıda açıklanmaktadır.
public void printBackfilledResults(DataFeed dataFeed) { String expectedDate = ""; String dimensionValue = ""; List<Integer> row = null; for (DataEntry entry : dataFeed.getEntries()) { String tmpDimValue = entry.getDimensions().get(0).getValue(); // Detect beginning of a series. if (!tmpDimValue.equals(dimensionValue)) { if (row != null) { forwardFillRow(row); printRow(dimensionValue, row); } // Create a new row. row = new ArrayList<Integer>(numberOfDays); dimensionValue = tmpDimValue; expectedDate = expectedStartDate; } // Backfill row. String foundDate = entry.getDimension("ga:date").getValue(); if (!foundDate.equals(expectedDate)) { backFillRow(expectedDate, foundDate, row); } // Handle the data. Metric metric = entry.getMetrics().get(0); row.add(new Integer(metric.getValue())); expectedDate = getNextDate(foundDate); } // Handle the last row. if (row != null) { forwardFillRow(row); printRow(dimensionValue, row); } }
Eksik Tarihleri Doldurun
Program, bir serideki her giriş için metrik değerlerini (girişler) row
adlı bir ArrayList
içinde depolar. Yeni bir zaman serisi algılandığında yeni bir satır oluşturulur ve beklenen tarih, beklenen başlangıç tarihine ayarlanır.
Program, her bir giriş için, girişteki tarih değerinin beklenen tarihe eşit olup olmadığını kontrol eder. Bunlar eşitse girişteki metrik satıra eklenir. Aksi takdirde, program, doldurulması gereken tarihlerin eksik olduğunu tespit etmiştir.
backfillRow
yöntemi, verileri doldurmayı işler. Mevcut satırın yanı sıra beklenen ve bulunan tarihleri parametre olarak kabul eder.
Daha sonra, iki tarih arasındaki gün sayısını (dahil olmayan) belirler ve satıra birçok 0 ekler.
public void backFillRow(String startDate, String endDate, List<Integer> row) { long d1 = 0; long d2 = 0; try { calendar.setTime(resultDateFormat.parse(startDate)); d1 = calendar.getTimeInMillis() / millisInDay; calendar.setTime(resultDateFormat.parse(endDate)); d2 = calendar.getTimeInMillis() / millisInDay; } catch (ParseException e) { handleException(e); } long differenceInDays = d2 - d1; if (differenceInDays > 0) { for (int i = 0; i < differenceInDays; i++) { row.add(0); } } }
Yöntem tamamlandığında, satır verilerle doldurulur ve mevcut veriler eklenebilir. Daha sonra, beklenen tarih getNextDate
yöntemi kullanılarak, bulunan tarihten bir gün sonrasına artırılır.
public String getNextDate(String initialDate) { try { calendar.setTime(resultDateFormat.parse(initialDate)); calendar.add(Calendar.DATE, 1); return resultDateFormat.format(calendar.getTime()); } catch (ParseException e) { handleException(e); } return ""; }
Kalan Değerleri Doldurun
Seri verileri row
olarak işlendikten sonra, serinin sonunda başka eksik tarih olup olmadığını kontrol etmemiz gerekir.
forwardFillRow
yöntemi, orijinal sorgudaki gün sayısı ile satırın mevcut boyutu arasındaki farkı hesaplar ve bu sayıyı satırın sonuna ekler.
public void forwardFillRow(List<Integer> row) { int remainingElements = numberOfDays - row.size(); if (remainingElements > 0) { for (int i = 0; i < remainingElements; i++) { row.add(0); } } }
Program bu noktada, zaman serisindeki eksik değerleri doldurmuştur. Artık tüm verilere sahip olduğumuza göre, program, boyut ve metrik değerlerini virgülle ayrılmış bir liste olarak yazdırır.
Sonuç
Bu örneği kullanarak, API tarafından döndürülmeyen tarihlere kolayca veri doldurabilirsiniz. Yukarıda belirtildiği gibi bu çözüm herhangi bir programlama diline uyarlanabilir. Hatta geliştiriciler bu teknikleri uyarlayabilir ve birden fazla boyutu ve metriği yönetmek için uygulayabilir. Google Analytics API tarafından döndürülen zaman serileri üzerinde gelişmiş analiz yapmaya başlamak artık her zamankinden daha kolay.