[데브인턴십 3기] 데이터 분석을 위한 Tableau 사용 후기

최재원

업데이트:

배경

띵스플로우에서 운영 중인 앱의 데이터는 현재 BigQuery로 옮겨져서 시간이 지날수록 많은 양으로 쌓이고 있고, 이러한 데이터를 관련 개발자 혹은 협업자가 SQL을 사용해서 필요한 정보를 추출해 가는 형식입니다. 하지만 이렇게 필요한 정보를 얻어간다고 해도 이 데이터를 시각화 하는 것은 어렵습니다. 나아가 비교 분석을 위해서 여러번 쿼리를 실행 시켜야 하는 등 단점도 존재합니다. 또한 개발자가 아닌 협업자는 쿼리를 통해 데이터를 추출 및 분석하는데 어려움이 존재합니다.

따라서 이러한 문제를 해결하기 위해 Tableau라는 프로그램을 사용합니다.

image

개념 및 서버(데이터) 연결

Tableau란 데이터 시각화 프로그램으로서 빠르고 쉬운 데이터 시각화를 제공하면서 동시에 간단한 분석까지 가능하게 해주는 도구입니다. Tableau는 시각화 화면끼리 상호작용을 하는 인터렉티브 시각화도 제공을 해주며, Tableau 프로그램 자체에 내장 되어 있는 함수들과 분석 기능들을 활용하여 분석도 가능합니다.

image

image

현재 띵스플로우에서 사용하는 Tableau는 크게 두가지 Tableau Desktop과 Tableau Online으로 나눌 수 있습니다. Tableau Desktop은 서버에 저장된 데이터 원본을(띵스플로우에서는 Google BigQuery) 직접 연결해 분석 및 시각화를 할 수 있습니다. 위 사진과 같이 Tableau Desktop이 켜져 있고 Google BigQuery에 연결된 것을 확인할 수 있습니다. BigQuery로 연결 후 프로젝트, 데이터 집합을 설정하면 데이터 원본 페이지에 데이터가 업로드 되는 것을 확인할 수 있습니다.

image

Tableau Online은 클라우드 기반으로 제공되는 분석 플랫폼입니다. Tableau Desktop에서 대시보드 또는 시트 등을 게시하면 사용자 및 협업자들은 언제 어디서나 다양한 기기(모바일 앱 포함)를 통해 접속 가능하고, 여러 기능들을 통해 데이터 분석이 가능하게 해줍니다. 현재 띵스플로우에서는 데이터 엔지니어가 Tableau Desktop을 통해서 여러 데이터들을 시각화 하고, 대시보드를 공유하면 협업자들은 Tableau Online을 통해서 시각화한 대시보드를 보고 이용하고 있습니다.

사용법

Tableau로 가져올 원본 데이터를 서버 혹은 파일에서 연결하고 난 후, 본격적으로 데이터 시각화 및 분석을 시작합니다. 서버에 연결한 후 빅쿼리에서 원하는 데이터를 간단한 SQL문을 이용해서 가져오겠습니다.

테이블 만들기

SELECT * 
FROM `storyplay-4fe65.analytics_250448727.pivot_events_*` 
WHERE _TABLE_SUFFIX BETWEEN REGEXP_REPLACE(STRING(TIMESTAMP(<매개 변수.시작일>)),"-","") 
	AND REGEXP_REPLACE(STRING(TIMESTAMP(<매개 변수.종료일>)),"-","")
  • 위 코드에서 기존 SQL문에 Tableau가 제공하는 매개 변수 삽입이라는 기능을 통해서 원하는 매개 변수를 추가했습니다. 추후에 대시보드에서 사용자들이 직접 원하는 조건을 설정할 수 있도록 편의를 제공해 줍니다.

image

  • 예시에는 사용자가 원하는 기간을 따로 설정할 수 있게 매개변수 시작일 및 종료일을 추가해 주었습니다.

