Nick Mihailovski ทีม Google Analytics API – ตุลาคม 2009
บทความนี้อธิบายวิธีตรวจหาและทดแทนค่าอนุกรมเวลาที่ขาดหายไปในข้อมูลที่แสดงผลจาก API การส่งออกข้อมูลของ Google Analytics
ก่อนที่คุณจะเริ่มต้น
บทความนี้จะถือว่าคุณทราบวิธีการทำงานของ API การส่งออกข้อมูลของ Google Analytics โค้ดตัวอย่างจะอยู่ใน Java แต่คุณใช้แนวคิดในภาษาที่เลือกได้ โค้ดสำหรับบทความนี้จัดเตรียมไว้ให้เป็นโอเพนซอร์สและ ดาวน์โหลดได้จากการโฮสต์โปรเจ็กต์
หลังจากอ่านบทความนี้ คุณจะได้เรียนรู้เรื่องต่อไปนี้
- วิธีที่ API การส่งออกข้อมูลของ Google Analytics จัดการกับมิติข้อมูลวันที่
- วิธีจัดโครงสร้างคำค้นหาเพื่อจัดกลุ่มผลลัพธ์และตรวจหาวันที่หายไป
- วิธีกรอกค่าที่ขาดหายไปโดยใช้ Java
เกริ่นนำ
การเปรียบเทียบข้อมูลในช่วงระยะเวลาหนึ่งจะให้บริบท
เช่น การระบุว่าเว็บไซต์หนึ่งสร้างรายได้ 1 ล้านเหรียญสหรัฐไม่ได้หมายความว่าจะมีรายได้เท่าใด แต่การบอกว่าเว็บไซต์มีรายได้เพิ่มขึ้น 10 เท่าเทียบกับไตรมาสก่อนหน้าแบบปีต่อปีเป็นเรื่องที่น่าประทับใจจริงๆ API ของ Google Analytics ช่วยให้คุณพล็อตข้อมูลเมื่อเวลาผ่านไปได้ง่ายๆ โดยใช้มิติข้อมูล ga:date
, ga:day
และ ga:month
หากคำค้นหาใช้มิติข้อมูลวันที่เท่านั้น หากมีวันใดในช่วงวันที่รวบรวมข้อมูลเป็น 0 Google Analytics API จะทดแทนข้อมูลวันที่และค่า 0
สำหรับเมตริก
ga:date | ga:sessions |
---|---|
2010-03-01 | 101 |
2010-03-02 | 0 |
2010-03-03 | 69 |
อย่างไรก็ตาม จะเป็นเรื่องยากหากคุณค้นหาวันที่ร่วมกับมิติข้อมูลอื่นๆ หากวันที่ใดวันที่หนึ่งไม่มีข้อมูล API จะไม่แสดงรายการสำหรับวันที่นั้น แต่จะข้ามไปยังวันที่ว่างถัดไปที่มีข้อมูล
ga:keyword | ga:date | ga:sessions |
---|---|---|
เก้าอี้ | 2010-03-01 | 55 |
เก้าอี้ | 2010-03-03 | 48 |
ตามหลักการแล้ว นักวิเคราะห์ควรระบุวันที่ที่ขาดหายไปสำหรับคีย์เวิร์ดหนึ่งๆ ซึ่งกรอกให้เหมือนกับตัวอย่างแรกด้านบน
บทความนี้จะอธิบายแนวทางปฏิบัติแนะนำสำหรับการทดแทนข้อมูลในทางปฏิบัติ
ที่มา
ก่อนอื่น ลองมาดูสาเหตุของปัญหานี้กัน ซึ่งมี 2 สาเหตุ
- Google Analytics จะประมวลผลข้อมูลที่รวบรวมไว้เท่านั้น หากไม่มีใครมาที่เว็บไซต์ในวันใดวันหนึ่ง จะไม่มีข้อมูลให้ประมวลผล จึงไม่มีข้อมูลแสดงขึ้นมา
- การกำหนดจำนวนมิติข้อมูลเพิ่มเติมและค่าที่ควรใช้สำหรับวันที่ไม่มีข้อมูลนั้นทำได้ยากมาก
ดังนั้นแทนที่จะพยายามกำหนดกระบวนการเพียงกระบวนการเดียวเพื่อกฎเกณฑ์ทั้งหมด แต่ Google Analytics API จะปล่อยให้นักพัฒนาซอฟต์แวร์กรอกข้อมูลสำหรับคำค้นหาที่มีมิติข้อมูลหลายรายการได้ โชคดีจัง :)
ภาพรวมของโปรแกรม
ขั้นตอนการทดแทนข้อมูลในแผนภูมิด้านบนมีดังนี้
- แก้ไขการค้นหาเพื่อให้ระบบจัดเรียงมิติข้อมูลตามโอกาส
- ระบุวันที่ที่คาดไว้จากช่วงวันที่
- ทำซ้ำและทดแทนข้อมูลวันที่ที่ขาดหายไป
- กรอกค่าที่เหลือที่ยังขาดอยู่
แก้ไขคำค้นหา
ในการทดแทนวันที่ เราต้องตรวจสอบว่าข้อมูลที่แสดงผลจาก API อยู่ในรูปแบบที่ช่วยให้ตรวจหาได้ง่ายว่าข้อมูลวันที่ขาดหายไปเมื่อใด
ตัวอย่างการค้นหาที่ใช้เรียกข้อมูลทั้ง ga:keyword
และ ga:date
ในช่วง 5 วันแรกในเดือนมีนาคมมีดังนี้
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");
เมื่อระบบส่งการค้นหาไปยัง API แล้ว ผลลัพธ์จะมีรายการออบเจ็กต์ DataEntry
รายการ ออบเจ็กต์รายการแต่ละรายการแสดงแถวข้อมูล โดยมีชื่อและค่าสำหรับมิติข้อมูล/เมตริก เนื่องจากไม่ได้ใช้พารามิเตอร์การจัดเรียง ผลการค้นหาจึงแสดงในลำดับที่กําหนดเอง
ga:keyword | ga:date | ga:entrances |
---|---|---|
เก้าอี้ | 2010-03-04 | 14 |
เก้าอี้ | 2010-03-01 | 23 |
โต๊ะ | 2010-03-04 | 18 |
โต๊ะ | 2010-03-02 | 24 |
เก้าอี้ | 2010-03-03 | 13 |
เราต้องจัดกลุ่มมิติข้อมูลทั้งหมดไว้ด้วยกันก่อน เพื่อให้ระบุวันที่ที่หายไปได้ง่ายขึ้น ซึ่งทำได้โดยการตั้งค่าพารามิเตอร์การจัดเรียงของการค้นหาเป็นมิติข้อมูลที่ใช้ในการค้นหาเดิม
dataQuery.setSort("ga:keyword,ga:date");
การเพิ่มพารามิเตอร์การจัดเรียงจะทำให้ API แสดงผลลัพธ์ในลำดับที่ต้องการ
ga:keyword | ga:date | ga:entrances |
---|---|---|
เก้าอี้ | 2010-03-01 | 23 |
เก้าอี้ | 2010-03-03 | 13 |
เก้าอี้ | 2010-03-04 | 14 |
โต๊ะ | 2010-03-02 | 24 |
โต๊ะ | 2010-03-04 | 18 |
ขั้นตอนที่ 2 คือการตรวจสอบว่ามิติข้อมูลทุกรายการจะแสดงวันที่ทั้งหมดตามลําดับจากน้อยไปมาก แม้ว่า Google Analytics API จะมีมิติข้อมูลวันที่อยู่จำนวนหนึ่ง แต่คุณจัดเรียงเฉพาะ ga:date
ในขอบเขตวันที่ได้อย่างแม่นยำเท่านั้น (เช่น วัน เดือน ปี) ดังนั้นหากต้องการทดแทนวันที่ ให้ตรวจสอบว่าคำค้นหาใช้มิติข้อมูล ga:date
ทั้งในมิติข้อมูลและการจัดเรียงพารามิเตอร์การค้นหา
เมื่อเรียกใช้การค้นหาที่จัดเรียงแล้ว หน้า Landing Page เดียวกันทั้งหมดจะแสดงผลอยู่ติดกัน และวันที่จะอยู่ในลำดับ รายการวันที่สำหรับหน้า Landing Page หน้าเดียวอาจถือเป็นอนุกรมเวลา และเนื่องจากวันที่เหล่านั้นมีลำดับเหตุการณ์ จึงสามารถระบุวันที่ที่ขาดหายไปได้ง่ายขึ้นมาก
ระบุวันที่ที่คาดไว้
ในการตรวจหาวันที่ที่ขาดหายไป เราจำเป็นต้องเปรียบเทียบวันที่จริงที่ได้จาก API กับวันที่ที่คาดไว้ในอนุกรมเวลาทั้งหมด เราสามารถทราบได้ว่าสิ่งใดที่เราคาดหวังจากสิ่งต่อไปนี้
- การกำหนดวันที่เริ่มต้นที่คาดไว้จากการค้นหา API
- นับจำนวนวันที่คาดว่าจะได้รับในช่วงวันที่ของการค้นหา
คุณใช้ทั้ง 2 ค่าร่วมกันเพื่อกำหนดวันที่ที่คาดไว้แต่ละวันได้โดยเพิ่มวันที่เริ่มต้นเป็น 1 สำหรับแต่ละวันในช่วงวันที่
การกำหนดวันที่เริ่มต้นที่คาดไว้
เราใช้พารามิเตอร์การค้นหา start-date
เป็นวันที่เริ่มต้นที่คาดไว้ของชุดหนังสือได้ เนื่องจากรูปแบบวันที่ที่แสดงผลในการตอบกลับของ API yyyyMMdd
แตกต่างจากรูปแบบของพารามิเตอร์การค้นหา yyyy-MM-dd
เราจึงต้องแปลงรูปแบบวันที่ก่อน จึงจะใช้งานได้
เมธอด setExpectedStartDate
จะแปลงรูปแบบของวันที่
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); } }
การนับจำนวนวันที่คาดว่าจะได้รับ
หากต้องการทราบจำนวนวันในช่วงวันที่ โปรแกรมจะแยกวิเคราะห์วันที่เริ่มต้นและวันที่สิ้นสุดเป็นออบเจ็กต์ Java Date
จากนั้นใช้ออบเจ็กต์ Calendar
เพื่อหาเวลาระหว่างวันที่ทั้ง 2 วัน ระบบจะเพิ่ม 1 วันลงในความแตกต่างของวันที่เพื่อให้นับรวมด้วย
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); }
ตอนนี้เรามีข้อมูลทั้งหมดที่จำเป็นต้องใช้เพื่อค้นหาวันที่ที่หายไป
ระบุอนุกรมเวลาแต่ละชุดในผลลัพธ์
เมื่อระบบเรียกใช้การค้นหา โปรแกรมจะผ่านออบเจ็กต์ DataEntry
แต่ละรายการในการตอบสนองของ API เนื่องจากมีการจัดเรียงคำค้นหาในขั้นต้น การตอบกลับจะมีอนุกรมเวลาบางส่วนสำหรับคีย์เวิร์ดแต่ละคำ เราจึงต้องค้นหาจุดเริ่มต้นของอนุกรมเวลาแต่ละชุด จากนั้นตรวจสอบแต่ละวันที่และกรอกข้อมูลที่ขาดหายไปซึ่ง API ไม่ได้ส่งคืน
โปรแกรมนี้ใช้ตัวแปร dimensionValue
และ tmpDimensionValue
เพื่อตรวจหาจุดเริ่มต้นของแต่ละชุด
ต่อไปนี้เป็นโค้ดทั้งหมดที่ใช้จัดการคำตอบได้ เราจะอธิบายเกี่ยวกับการกรอกข้อมูลที่ขาดหายไปด้านล่าง
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); } }
ทดแทนข้อมูลวันที่ที่ขาดหายไป
สำหรับแต่ละรายการในชุด โปรแกรมจะจัดเก็บค่าเมตริก (รายการเข้า) ไว้ใน ArrayList
ที่เรียกว่า row
เมื่อตรวจพบอนุกรมเวลาใหม่ ระบบจะสร้างแถวใหม่และตั้งค่าวันที่ที่คาดไว้เป็นวันที่เริ่มต้นที่คาดไว้
จากนั้นโปรแกรมจะตรวจสอบว่าค่าวันที่ในแต่ละรายการตรงกับวันที่ที่คาดไว้หรือไม่สำหรับแต่ละรายการ หากเท่ากัน ระบบจะเพิ่มเมตริกในรายการลงในแถว มิเช่นนั้น โปรแกรมตรวจพบวันที่ที่ขาดหายไปซึ่งจำเป็นต้องทดแทนข้อมูล
เมธอด backfillRow
จะจัดการการทดแทนข้อมูล ยอมรับพารามิเตอร์วันที่ที่คาดไว้และวันที่พบ รวมถึงแถวปัจจุบัน
จากนั้นจะกำหนดจำนวนวันระหว่างวันที่ 2 วันที่นั้น (ไม่รวม) และเพิ่ม 0 จำนวนมากลงในแถว
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); } } }
เมื่อดำเนินการเสร็จแล้ว ระบบจะทดแทนแถวด้วยข้อมูลและเพิ่มข้อมูลปัจจุบันได้ ระบบจะเพิ่มวันที่ที่คาดไว้เป็น 1 วันหลังจากวันที่พบโดยใช้เมธอด getNextDate
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 ""; }
กรอกค่าที่เหลืออยู่
เมื่อประมวลผลข้อมูลชุดหนังสือเป็น row
แล้ว เราจะต้องตรวจสอบว่าไม่มีวันที่ที่ขาดหายไปในตอนท้ายของชุดหนังสืออีก
เมธอด forwardFillRow
จะแค่คำนวณความแตกต่างระหว่างจำนวนวันในการค้นหาเดิมกับขนาดปัจจุบันของแถว แล้วบวก 0 จำนวนนั้นต่อท้ายแถว
public void forwardFillRow(List<Integer> row) { int remainingElements = numberOfDays - row.size(); if (remainingElements > 0) { for (int i = 0; i < remainingElements; i++) { row.add(0); } } }
ณ จุดนี้ โปรแกรมได้เติมค่าที่ขาดหายไปในอนุกรมเวลาแล้ว เมื่อเรามีข้อมูลทั้งหมดแล้ว โปรแกรมจะพิมพ์ค่ามิติข้อมูลและเมตริกเป็นรายการที่คั่นด้วยเครื่องหมายจุลภาค
บทสรุป
เมื่อใช้ตัวอย่างนี้ คุณสามารถทดแทนข้อมูลในวันที่ API ไม่ได้แสดงผลได้อย่างง่ายดาย ดังที่กล่าวไว้ข้างต้น โซลูชันนี้นำไปปรับใช้กับภาษาโปรแกรมใดก็ได้ นักพัฒนาซอฟต์แวร์ยังปรับและประยุกต์ใช้เทคนิคเหล่านี้เพื่อจัดการกับมิติข้อมูลและเมตริกหลายรายการได้อีกด้วย ตอนนี้คุณสามารถเริ่มวิเคราะห์ขั้นสูงเกี่ยวกับอนุกรมเวลาที่แสดงผลโดย Google Analytics API ได้ง่ายกว่าที่เคย