#1 - Kaggle Data Survey
์ด๋ฒ ๊ธ์์๋ ๊ฐ๋จํ BI(Business Intelligence) ๋ถ์์ ์งํํ๋ฉฐ ๋น์ฆ๋์ค ์ง๋ฌธ์ ๋ํ ๋ต์ ์ฐพ์๊ฐ๋ ๊ณผ์ ์ ๋ค๋ค๋ณด๊ณ ์ ํ๋ค.
BigQuery ์ธ์ด์ ์ต์ํ์ง ์๋๋ผ๋ ์ฐ์ ์ ๋ถ์ํ๋ฆ์ ์ต์ํด์ง๋ ๊ฒ์ ๋ชฉํ๋ก ์ ์๋ ์ฟผ๋ฆฌ๋ค์ ํ๋์ฉ ์คํํ๋ฉฐ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํด ๋ณด๋๋ก ํ์.
โ ์ค์ต ์ฃผ์ (Hands-On Topic)
Kaggle์์๋ ํด๋ง๋ค ๊ฒฝ์ง๋ํ์ ์ฐธ์ฌํ๋ ๋ฐ์ดํฐ ๊ณผํ์๋ค์ ๋์์ผ๋ก ์ค๋ฌธ์ ์ค์ํ๋ฉฐ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๊ณต์ ํ๋ค. ์ค๋ฌธ์๋ ๋ฐ์ดํฐ ๊ณผํ์๋ค์ ๊ฐ๋จํ ํ๋กํ์ผ ํต๊ณ์ ๊ฒฝ๋ ฅ ๊ธฐ๊ฐ, ๊ธ์ฌ, ๊ต์ก ์์ค ๋ฐ ์ ํธ ๋๊ตฌ ๋ฑ ๋ค์ํ ํญ๋ชฉ์ด ํฌํจ๋์ด ์๋ค.

