์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- ๋จธ์ ๋ฌ๋
- ๋ง์ผํ
- ์ฝ๋ฉ
- ์บ๊ธ
- ๋ฐ์ดํฐ๋ถ์
- TIL
- ์ฝ๋์นดํ
- ํ์ด์ฌ
- ํ๋ก๊ทธ๋๋จธ์ค
- ๋ ํ
- ์๋์ฐ ํจ์
- sql
- sqld
- ๋ฐ์ดํฐ ๋ถ์
- ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ
- Today
- Total
SQL & Python Study
[D+21][ํ๋ก์ ํธ #1-3] ๊ตฐ์ง๋ณ ํธํ ์๋น์ค ์ด์ฉ ์ ์์ ์ผํ๊ท ๋งค์ถ์ ์๊ด ๊ด๊ณ ๋ถ์๊ณผ ์๊ฐํ ๋ณธ๋ฌธ
[D+21][ํ๋ก์ ํธ #1-3] ๊ตฐ์ง๋ณ ํธํ ์๋น์ค ์ด์ฉ ์ ์์ ์ผํ๊ท ๋งค์ถ์ ์๊ด ๊ด๊ณ ๋ถ์๊ณผ ์๊ฐํ
๊น์ฎ์ 2024. 5. 28. 18:09๐ INDEX
01. ๊ณ ๊ฐ ๊ตฌ์ฑ์ ๋ฐ๋ฅธ total_socre์ adr์ ๊ด๊ณ
02. ๊ตญ์ ์ ๋ฐ๋ฅธ total_socre์ adr์ ๊ด๊ณ
03. ๋ง์ผ ์ธ๊ทธ๋จผํธ์ ๋ฐ๋ฅธ total_score์ adr์ ๊ด๊ณ
*ํธํ ์๋น์ค ์ด์ฉ ์ ์๋ total_socre, ํ๊ท ์ผ์ผ ์๊ธ์ adr ์นผ๋ผ์ ๋๋ค.
*๋ง์ผ ์ธ๊ทธ๋จผํธ(market_segment)๋ ๊ณ ๊ฐ์ ์์ฝ ์ฑ๋์ ์๋ฏธํฉ๋๋ค.
01. ๊ณ ๊ฐ ๊ตฌ์ฑ์ ๋ฐ๋ฅธ total_score์ adr์ ๊ด๊ณ
์ ๋ SQL์ ํ์ฉํด์ ๋ฐ์ดํฐ๋ฅผ 1์ฐจ ์ง๊ณํ๊ณ , ํด๋น ๊ฒฐ๊ณผ๋ฅผ ํ์ด์ฌ์ ๊ฐ์ ธ์์ ์๊ฐํํ์ด์.
์ถํ์ SQL์์ ์ฟผ๋ฆฌ๋ฅผ CSV ํ์ผ๋ก ์ถ์ถํ๋ ๋ฐฉ๋ฒ์ ๋์ค์ ํ๋ฒ ์ ๋ฆฌํด์ ์ฌ๋ ค๋ณด๊ฒ ์ต๋๋ค!
๊ณ ๊ฐ ๊ตฌ์ฑ์ ๋ฐ๋ฅธ ํธํ ์๋น์ค ์ฌ์ฉ ์ ์๋ฅผ ์ง๊ณํ๊ธฐ ์ํด์ ์๋ธ ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ฒ ์ฌ์ฉํ๋๋ฐ์.
WITH ๋ฌธ์ ์ฌ์ฉํ๋ค๋ฉด ํจ์ฌ ๊ฐ๊ฒฐํ๊ณ ๊ฐ๋ ์ฑ ์๊ฒ ์์ ํ ์ ์์์ ๊ฒ ๊ฐ์์.
# ์ด์ฉ๊ฐ ์ธ๊ทธ๋จผํธ(๊ณ ๊ฐ ์ ํ)์ ๋ฐ๋ฅธ ํธํ
์๋น์ค ์ฌ์ฉ ์ ์์ ์ผํ๊ท ๋งค์ถ ์ง๊ณ
SELECT
customer_segment,
total_score,
ROUND(AVG(adr)) AS avg_adr
FROM (
SELECT # total_score์ ๋ฐ๋ฅธ ํ์ฑํ ๊ณ ๊ฐ ์ธ๊ทธ๋จผํธ
case when (meal_score + parking_score + request_score) <=1 then '[0~1์ ] ์๊ทน ์ด์ฉ'
when (meal_score + parking_score + request_score) <=3 then '[2~3์ ] ํธ์ ์ด์ฉ'
else '[4์ ์ด์] ์ ๊ทน ์ด์ฉ ๊ณ ๊ฐ' end as total_score,
adr,
hotel,
arrival_date_year,
arrival_date_month,
# ์ธ์ ๋ฐ ์์ด ์ฌ๋ถ์ ๋ฐ๋ฅธ ์ด์ฉ๊ฐ ์ธ๊ทธ๋จผํธ (์ฒ ํ๋, ์ ๋ฆผ๋ ์ฟผ๋ฆฌ ํ์ฉ)
CASE WHEN total_customer >= 4 AND youth_yn = 'y' THEN '๋ค์ธ๊ฐ์กฑ'
WHEN total_customer >= 4 AND youth_yn = 'n' THEN '๋จ์ฒด'
WHEN total_customer = 3 AND youth_yn = 'y' THEN '3์ธ๊ฐ์กฑ'
WHEN total_customer = 3 AND youth_yn = 'n' THEN '3์ธ'
WHEN total_customer = 2 AND youth_yn = 'y' THEN '2์ธ๊ฐ์กฑ'
WHEN total_customer = 2 AND youth_yn = 'n' THEN '2์ธ'
ELSE '1์ธ' END customer_segment,
youth_yn
FROM (
SELECT
hotel,
arrival_date_year,
arrival_date_month,
adr,
# ์ด ์ธ์ ํ์ธ
adults + babies + children AS total_customer,
# ์ ์ ๋๋ฐ ํ์ธ
CASE WHEN babies + children > 0 THEN 'y'
ELSE 'n'
END AS youth_yn,
# ์์ฌ ์๋น์ค ์ฌ์ฉ์ ๋ฐ๋ฅธ ์ ์ ํ ๋น
CASE
WHEN meal IN ('SC', 'BB') THEN 1
WHEN meal = 'HB' THEN 2
WHEN meal = 'FB' THEN 3
ELSE 0
END AS meal_score,
# ์ฃผ์ฐจ ์๋น์ค ์ฌ์ฉ์ ๋ฐ๋ฅธ ์ ์ ํ ๋น
CASE
WHEN required_car_parking_spaces BETWEEN 1 AND 3 THEN 1
WHEN required_car_parking_spaces >= 4 THEN 2
ELSE 0
END AS parking_score,
# ํน๋ณ ์์ฒญ ์๋น์ค์ ๋ฐ์ฐ
CASE
WHEN total_of_special_requests BETWEEN 1 AND 2 THEN 1
WHEN total_of_special_requests >= 3 THEN 2
ELSE 0
END AS request_score
FROM processed_hotel_booking_file phbf
WHERE adr > 0 and is_canceled = 0 #์ผํ๊ท ๋งค์ถ ์์, ์์ฝ ์ทจ์ ๊ณ ๊ฐ ์ ์ธ
) AS scores_and_family
) a
GROUP BY customer_segment, total_score
ORDER BY avg_adr desc;
์ ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ CSV ํ์ผ๋ก ์ถ์ถํ๊ณ (ํ์ผ๋ช cus_score)
๋งฅํ๋กฏ๋ฆฝ๊ณผ ์๋ณธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ์ฉํด์ ๋ง๋ ๊ทธ๋ํ๋ฅผ ๋ง๋ค์์ต๋๋ค.
ํ์ด์ฌ์ ํ๊ธ ๊ธ๊ผด์ ์ง์ํ์ง ์๊ธฐ ๋๋ฌธ์ ํ์ด๋ธ ๋ฐ ๋ฒ๋ก ํ ์คํธ๊ฐ ๊นจ์ ธ์ ๋์๋๋ฐ์,
์๋์ ๊ฐ์ด ๊ธ๊ผด์ ์ง์ ํ๋ฉด ์ค๋ฅ ์์ด ๊ทธ๋ํ๋ฅผ ์ถ์ถํ ์ ์์ต๋๋ค. (์ํ ํํฐ๋๊ป์ ์๋ ค์ฃผ์ ๋ฐฉ๋ฒ!)
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# DataFrame ์ ๋ ฌ
cus_score.sort_values(by=['customer_segment', 'total_score', 'avg_adr', 'cnt'], ascending=[True, True, False, False], inplace=True)
# ํ๊ธ ํฐํธ ์ค์
plt.rcParams['font.family'] ='Malgun Gothic'
plt.rcParams['axes.unicode_minus'] =False
# ๋ง๋ ๊ทธ๋ํ ์์ฑ
sns.barplot(x='total_score', y='avg_adr', hue='customer_segment', data=cus_score)
# ํ์ดํ ๋ฐ ๋ฒ๋ก ์ค์
plt.title('์ด์ฉ๊ฐ ์ ํ๋ณ ํธํ
์ฌ์ฉ ์๋น์ค ์ ์, ์ผํ๊ท ๋งค์ถ')
plt.legend(title='customer_segment', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.show
02. ๊ตญ์ ์ ๋ฐ๋ฅธ total_socre์ adr์ ๊ด๊ณ
์ฒ์์๋ ๋ด๊ตญ์ธ๊ณผ ์ธ๊ตญ์ธ ๋ ์ง๋จ์ด๋ ์ฐ์ ๋(scatter) ๊ทธ๋ํ๋ฅผ ์ด์ฉํด์, ๊ฐ ์ง๋จ์ ๋งค์ถ๊ณผ ํ๊ท ์ ๊ด๊ณ๋ฅผ ๋ถ์ํ๋ฉด ๋๊ฒ ๋ค ์๊ฐํ๋๋ฐ์. x์ถ๊ณผ y์ถ์ ๋ชจ๋ ์ซ์ํ ๋ฐ์ดํฐ๊ฐ ๋ค์ด๊ฐ์ผ ํด์ ํ ๋ฒ์ ๋ํ๋ด๊ธฐ์ ์ด๋ ต๋๋ผ๊ณ ์... ๊ทธ๋ฆฌ๊ณ ํธํ ์๋น์ค ์ฌ์ฉ ์ ์๊ฐ ๋ชจ๋ ์ ์์ฌ์ ์ค๋ฌด๋ฌ ํฐ์ ์ธ ๋ง๋ฅ ๊ฒฐ๊ณผ๊ฐ ๋์๋๋ผ๊ตฌ์ .... ๐ฅฒ
์ฌ๋ฌ๊ฐ์ง ์๊ฐํ ๋ฐฉ๋ฒ์ ๊ณ ๋ฏผํ๋ค๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฅ ๋ช ๋ฃํ๊ฒ ๋ณด์ฌ์ค ์ ์๋ ํผ๋ฒ ํ ์ด๋ธ์ ๋ง๋ค์์ต๋๋ค.
๋ฐ์ดํฐ์ ์ ํฉํ ์๊ฐํ, ์ ๋ฆฌ ๋ฐฉ๋ฒ์ ์๋ ๊ฒ๋ ์๋ จ๋๊ฐ ๋ ํ์ํ๋ค๋ ๊ฒ์ ์ฌ์คํ ๋๊ผ์ต๋๋ค.
ํด๋น ์์ ๋ ๋ฐ์ดํฐ ์ง๊ณ๋ SQL, ์๊ฐํ/์ ์ ๋ ํ์ด์ฌ์ ํ์ฉํด์ ์งํํ์ด์.
๊ตญ์ ์ ๋ฐ๋ฅธ ํธํ
์๋น์ค ์ฌ์ฉ ์ ์์ ์ผํ๊ท ๋งค์ถ ๋ฐ์ดํฐ ์ง๊ณ(SQL)
select `guest_country`,
total_score,
round(avg(adr)) as avg_adr
from
(
SELECT # total_score์ ๋ฐ๋ฅธ ํ์ฑํ ๊ณ ๊ฐ ์ธ๊ทธ๋จผํธ
case when (meal_score + parking_score + request_score) <=1 then '[0~1์ ] ์๊ทน ์ด์ฉ'
when (meal_score + parking_score + request_score) <=3 then '[2~3์ ] ํธ์ ์ด์ฉ'
else '[4์ ์ด์] ์ ๊ทน ์ด์ฉ ๊ณ ๊ฐ' end as total_score,
adr,
`guest_country`,
hotel,
arrival_date_year,
arrival_date_month
FROM
(
SELECT hotel,
arrival_date_year,
arrival_date_month,
adr,
if(country = 'PRT', '๋ด๊ตญ์ธ', '์ธ๊ตญ์ธ') as `guest_country`,
case when meal in ('SC', 'BB') then 1
when meal = 'HB' then 2
when meal = 'FB' then 3
else 0 end as meal_score,
case when required_car_parking_spaces between 1 and 3 then 1
when required_car_parking_spaces >= 4 then 2
else 0 end as parking_score,
case when total_of_special_requests between 1 and 2 then 1
when total_of_special_requests >= 3 then 2
else 0 end as request_score
FROM processed_hotel_booking_file phbf
WHERE `adr` > 0 and is_canceled = 0
) as scores
) a
group by `guest_country`, total_score
order by avg_adr desc;
ํผ๋ฒ ํ
์ด๋ธ ์ ์ (ํ์ด์ฌ)
# DataFrame ์ ๋ ฌ
country_score_str.sort_values(by=['guest_country', 'total_score', 'adr'], ascending=[True, True, False], inplace=True)
# ํผ๋ฒ ํ
์ด๋ธ ์์ฑ
country_score_str.pivot_table(
index=['guest_country', 'total_score'],
values='adr',
aggfunc=['mean', 'max', 'min', 'count']).round()
03. ๋ง์ผ ์ธ๊ทธ๋จผํธ์ ๋ฐ๋ฅธ total_score์ adr์ ๊ด๊ณ
ํ์๋ค๊ณผ ๋ฐ์ดํฐ๋ฅผ ํธํ ์ข ๋ฅ๋ณ๋ก, ์ฐ๋๋ณ๋ก, ๊ทธ๋ฆฌ๊ณ 3๊ฐ์ ๊ตฐ์ง๋ณ๋ก ๋๋์ด ๋ณด๊ธฐ๋ก ํด์
ํด๋น ๋ง์ผ ์ธ๊ทธ๋จผํธ์ ๋ฐ๋ฅธ ํธํ ์๋น์ค ์ฌ์ฉ ์ ์์ ์ผ์ผ ์๊ธ์ ๊ด๊ณ๋ ์ง๊ณํด๋ณด๊ณ ๊ทธ๋ํ๋ก ๊ทธ๋ ค๋ณด์์ต๋๋ค.
๋ค๋ง, ์์ฝ ๊ฒฝ๋ก ์์ฒด๊ฐ ๊ณ ๊ฐ ์ ํ์ด๋ ํน์ง์ ๋ํํ๊ธด ์ด๋ ค์์ 3๋ฒ ๋ถ์์ ์ ์๋ฏธํ ๊ฒฐ๋ก ์ ๋์ถํ์ง ๋ชปํ๋ค๊ณ ์๊ฐํด์๐ญ ๐ญ
๊ทธ๋๋ ์งํํ ๋ด์ฉ์ด ์์ด ์ผ๋จ ์ ๋ฆฌํด๋ณด์๊ณ , ์์ ๋์ผํ๊ฒ SQL๋ก ๋ฐ์ดํฐ ์ง๊ณ, ํ์ด์ฌ์ผ๋ก ์๊ฐํํ์ต๋๋ค.
๋ง์ผ ์ธ๊ทธ๋จผํธ์ ๋ฐ๋ฅธ ํธํ
์๋น์ค ์ฌ์ฉ ์ ์์ ํ๊ท ์ผ๋งค์ถ ์ง๊ณ
select market_segment,
total_score,
round(avg(adr)) as avg_adr
from
(
SELECT # total_score์ ๋ฐ๋ฅธ ํ์ฑํ ๊ณ ๊ฐ ์ธ๊ทธ๋จผํธ
case when (meal_score + parking_score + request_score) <=1 then '[0~1์ ] ์๊ทน ์ด์ฉ'
when (meal_score + parking_score + request_score) <=3 then '[2~3์ ] ํธ์ ์ด์ฉ'
else '[4์ ์ด์] ์ ๊ทน ์ด์ฉ ๊ณ ๊ฐ' end as total_score,
adr,
hotel,
arrival_date_year,
arrival_date_month,
market_segment
FROM
(
SELECT hotel,
arrival_date_year,
arrival_date_month,
adr,
market_segment,
# ํธํ
์ฌ์ฉ ์๋น์ค์ ๋ฐ๋ผ ์ ์ ํ ๋น
case when meal in ('SC', 'BB') then 1
when meal = 'HB' then 2
when meal = 'FB' then 3
else 0 end as meal_score,
case when required_car_parking_spaces between 1 and 3 then 1
when required_car_parking_spaces >= 4 then 2
else 0 end as parking_score,
case when total_of_special_requests between 1 and 2 then 1
when total_of_special_requests >= 3 then 2
else 0 end as request_score
FROM processed_hotel_booking_file phbf
WHERE `adr` > 0 and is_canceled = 0
) as scores
) a
group by market_segment, total_score
order by avg_adr desc ;
# DataFrame ์ ๋ ฌ
market_score.sort_values(by=['market_segment', 'total_score', 'avg_adr'], ascending=[True, True, True], inplace=True)
# ๊ธ๊ผด ์ค์
plt.rcParams['font.family'] ='Malgun Gothic'
plt.rcParams['axes.unicode_minus'] =False
# ์๋ณธ์ ์ฌ์ฉํ ๋ง๋ ๊ทธ๋ํ ์์ฑ
sns.barplot(x='total_score', y='avg_adr', hue='market_segment', data=market_score)
# ํ์ดํ ๋ฐ ๋ฒ๋ก ์ค์
plt.title('์์ฝ ์ฑ๋๋ณ ํธํ
์๋น์ค ์ฌ์ฉ ์ ์, ์ผํ๊ท ๋งค์ถ')
plt.legend(title='market_segment', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.show
[ Today I Learned ] ์ฒ์์ ๊ณ ๊ฐ์ ํ๋์ด๋ ์ ํ์ ํน์ ํ ์ ์๋ ์นผ๋ผ์ด ๋ง์ด ์์ด์, 'ํธํ ์๋น์ค๋ฅผ ์ ๊ทน์ ์ผ๋ก ์ฌ์ฉํ๋ ๊ณ ๊ฐ์ด ๋ ๋ง์ ์๋น๋ฅผ ํ์ฌ ํ๊ท ๋งค์ถ์ด ๋์ ๊ฒ์ด๋ค.'๋ผ๋ ๊ฐ์ค์ ์ธ์ ์นผ๋ผ์ ์ถ๊ฐํ๋ ๊ฒ์ธ๋ฐ์. ์ ๋ฐ์ ์ผ๋ก ํธํ ์๋น์ค ์ฌ์ฉ ์ ์๊ฐ ๋์์๋ก ํ๊ท ๋งค์ถ์ด ๋์ ์์ ์๊ด ๊ด๊ณ๋ฅผ ๋ณด์ฌ์ฃผ๊ณ ์์ด์ ์ด๋ ์ ๋ ๊ฐ์ค์ด ๋ง์ ๊ฒ ๊ฐ์ ์ฌ๋ฏธ์์์ต๋๋ค. ๋ง์ฝ, ๋ ๋ง์ ๋ฐ์ดํฐ๋ฅผ ํ์ธํ ์ ์์๋ค๋ฉด ์กฐ๊ธ ๋ ๋พฐ์กฑํ ๋ถ์์ ํ ์ ์์ง ์์๊น ์ถ์ด์! ๊ทธ๋ฆฌ๊ณ ๋ฐ์ดํฐ์ ์ ํฉํ ์๊ฐํ ๋ฐฉ๋ฒ์ ๊ณ ๋ คํ๊ณ ์ ์ฉํ๋ ๊ฒ๋ ๋ง์ ๊ณ ๋ฏผ์ด ํ์ํ๋ค๋ ์ฌ์ค์ ๋๊ผ์ต๋๋ค. ์๋๋ ์ ๊ฐ ์ด์ฌํ ๋ ธ๋ ฅํด๋ดค์ง๋ง ๋งํ ๊ทธ๋ํ๋ค์ด์์ ... ์ค๋์ ๊ธฐ๋ ํ๋ฉฐ ์ฌ๋ ค๋ด ๋๋ค.
02๋ฒ ๋ฐ์ดํฐ์ ํผ๋ด ํ ์ด๋ธ์ ์ ์ฉํ๊ธฐ ์ ๊ฑฐ์ณค๋ ๋ง์ ์ํ ์ฐฉ์ค๋ค(=๊ทธ๋ํ)