p.20
분석은 단순히 적절한 방법론을 사용해 정확한 숫자를 만들어내는 일 이상을 의미합니다. 분석이란 호기심을 갖고 '왜' 그 숫자가 나왔는지 질문을 던지는 일입니다. 또한 다양한 패턴과 이례적인 현상들 그리고 비즈니스가 어떻게 움직이고 인간이 어떻게 행동하는지 이해하기 위한 단서를 찾고 해석하는 일입니다.
p.29~30
분석 업무는 항상 질문을 던지는 데서 시작합니다. 예를 들어, '신규 고객이 얼마나 유입됐는가?', '판매 추이가 어떠한가?', '왜 어떤 고객은 한번 서비스를 이용한 후 다시 돌아오지 않는 반면, 어떤 고객은 지속해서 서비스를 사용하는가?' 등의 질문이 생기고 나면 데이터가 어디에서 나오고 어디에 저장되는지, 분석 계획은 무엇이며 결과를 어떻게 발표할지 생각해야 합니다.
p.36
열 기반 데이터베이스에는 기본키가 꼭 필요하지 않으며 인덱스도 없습니다. 앞서 언급한 압축기술이 있으므로 반복되는 값도 문제가 되지 않습니다. 데이터가 여러 테이블에 분산돼 있지 않으므로 JOIN이 필요하지 않고, 데이터가 한 곳에 모여 있어 스키마도 분석 쿼리에 잘 맞춰집니다. 단, 기본키가 없어 중복된 값들이 있을 수 있으므로 데이터가 어디에서 왔는지 이해하고 데이터 품질을 잘 확인해야 합니다.
한 행도 여러 열로 분산돼 저장하므로 대부분의 열 기반 데이터베이스에서 UPDATE와 DELETE 연산 시 많은 비용이 듭니다. 따라서 매우 큰 테이블은 UPDATE와 DELETE를 사용할 수 없도록 쓰기 전용(write-only)으로 사용되기도 하므로, 데이터가 어떻게 생성됐는지 잘 알아보고 꼭 필요한 레코드를 미리 파악하는 편이 좋습니다. 데이터를 읽을 때는 압축을 해제해야 할 때도 있어 읽기 속도가 느려질 수도 있습니다.
p.47
많은 SaaS 업체에서 보고 도구(reporting tool)를 제공하는데 왜 굳이 데이터를 데이터 웨어하우스로 옮겨와야 할까요? 고객 서비스 부서에서는 기본으로 제공되는 보고 도구만 사용해도 고객의 문제를 해결하는 데 걸리는 시간이나 헬프데스크 소프트웨어를 통한 고객 응대 생산성 등을 파악하는 데 충분하다고 생각할 수 있습니다. 하지만 고객 서비스 부서와 관련된 상품 판매 및 취소 등의 인터랙션 데이터를 비롯해, 보고 도구에서 확인할 수 없는 데이터는 고객 관계 모델 구성을 위한 중요한 요소이므로 데이터 스토어에 통합해 저장하는 편이 좋습니다.
특정 데이터 소스에서 생성된 데이터를 별도로 저장하면 좋은지 판단하는 데 참고할 만한 법칙이 있습니다. '이 데이터를 다른 시스템의 데이터와 함꼐 사용해 유용한 가치를 만들어낼 수 있는가?'라는 질문에 대한 답이 '그렇다'이면 저장하는 편이 좋습니다. 혹은 '그렇지 않다'이면 다른 좋은 가치를 찾을 때까지 기다리는 편이 좋습니다.
p.51
샘플링을 하려면 랜덤 분포를 이루는 ID 필드에 특정 함수를 사용합니다. 예를 들어, mod 함수는 정수의 나눗셈 결과에서 몫이 아닌 나머지 값을 반환합니다. ID 필드가 정수라면 mod함수를 사용해 마지막 한 자리, 두 자리 또는 세 자리 이상의 숫자로 결과를 필터링할 수 있습니다.
WHERE mod(integer_order_id, 100) = 6
위 코드는 mod 함수를 사용해 integer_order_id 필드의 값을 100으로 나눈 나머지가 6인 결과를 모두 반환합니다. 이 방법은 전체 데이터의 1%만 샘플링합니다. 필드에 저장된 값이 숫자 뿐 아니라 알파벳일 수도 있다면 right 함수를 사용해서 integer_order_id 필드에서 주어진 숫자만큼의 마지막 글자(오른쪽 글자)를 반환받아 필터링할 수 있습니다.
WHERE right(alphanum_order_id, 1) = 'B'
위 코드는 integer_order_id 필드의 마지막 한 글자가 B인 결과를 모두 반환합니다. 해당 필드에서 모든 알파벳과 숫자가 비슷한 빈도로 사용됐다는 전제하에 전체 결과의 약 3%를 샘플링하게 됩니다.
p.57
하나의 CASE 문에서 THEN의 모든 반환값은 데이터 타입이 같아야 하며 (문자열, 숫자, 논리 등), 그렇지 않으면 오류가 발생합니다. 만약 이 문제로 오류가 발생하면 반환값의 데이터 타입을 문자열 등의 일반 데이터 타입으로 캐스팅해 해결합니다.
p.63~64
열별로 행 개수를 세어보면서 전체 데이터에 대해서도 중복을 찾으려면 SELECT와 count 함수를 사용합니다.
SELECT count(*)
FROM
(
SELECT column_a, column_b, column_c ...
, count(*) as records
FROM ...
GROUP BY 1, 2, 3
) a
WHERE records > 1
;
이 방법으로 어느 열에서 중복이 발생했는지 찾습니다. 위 쿼리가 0을 반환하면 중복이 없다는 의미입니다. 다음 코드는 중복 레코드 개수를 확인합니다.
SELECT records, count(*)
FROM
(
SELECT column_a, column_b, column_c..., count(*) as records
FROM ...
GROUP BY 1, 2, 3...
) a
WHERE records > 1
GROUP BY 1
;
p.74
데이터베이스마다 null을 처리하는 방법이 다르므로 집계 함수를 사용할 때나 그룹화를 수행할 때 문제가 생길 수 있습니다. 예를 들어, 값이 5, 10, 15, 20, null인 레코드 5개가 있다고 가정합시다. 총합은 50이지만 null을 전체 데이터 개수로 취급하는지에 따라 평균이 10이 될 수도 있고 12.5가 될 수도 있습니다. 사실 null이 존재하는 데이터로 합계나 평균을 내는 것이 맞는지조차 할 수 없습니다. 대부분의 데이터베이스 함수는 null이 입력되면 null을 반환하며, null을 사용해 '같다', '다르다' 등의 논리 연산을 수행해도 null을 반환합니다. null을 잘 신경 쓰지 않으면 온갖 예상치 못한 황당한 쿼리 결과가 나오게 됩니다.
p.110~111
각기 다른 출처에서 가져온 데이터를 다룰 때, 타임스탬프의 시간이 제대로 동기화돼 있는지 주의해야 합니다. 사용자의 노트북이나 스마트폰의 데이터, 서버에 저장된 데이터처럼 데이터의 출처가 다른 경우가 있습니다. 이 경우, 사용자의 기기에 저장된 타임스탬프를 서버로 전송하는 경우에 시간 동기화 문제가 발생할 수 있습니다. 한번은 스마트폰에서 사용자의 액션을 기록한 시간과 서버에서 기록한 시간 사이에 몇 분씩 차이가 발생해 실험 결과가 잘못 계산된 적이 있습니다. 사용자의 타임스탬프 시간이 서버의 시간보다 몇 분 빨라서 일부 이벤트 데이터가 분석에 포함되지 않았던 것입니다. 이런 문제를 해결하는 방법은 간단합니다. 우선 서버의 타임스탬프와 사용자의 타임스탬프 값이 다른 데이터를 찾습니다. 만약 두 타임스탬프의 시간 차이가 특정 값보다 크다면 데이터를 삭제하고, 특정 값보다 작다면 데이터를 버리지 않고 보정해 남겨둘 수 있습니다. 이때 BETWEEN 절과 앞 절에서 설명한 날짜 계산을 활용합니다.
모바일 앱의 데이터를 다룰 때, 모바일에서의 특정 액션 로그 데이터가 스마트폰 시간으로 기록되는지 혹은 서버의 데이터베이스에 도착한 시간으로 기록되는지 잘 파악해야 합니다. 시간 차이는 무시해도 될 정도로 작기도 하고, 하루 이상이 되기도 합니다. 이렇게 차이가 나는 원인은 모바일 앱이 오프라인 모드로도 동작하는지 여부, 인터넷 신호가 약할 때 데이터를 서버로 전송하는 방법 등 다양합니다. 모바일 앱의 데이터가 며칠이 지난 후에야 서버로 전송되는 경우도 있고, 제때 전송됐지만 서버에 늦게 도착하는 경우도 있습니다. 게다가 날짜와 타임스탬프 값이 전송 도중에 달라지는 일도 발생하므로 먼 과거나 미래의 값이 존재하지 않는지 잘 살펴야 합니다.
p.126
다양한 속성을 가진 시계열 데이터를 다룰 때, 각 속성이 전체에서 차지하는 양이 얼마나 되는지, 그리고 그 양이 시간에 따라 어떻게 바뀌는지 알아보면 전체를 이해하는 데 도움이 됩니다.
p.168~169
코호트 그룹화(cohort grouping)는 고객의 첫 구매 날짜, 구독 날짜, 학교 입학 날짜 등 시작 날짜를 기준으로 수행되는 경우가 많습니다. 그 외에도 코호트는 선천적이거나 후천적인 여러 가지 특징을 기준으로 그룹핑되기도 합니다. 선천적 특징으로는 생일, 국적, 회사의 설립 연도 등이 있으며, 후천적 특징으로는 거주 도시, 혼인 여부 등이 있습니다. 이런 다양한 특징들이 데이터에 포함되어 있는 경우에는 시작 날짜에만 기준을 두고 그룹을 나누는 편이 좋습니다. 특징은 계속 변화할 수 있기 때문에, 시작 날짜에 기준을 두지 않으면 개체의 그룹 구분이 모호해질 수 있습니다.
'Growth' 카테고리의 다른 글
Behavioral Data Analysis with R and Python (1) | 2024.01.08 |
---|---|
컨버티드 마음을 훔치는 데이터분석의 기술 (1) | 2023.06.10 |
웹 데이터 분석학 (0) | 2023.06.10 |
How to learn to code FAST using ChatGPT (it's a game changer seriously) (0) | 2023.03.05 |
[12월 핵클 웨비나] 데이터 활용하여 게임 효율 개선하기 (0) | 2022.12.18 |
댓글