image

원하는 데이터를 쿼리를 통해 설정해 주면 위와 같이 자동으로 BigQuery에 있는 데이터들을 Tableau에서 볼 수 있습니다. Tableau는 이처럼 연결된 서버의 데이터를 Tableau 데이터 원본으로 사용합니다. 하지만 Tableau 내부에서 자체적으로 원본 데이터를 수정할 수는 없습니다.

다중 테이블 분석을 위한 데이터 결합(관계 생성)

WITH all_cte AS(
    SELECT story_id, chapter, COUNT(DISTINCT user_id) AS user
    FROM `storyplay-4fe65.analytics_250448727.pivot_events_*`
    WHERE _TABLE_SUFFIX BETWEEN REGEXP_REPLACE(STRING(TIMESTAMP(<매개 변수.시작일>)),"-","") AND REGEXP_REPLACE(STRING(TIMESTAMP(<매개 변수.종료일>)),"-","") 
            AND event_name = 'start_chapter' 
            AND chapter >= <매개 변수.시작(기준) 회차>
            AND chapter BETWEEN <매개 변수.시작(기준) 회차> AND <매개 변수.종료 회차>
    GROUP BY story_id, chapter
    ORDER BY story_id, chapter
),
base_cte AS(
    SELECT story_id, chapter, COUNT(DISTINCT user_id) AS user_base
    FROM `storyplay-4fe65.analytics_250448727.pivot_events_*`
    WHERE _TABLE_SUFFIX BETWEEN REGEXP_REPLACE(STRING(TIMESTAMP(<매개 변수.시작일>)),"-","") AND REGEXP_REPLACE(STRING(TIMESTAMP(<매개 변수.종료일>)),"-","") 
            AND event_name = 'start_chapter' 
            AND chapter =  <매개 변수.시작(기준) 회차>
            AND chapter BETWEEN <매개 변수.시작(기준) 회차> AND <매개 변수.종료 회차>
    GROUP BY story_id, chapter
    ORDER BY story_id, chapter
),
event_cte AS(
    SELECT story_id, chapter, COUNT(*) AS event_count
    FROM `storyplay-4fe65.analytics_250448727.pivot_events_*`
    WHERE
        _TABLE_SUFFIX BETWEEN REGEXP_REPLACE(STRING(TIMESTAMP(<매개 변수.시작일>)),"-","") AND REGEXP_REPLACE(STRING(TIMESTAMP(<매개 변수.종료일>)),"-","")
        AND event_name = 'start_chapter'
        AND chapter >=  <매개 변수.시작(기준) 회차>
        AND chapter BETWEEN <매개 변수.시작(기준) 회차> AND <매개 변수.종료 회차>
    GROUP BY story_id, chapter
    ORDER BY story_id, chapter
),
event_base_cte AS(
    SELECT story_id, chapter, COUNT(*) AS event_count_base
    FROM `storyplay-4fe65.analytics_250448727.pivot_events_*`
    WHERE
        _TABLE_SUFFIX BETWEEN REGEXP_REPLACE(STRING(TIMESTAMP(<매개 변수.시작일>)),"-","") AND REGEXP_REPLACE(STRING(TIMESTAMP(<매개 변수.종료일>)),"-","")
        AND event_name = 'start_chapter' 
        AND chapter =  <매개 변수.시작(기준) 회차>
        AND chapter BETWEEN <매개 변수.시작(기준) 회차> AND <매개 변수.종료 회차>
    GROUP BY story_id, chapter
    ORDER BY story_id, chapter
),
event_union AS (
    SELECT A.story_id, A.chapter, A.event_count, B.event_count_base, (A.event_count / B.event_count_base * 100) AS event_retention
    FROM event_cte A JOIN event_base_cte B ON A.story_id = B.story_id
    ORDER BY story_id, chapter    
),
story_union AS (
	SELECT A.story_id, A.chapter, A.user , B.user_base, (A.user / B.user_base * 100) AS user_retention
	FROM all_cte AS A JOIN base_cte AS B ON A.story_id = B.story_id 
	ORDER BY story_id, chapter
)   
SELECT A.story_id, A.chapter, A.user, A.user_base, B.event_count, B.event_count_base, A.user_retention, B.event_retention
FROM story_union A FULL OUTER JOIN event_union B ON A.story_id = B.story_id AND A.chapter = B.chapter
ORDER BY story_id, chapter