์์ธํ ๋ด์ฉ์ ์๋ ๋งํฌ๋ฅผ ์ฐธ์กฐํ์.
์ฌ๋ฌ ์ค๋ฌธ ํญ๋ชฉ ์ค ์ด๋ฒ ํธ์ฆ์จ์์๋ ์๋์ ๊ฐ์ ์ง๋ฌธ์ ๋ํ ๋ต์ ์ฐพ๊ณ ์ ํ๋ค.
โท ํต์ฌ ๋น์ฆ๋์ค ์ง๋ฌธ๋ค(Key Business Questions)
2021๋ ๋์ ๋ถ์๊ฐ๋ค๋ก๋ถํฐ ๊ฐ์ฅ ๋ง์ด ์ ํ๋ฐ์ ์ธ์ด๋?
Kaggle ๋ถ์๊ฐ๋ค์ ๋ช ๊ฐ์ง ์ธ์ด๋ก ๋ถ์์ ์งํํ ๊น?
์ด๋ค ์ธ์ด์กฐํฉ์ด ๊ฐ์ฅ ๋ง์ด ์ ํธ๋๊ณ ์์๊น?
โ Hands-On
์์์ ๋น์ฆ๋์ค ์ง๋ฌธ์ ๋ํ ๋ต์ ์ฐพ๋ ๊ณผ์ ์๋ BigQuery์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฌํ๊ณ ๋ถ์์ด ์ฉ์ดํ ํํ๋ก ๋ณํํ๋ ELT(Extract-Load-Transform) ๊ณผ์ ์ด ์๋ฐ๋๋ค.
โท ๋ฐ์ดํฐ ์ค๋น (Data Preparation)
์ฐ์ Kaggle ์ฌ์ดํธ์์ ์ค๋ฌธ ๋ฐ์ดํฐ๋ฅผ ๋ค์ด๋ก๋ ๋ฐ๊ณ ๊ฐ๋ต์ ์ผ๋ก ๋ฐ์ดํฐ์ ๋ด์ฉ๊ณผ ํ์์ ํ์ ํ๋๋ก ํ๋ค.
Data Source - Kaggle Survey 2021 ์์ ์๋ณธ ํ์ผ์ ๋ค์ด๋ก๋ํ๊ณ ์์ถ์ ํด์ ํ๋ค.
EDA(๋ฐ์ดํฐํ์)
kaggle_survey_2021_responses.csv ์์ ๋๋ต์ ์ธ ๋ฐ์ดํฐ ํํฉ๊ณผ ๋น์ฆ๋์ค ์ง๋ฌธ๊ณผ ๊ด๋ จ๋ ์ปฌ๋ผ์ ๋ด์ฉ์ ์ดํ๋ค.
CSV์ ๊ฒฝ์ฐ ๋ถ๋ฆฌ์(delimeter)์ ํค๋ ๋ฐ ์ปฌ๋ผ ์์ฑ ๋ฑ์ ํ์ ํด ๋๋ค.
๋ฐ์ดํฐ ์ ๋ก๋
๋ก์ปฌPC์ ํ์ผ์ ๋ฐ๋ก BigQuery์ ์ ๋ก๋๋ ๊ฐ๋ฅํ๋ ํ์ผ ํฌ๊ธฐ์ ์ ํ(10MB)์ด ์๋ค.
์ด๋ก ์ธํด ํฐ ํ์ผ์ Clodud Storage์ ์ ๋ก๋ ํ BigQuery๋ก ์ ์ฌํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ด๋ค.
์ด๋ฒ ํธ์ฆ์จ์์ Cloud Storage ๋์ Google Drive์ ํ์ผ์ ์ฌ๋ ค ์ค์ตํ ๋ก ํ๊ฒ ๋ค.
Drive URI ํ์ธ - BigQuery์ ์ธ๋ถ ๋ฐ์ดํฐ ์์ค์ ์์น๋ฅผ ์๋ ค์ค ๋ ํ์ํ ์ ๋ณด๋ก ์ฌ์ ์ ํ์ ํด ๋๋ค.
์ ๋ก๋๋ ํ์ผ์์ ๋ง์ฐ์ค ์ค๋ฅธ์ชฝ ํด๋ฆญ ํ
Get link
์ ํํ๋ค.Copy link ๋ด์ ์ํธ๋ ์ซ์๊ฐ ํ์ผ์ id --> BigQuery ์ ์ฌ์ ํ์ํ ์ ๋ณด
์ต์ข ์ ์ผ๋ก ์ค๋ฌธ ๋ฐ์ดํฐ๋ ์๋์ Google Drive URI์ ์์นํ๊ฒ ๋๋ค.
https://drive.google.com/open?id=1xGKxgLmk07GP7wfP9OjROqcw7zP-QkxU
โท ๋ฐ์ดํฐ ์ ์ฌ (Load)
๋ถ์ํ ๋ฐ์ดํฐ๊ฐ ์ค๋น๋์์ผ๋ฏ๋ก BigQuery์ ์ด๋ฅผ ์ ์ฌํ๊ธฐ ์ํ Dataset์ ์ค๋นํ์. BigQuery Dataset์ ํ ์ด๋ธ ๋๋ ๋ทฐ(View)๋ค์ ๋ด๊ณ ์๋ ์ปจํ ์ด๋์ ์ญํ ์ ํ๋ค.
BigQuery Console ์คํ
https://console.cloud.google.com/bigquery?project=************
project
์๋ ๋ณธ์ธ์ด ์์ฑํ GCP ํ๋ก์ ํธ์ ์ด๋ฆ ์ฌ์ฉํ ๊ฒ - ์๋จ์ ๋ณธ์ธ ํ๋ก์ ํธ(ex. learning-club-2020)๊ฐ ์ ํ๋์ด ์๋์ง ๋จผ์ ํ์ธ
Dataset ์์ฑ
ํ ์ด๋ธ์ ์ ์ฅํ Dataset ์์ฑ - ์ผ์ชฝ ํ๋ก์ ํธ ๋ฆฌ์คํธ ๋ชฉ๋ก์์ ๋ด ํ๋ก์ ํธ๋ฅผ ์ ํํ๋ฉด ์ค๋ฅธ์ชฝ
[+] ๋ฐ์ดํฐ์ธํธ ๋ง๋ค๊ธฐ
๋ฒํผ์ ๋๋ฅด๋ฉด ๋ฐ์ดํฐ์ ์์ฑ ํ์ ์ด ๋ธ.
๋ฐ์ดํฐ์ ์ด ์ค๋น๋์์ผ๋ CSV๋ก ๋์ด ์๋ ์ค๋ฌธ๋ฐ์ดํฐ๋ฅผ BigQuery ํ ์ด๋ธ๋ก ์ฎ๊ธธ ์ฐจ๋ก์ด๋ค.
์ด ๋ ์๋์ ๊ฐ์ด ๊ฐ๋ฅํ ๋ฐฉ๋ฒ ๋ช ๊ฐ์ง๊ฐ ์๋๋ฐ ์ด๋ฒ ์ค์ต์์๋ ์ด ์ค์์ ๋ ๋ฒ์งธ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋๋ก ํ๋ค.
BigQuery Console UI ์์์๋ Command Line ์์ CSV ๋ฐ์ดํฐ๋ฅผ BigQuery ์คํ ๋ฆฌ์ง๋ก ์ ์ฌํ๋ ๋ฐฉ๋ฒ
์ธ๋ถํ ์ด๋ธ(External Table)๋ก ์์ฑํ์ฌ ๋ฌผ๋ฆฌ์ ์ธ ๋ฐ์ดํฐ์ ์ด๋์์ด BigQuery๊ฐ ์ธ๋ถ๋ฐ์ดํฐ(CSVํ์ผ)๋ฅผ ํ ์ด๋ธ์ฒ๋ผ ์ฝ๋๋ก ๋ง๋๋ ๋ฐฉ๋ฒ
BigQuery ์ธ๋ถ ํ ์ด๋ธ (External Table) ์์ฑ
BigQuery๋ DDL(Data Definition Language) ๋ฌธ์ผ๋ก ์ธ๋ถ ์ ์ฅ์์ ์์นํ ๋ฐ์ดํฐ๋ฅผ ์ฐธ์กฐํ๋ External Table ์์ฑ์ด ๊ฐ๋ฅํ๋ค.
์์ ํ์ธํ Google Drive URI๋ฅผ ์ฌ์ฉํ์ฌ ํ ์ด๋ธ์ ์์ฑํ๋ BigQuery ๊ตฌ๋ฌธ์ ๋ค์๊ณผ ๊ฐ๋ค.
CREATE OR REPLACE EXTERNAL TABLE learning_club.kaggle_survey_2021
OPTIONS (
format = 'CSV',
skip_leading_rows = 2,
field_delimiter = ',',
uris = ['https://drive.google.com/open?id=1xGKxgLmk07GP7wfP9OjROqcw7zP-QkxU']
);
SELECT * FROM learning_club.kaggle_survey_2021;
uris
๋ฅผ ํตํด CSVํ์ผ์ด ์์นํ URI๋ฅผ BigQuery์ ์๋ ค์ฃผ๊ณ ์๋ค. CSVํ์ผ์ ํค๋๊ฐ 2์ค์ ๊ฑธ์ณ์์ผ๋ฏ๋ก skip_leading_rows
๊ฐ์ 2๋ก ์ค์ ํ์๋ค.
โท ๋ฐ์ดํฐ ๋ณํ (Transform)
์ค๋ฌธ ํ์ผ์๋ ๋ค์ํ ์ค๋ฌธ ํญ๋ชฉ๊ณผ ๊ด๋ จ๋ ๋ง์ ์ปฌ๋ผ๋ค์ ํฌํจํ๊ณ ์๋ค.
์ด ์ค ํธ์ฆ์จ์ ๋น์ฆ๋์ค ์ง๋ฌธ๊ณผ ๊ด๋ จ์ด ์๋ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด ์ปฌ๋ผ๋ค๋ง ์ถ์ถํ์. ๊ทธ๋ฆฌ๊ณ External Table ์ Internal Table๋ก ์ฎ๊ฒจ์ ๋น ๋ฅด๊ฒ ์ฟผ๋ฆฌ๊ฐ ์ํ๋ ์ ์๋๋ก ํด๋ณด์.
CREATE OR REPLACE TABLE learning_club.survey_raw AS
SELECT What_programming_languages_do_you_use_on_a_regular_basis___Select_all_that_apply____Selected_Choice___Python AS Python,
What_programming_languages_do_you_use_on_a_regular_basis___Select_all_that_apply____Selected_Choice___R AS R,
What_programming_languages_do_you_use_on_a_regular_basis___Select_all_that_apply____Selected_Choice___SQL AS SQL,
What_programming_languages_do_you_use_on_a_regular_basis___Select_all_that_apply____Selected_Choice___C AS C,
What_programming_languages_do_you_use_on_a_regular_basis___Select_all_that_apply____Selected_Choice___Java AS Java,
What_programming_languages_do_you_use_on_a_regular_basis___Select_all_that_apply____Selected_Choice___Javascript AS Javascript,
What_programming_languages_do_you_use_on_a_regular_basis___Select_all_that_apply____Selected_Choice___Julia AS Julia,
What_programming_languages_do_you_use_on_a_regular_basis___Select_all_that_apply____Selected_Choice___Swift AS Swift,
What_programming_languages_do_you_use_on_a_regular_basis___Select_all_that_apply____Selected_Choice___Bash AS Bash,
What_programming_languages_do_you_use_on_a_regular_basis___Select_all_that_apply____Selected_Choice___MATLAB AS MATLAB,
What_programming_languages_do_you_use_on_a_regular_basis___Select_all_that_apply____Selected_Choice___Other AS Other,
ROW_NUMBER() OVER() AS id, -- ์ฌ์ฉ์ ID ์์ฑ
FROM learning_club.kaggle_survey_2021;
Kaggle ์ค๋ฌธ ์๋ฃ๋ ๋ถ์ํ๊ธฐ ์ฉ์ดํ ๊ตฌ์กฐ๊ฐ ์๋์ด์ Tidy Data๊ฐ ๋๋๋ก ๋ณํ ์์ ์ด ํ์ํ๋ฐ ์๋์ ๋ช๊ฐ์ง ๋ฐฉ๋ฒ์ด ๊ฐ๋ฅํ๋ค.
๋ณํ๋ ๊ตฌ์กฐ๋ ์๋์ ๊ทธ๋ฆผ๊ณผ ์ ์ฌํ๋ ์ฐธ๊ณ ํ ๋ก ํ๋ค.

[์ฐธ๊ณ ] Tidy Data
https://vita.had.co.nz/papers/tidy-data.pdf
https://www.openscapes.org/blog/2020/10/12/tidy-data/
๋ฐฉ๋ฒ 1 - UNION ALL ์ฌ์ฉ
ํ์ค SQL ๋ฌธ๋ฒ์ UNION ALL์ ์ฌ์ฉํด์ ์๋์ ๊ฐ์ด Stacked Data๋ก ๋ง๋ค ์ ์๋ค.
WITH tidy AS ( -- WITH ๊ตฌ๋ฌธ์ SQL ๋ฌธ๋ฒ ์๊ฐ๋ ๋ค๋ฃฐ ์์ ์
๋๋ค.
SELECT id, Python AS lang FROM learning_club.survey_raw
UNION ALL
SELECT id, R AS lang FROM learning_club.survey_raw
UNION ALL
SELECT id, SQL AS lang FROM learning_club.survey_raw
-- UNION ALL
-- SELECT ....
)
SELECT * FROM tidy WHERE lang IS NOT NULL;
๋ฐฉ๋ฒ 2 - ARRAY ์ฌ์ฉ
BigQuery ์ค๋ฝ๊ฒ ARRAY
๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด ์ข ๋ ๊ฐ๊ฒฐํ๊ฒ ์ฟผ๋ฆฌ ๊ธฐ์ ์ด ๊ฐ๋ฅํ๋ค.
WITH tidy AS (
SELECT id, lang FROM (
SELECT id, [Python, R, SQL, C, Java, Javascript, Julia, Swift, Bash, MATLAB, Other] AS languages
FROM learning_club.survey_raw
), UNNEST(languages) AS lang
)
SELECT * FROM tidy WHERE lang IS NOT NULL;
๋ฐฉ๋ฒ 3 - UNPIVOT ์ฌ์ฉ
๋ง์ง๋ง์ผ๋ก BigQuery UNPIVOT
์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ณํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด์.
WITH tidy AS (
SELECT * EXCEPT(dummy)
FROM learning_club.survey_raw
UNPIVOT (dummy FOR lang IN (Python, R, SQL, C, Java, Javascript, Julia, Swift, Bash, MATLAB, Other))
)
SELECT * FROM tidy WHERE lang IS NOT NULL;
1
16
Python
2
16
C
3
16
MATLAB
4
136
SQL
5
139
Python
6
139
SQL
...
...
...
์ฃผ์ด์ง ์์๋ฐ์ดํฐ(raw data)๊ฐ ๋ด๊ฐ ์ํ๋ ํํ๋ก ์ฃผ์ด์ง๋ ๊ฒฝ์ฐ๋ ๊ฑฐ์ ์์ผ๋ฏ๋ก ์ฟผ๋ฆฌ๋ฅผ ํตํด์ ํ ์ด๋ธ์ ํํ๋ฅผ ์ํ๋ ๋ชจ์ต์ผ๋ก ๋ณํ์ํฌ ์ ์๋ ์ฐ์ต์ด ํ์ํ๋ค.
ARRAY
๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ผ๋ก ๋ค์ ๋ถ์์ ์ด์ด๊ฐ๋๋ก ํ์.
โท ๋ฐ์ดํฐ ๋ถ์ (Analysis)
๋ถ์์ด ์ฉ์ดํ ๊ตฌ์กฐ๋ก ๋ณํ์ด ๋์์ผ๋ฏ๋ก GROUP BY
์ ์ง๊ณ ํจ์(aggregation function)์ ์ฌ์ฉํ์ฌ ๊ฐ๋จํ ๋ถ์์ ์งํํ๋ค.
์ฒซ๋ฒ์งธ ์ง๋ฌธ์ ๋ต์ ์ฐพ๊ธฐ ์ํ ์ฟผ๋ฆฌ - ๊ณผํ์๋ค์ด ๊ฐ์ฅ ์ ํธํ๋ ๋๊ตฌ๋?
WITH tidy AS (
SELECT id, lang FROM (
SELECT id, [Python, R, SQL, C, Java, Javascript, Julia, Swift, Bash, MATLAB, Other] AS languages
FROM learning_club.survey_raw
), UNNEST(languages) AS lang
)
SELECT lang, COUNT(1) AS cnt
FROM tidy
WHERE lang IS NOT NULL
GROUP BY 1
ORDER BY 2 DESC;
1
Python
21860
2
SQL
10756
3
R
5334
4
Java
4769
5
C
4709
...
...
...
์ฟผ๋ฆฌ ์ํ์ ๊ฒฐ๊ณผ์
์ผ๋ก ๋ถํฐ ์ง๋ฌธ์ ๋ํ ๋ต์ ํ์ธ ํ ์ ์๊ณ ๊ฒฐ๊ณผ์ฐฝ์ Explore Data (๋ฐ์ดํฐ ํ์)
๋ฒํผ์ ํด๋ฆญํ๋ฉด Data Studio์ ์๊ฐ์ ๋ถ์ ํ๊ฒฝ์ผ๋ก Seamless ํ๊ฒ ๋์ด๊ฐ ์ ์๋ค.