스토리플레이 작품별 사용자, 이벤트 전환율을 나타내 주는 코드를 작성해 보았습니다.

  • 사용자가 추후에 기간 설정이 가능하게 매개 변수를 추가했습니다.
  • 사용자가 전환율 기준 회차 및 회차 범위를 설정할 수 있도록(기존 전환율은 1회 기준) 매개 변수 시작(기준) 회차 및 종료 회차를 추가했습니다

    image

image

이처럼 SQL문을 작성하고 나면 테이블이 생성되고 Tableau에서 자동으로 관계를 생성해 줍니다. 관계는 다중 테이블 분석을 위해 데이터를 결합하는 방법입니다.

  • 기존의 조인 작동 방식과 달리, 관계는 결합된 형태로 테이블을 저장하지 않습니다.
  • 관계에서 사용된 테이블 전체를 확인할 방법이 없습니다.

데이터 시각화(시트)

앞 두 단계를 걸쳐서 visualization에 사용할 데이터 원본 연결 및 사용자 지정 SQL문을 통한 테이블 생성을 마쳤다면 워크시트에서 측정 값들을 확인할 수 있으며 행과 열 선반 및 차트 생성 부분에서 데이터 형태를 확인할 수 있습니다.

시트에서 시각화 및 분석에 필요한 요소:

image

  • 차원 및 측정값 ⇒ 데이터 원본으로부터 Tableau가 자동으로 인식하여 시트에 표시(시트 왼쪽, 명칭은 임의로 지어놨습니다. 명칭 또한 변경 가능하고 추가로 측정값은 별칭 설정 또한 가능합니다.)

image

  • 행과 열 선반 및 차트 생성부분 ⇒ 데이터 표현 방식에 따라서 행과 열에 나타낼 차원 또는 측정값을 넣어줄 수 있습니다. 또한 오른쪽에 보이는 작품, 시작일, 종료일, 시작 회차, 종료 회차는 앞서 SQL문을 작성할 때 넣어준 매개 변수로서 사용자가 직접 조정하며 설정할 수 있게 차트에 표시를 해줍니다.

image

  • 마크 카드 설정을 통해서 데이터에 대한 특징을 표시할 수 있다. 위 사진에서는 작품에 따라서 색깔을 다르게 하고 마우스를 가져댔을 때 보이는 상세 특징 등을 설정해 주었다.
  • 스토리플레이 작품을 필터 설정을 해서 사용자가 추후에 지표를 확인하고 싶은 작품만 볼 수 있도록 설정해 주었습니다.

image

image

  • 축 디테일 설정도 가능합니다. 위 사진에서는 세로축(전환율)에 관해서 범위 조정, 제목 그리고 숫자 표시 형식 등을 설정해 주었습니다.

image

image

  • Tableau에서 제공하는 분석 기능을 이용해서 차트에 간단한 분석 기능도 추가할 수 있습니다. 위 사진에서는 두 개의 작품에 대해 기존 회차 전환율 차트에서 추체선(점선)을 표시해서 분석할 수 있도록 했습니다.

대시보드 생성

이렇듯 여러 기능을 사용하여 원하는 시각화 시트를 만들고 나면, 대시보드를 통해 분석했던 시트들을 한 페이지에 정리할 수 있습니다.

image

  • 여러 시각화 화면을 대시보드에 모아두고 나서 중요한 점은 필터 및 매개 변수 항목을 모든 워크시트에 적용시켜 주는 것입니다. 모든 워크시트에 적용을 안해주면 비교 및 분석을 할 때 동시에 적용되지 않습니다. 아래 사진처럼 워크시트에 적용 → 관련 데이터 원본을 사용하는 모든 항목에 체크해 주시면 됩니다.

    image

완성된 대시보드 Tableau Online(서버) 업로드

제목, 이미지 등 필요한 디테일 요소들을 마무리 하고 나면 대시보드가 완성이 됩니다. 이렇게 완료한 대시보드는 현재 데이터 엔지니어가 작업하고 있는 로컬 환경(Tableau Desktop)에 저장이 되었고, 이제 협업자들이 볼 수 있도록 서버에 올려주어야 합니다.

image

  • 서버와 연동해서 올리는 방법은 간단합니다. Tableau 상단에 공유 버튼을 누르면 아래와 같이 창이 뜨고 게시하고 싶은 대시보드 및 시트를 고르고 나서 “게시” 버튼을 누르면 Tableau Desktop이 서버에 요청 후 성공적으로 Tableau Online으로 게시가 완료됩니다.

image

  • 위 사진은 Tableau Online에 게시된 띵스플로우 스토리플레이 관련 대시보드들이며 다양한 지표 확인 및 분석이 가능합니다.

결과

image

image

  • 대시보드를 들어가게 되면 위 사진들처럼 사용자는 필터 및 변수를 자유자재로 사용해서 원하는 지표를 얻어내고 나아가 분석까지 해서 의사결정에 도움이 될 것 같습니다.
  • 추가적으로 협업자가 보다 쉽게 사용할 수 있게 “스토리플레이 대시보드 사용법” 문서를 작성해서 대시보드 이용 가이드라인이 되도록 하였습니다.

마치며

Tableau를 이용해서 데이터 분석 및 시각화를 진행해 보았습니다. 데이터 엔지니어 인턴으로 입사하게 되면서 데이터 추출 및 가공에 집중해서 업무를 진행할 것이라 생각했습니다. 그렇지만 예상 범위를 넘어서 실제 회사 어플리케이션 데이터들을 이렇게 유의미한 지표로 시각화 하는 업무도 같이 진행을 했고, 저에게 있어서 매우 도움이 되었습니다. 또한 결과물이 나올 때마다 스스로 성장하는 느낌이었습니다.

Tableau 프로그램 자체가 별도의 프로그래밍을 요구하지 않고 드래그 앤 드롭 형식으로 시트 및 대시보드를 만들 수 있어도 처음 진입장벽은 높았습니다. 나아가 유료로만 제공되는 프로그램이어서 이전에 접할 기회도 많지 않았습니다. 그렇지만 이것저것 만지면서 익숙해 지고 나서는 매우 유용한 툴이라는 것을 알게 되었고, 앞으로 Tableau에 내장 되어 있는 더욱 많은 기능들을 공부해 실전에 활용하겠습니다. 최종적으로 여러 협업자들이 데이터 기반으로 의사결정을 할 시 도움이 되는 유의미한 지표를 만들 수 있는 데이터 엔지니어가 되도록 하겠습니다.

읽어 주셔서 감사하고 앞으로 Tableau를 사용하는데 있어서 도움이 되었으면 좋겠습니다. 추운 날씨 건강 조심하세요. 감사합니다!

띵스플로우 팀은 자기의 일을 좋아하고 잘하는 사람들 입니다. 사용자와 서비스를 중심으로 빠르게 실행하고 학습하며, 다양한 직무의 사람들이 협업을 통해 시너지를 내고 있습니다. 다양한 콘텐츠 혁신을 이루고 있는 띵스플로우 팀에 함께할 분을 찾습니다! 언제든 people@thingsflow.com로 이메일을 주시기 바랍니다!

태그:

카테고리:

업데이트:

댓글남기기