์ธ์ด๋ณ ์ ํธ๋ ์๊ฐํ
๋๋ฒ์งธ ์ง๋ฌธ - Kaggle ๋ถ์๊ฐ๋ค์ ๋ช ๊ฐ์ง ์ธ์ด๋ก ๋ถ์์ ์งํํ ๊น?
์ด ์ง๋ฌธ์ ๋ํ ๋ต์ ์ํด์๋ ์ฌ์ฉ์๋ณ๋ก ์ฌ์ฉํ๋ ์ธ์ด์ ๊ฐฏ์๋ฅผ ๋จผ์ ์ง๊ณํ ํ, ์ธ์ด์ ๊ฐฏ์๋ฅผ ์ฐจ์(dimension)์ผ๋ก ํ๋ ์ง๊ณ๋ฅผ ํ ๋ฒ ๋ ์ํํด์ผ ํ๋ค.
WITH tidy AS (
SELECT id, lang FROM (
SELECT id, [Python, R, SQL, C, Java, Javascript, Julia, Swift, Bash, MATLAB, Other] AS languages
FROM learning_club.survey_raw
), UNNEST(languages) AS lang
)
SELECT languages, COUNT(1) AS cnt
FROM (
-- ์ฌ์ฉ์๋ณ๋ก ์ฌ์ฉํ๋ ์ธ์ด๋ค์ ๋ฐฐ์ด๋ก ๋ฌถ์.
SELECT id, COUNT(1) AS languages
FROM tidy WHERE lang IS NOT NULL
GROUP BY 1
)
GROUP BY 1
ORDER BY 2 DESC;
1
2
7589
2
1
6798
3
3
5493
4
4
2716
5
5
1207
์ธ๋ฒ์งธ ์ง๋ฌธ - ์ด๋ค ์ธ์ด์กฐํฉ์ด ๊ฐ์ฅ ๋ง์ด ์ ํธ๋๊ณ ์์๊น?
์ด ์ง๋ฌธ์ ๋ํ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๊ธฐ ์ํด์ ์ธ์ด์กฐํฉ์ ํ๋์ ๋ฌธ์์ด๋ก ํํํ๊ณ ์ด๋ฅผ GROUP BY
ํ์ฌ ์ง๊ณํ์๋ค.
WITH tidy AS (
SELECT id, lang FROM (
SELECT id, [Python, R, SQL, C, Java, Javascript, Julia, Swift, Bash, MATLAB, Other] AS languages
FROM learning_club.survey_raw
), UNNEST(languages) AS lang
)
SELECT ARRAY_TO_STRING(languages, ', ') langs, COUNT(1) AS cnt
FROM (
-- ์ฌ์ฉ์๋ณ๋ก ์ฌ์ฉํ๋ ์ธ์ด๋ค์ ๋ฐฐ์ด๋ก ๋ฌถ์.
SELECT id, ARRAY_AGG(lang IGNORE NULLS ORDER BY lang) AS languages
FROM tidy GROUP BY 1
)
WHERE ARRAY_LENGTH(languages) = 2
GROUP BY 1 ORDER BY 2 DESC;
1
Python, SQL
2636
2
Python, R
1018
3
C, Python
790
4
MATLAB, Python
652
5
Java, Python
575
๊ฒฐ๊ณผ๋ก๋ถํฐ Python๊ณผ SQL ์กฐํฉ์ ๋ฐ์ดํฐ ๊ณผํ์์ ๋ถ์๊ฐ๋ค์ด ๊ฐ์ฅ ์ ํธํ๋ ๊ฒ์ ์ ์ ์๋ค.
์ด์ ๊ฐ์ด ๋ถ์์ ์ํ ํต์ฌ ์ง๋ฌธ(Key Business Question, KBQ)์ ์๊ฐํ๊ณ ์ฟผ๋ฆฌ๋ฅผ ํตํด ๋ต์ ์ฐพ๋ ๊ณผ์ ์ ๋ฐ๋ณตํ๋ฉฐ ๋ฐ์ดํฐ์ ๋ํ ์ดํด์ ํต์ฐฐ์ ํค์๊ฐ๋ ๊ณผ์ ์ด BI ๋ถ์์ด๋ผ ํ ์ ์๋ค. ์ด ๊ณผ์ ์์ ๋น์ฆ๋์ค ์ง๋ฌธ์ ์ ๋ํน ์ฟผ๋ฆฌ๋ก ๋ณํํ๋ ๋ฅ๋ ฅ์ด ์๊ตฌ๋๋ฉฐ ์ฟผ๋ฆฌ ์์ฑ ๋ฅ๋ ฅ์ด ๋ถ์์์ฐ๋ ฅ์ ์ฐจ์ด๋ฅผ ๋ง๋ ๋ค.
Last updated