competition - M5 EDA
Page content
강의 홍보
- 취준생을 위한 강의를 제작하였습니다.
- 본 블로그를 통해서 강의를 수강하신 분은 게시글 제목과 링크를 수강하여 인프런 메시지를 통해 보내주시기를 바랍니다.
스타벅스 아이스 아메리카노를 선물
로 보내드리겠습니다.
- [비전공자 대환영] 제로베이스도 쉽게 입문하는 파이썬 데이터 분석 - 캐글입문기
공지
제 수업을 듣는 사람들이 계속적으로 실습할 수 있도록 강의 파일을 만들었습니다. 늘 도움이 되기를 바라며. 참고했던 교재 및 Reference는 꼭 확인하셔서 교재 구매 또는 관련 Reference를 확인하시기를 바랍니다.
I. 개요
- Kaggle에서 데이터를 다운로드 하는 방법에 대해서는 생략한다.
- 본 포스트는
Google Colab
을 기반으로 작성하였다. Kaggle + Google Colab
데이터 연동하는 방법은 이전 포스트를 참고한다.
- 데이터는 크게 4가지로 구성되어 있다. (원문 인용)
- calendar.csv - Contains information about the dates on which the products are sold.
- sales_train_validation.csv - Contains the historical daily unit sales data per product and store [d_1 - d_1913]
- sample_submission.csv - The correct format for submissions. Reference the Evaluation tab for more info.
- sell_prices.csv - Contains information about the price of the products sold per store and date.
II. 데이터 불러오기
!pip install kaggle
from google.colab import files
files.upload()
Requirement already satisfied: kaggle in /usr/local/lib/python3.6/dist-packages (1.5.6)
Requirement already satisfied: tqdm in /usr/local/lib/python3.6/dist-packages (from kaggle) (4.41.1)
Requirement already satisfied: certifi in /usr/local/lib/python3.6/dist-packages (from kaggle) (2020.4.5.1)
Requirement already satisfied: requests in /usr/local/lib/python3.6/dist-packages (from kaggle) (2.23.0)
Requirement already satisfied: python-dateutil in /usr/local/lib/python3.6/dist-packages (from kaggle) (2.8.1)
Requirement already satisfied: python-slugify in /usr/local/lib/python3.6/dist-packages (from kaggle) (4.0.0)
Requirement already satisfied: six>=1.10 in /usr/local/lib/python3.6/dist-packages (from kaggle) (1.12.0)
Requirement already satisfied: urllib3<1.25,>=1.21.1 in /usr/local/lib/python3.6/dist-packages (from kaggle) (1.24.3)
Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.6/dist-packages (from requests->kaggle) (3.0.4)
Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.6/dist-packages (from requests->kaggle) (2.9)
Requirement already satisfied: text-unidecode>=1.3 in /usr/local/lib/python3.6/dist-packages (from python-slugify->kaggle) (1.3)
Saving kaggle.json to kaggle.json
{'kaggle.json': b'{"username":"your_name","key":"your_key"}'}
ls -1ha kaggle.json
kaggle.json
!mkdir -p ~/.kaggle # 파일 생성
!mv kaggle.json ~/.kaggle/ # kaggle.json 파일 이동
!chmod 600 ~/.kaggle/kaggle.json # 권한 부여
! kaggle competitions download -c m5-forecasting-accuracy
Warning: Looks like you're using an outdated API Version, please consider updating (server 1.5.6 / client 1.5.4)
Downloading sales_train_validation.csv.zip to /content
100% 15.5M/15.5M [00:00<00:00, 56.9MB/s]
Downloading sample_submission.csv.zip to /content
0% 0.00/163k [00:00<?, ?B/s]
100% 163k/163k [00:00<00:00, 146MB/s]
Downloading sell_prices.csv.zip to /content
63% 9.00M/14.2M [00:00<00:00, 52.0MB/s]
100% 14.2M/14.2M [00:00<00:00, 69.6MB/s]
Downloading calendar.csv to /content
0% 0.00/101k [00:00<?, ?B/s]
100% 101k/101k [00:00<00:00, 98.8MB/s]
!unzip sales_train_validation.csv.zip
!unzip sample_submission.csv.zip
!unzip sell_prices.csv.zip
Archive: sales_train_validation.csv.zip
inflating: sales_train_validation.csv
Archive: sample_submission.csv.zip
inflating: sample_submission.csv
Archive: sell_prices.csv.zip
inflating: sell_prices.csv
!ls
calendar.csv sample_data sell_prices.csv
sales_train_validation.csv sample_submission.csv sell_prices.csv.zip
sales_train_validation.csv.zip sample_submission.csv.zip
import pandas as pd
sales_train_val = pd.read_csv('sales_train_validation.csv')
print(sales_train_val.head())
id item_id ... d_1912 d_1913
0 HOBBIES_1_001_CA_1_validation HOBBIES_1_001 ... 1 1
1 HOBBIES_1_002_CA_1_validation HOBBIES_1_002 ... 0 0
2 HOBBIES_1_003_CA_1_validation HOBBIES_1_003 ... 1 1
3 HOBBIES_1_004_CA_1_validation HOBBIES_1_004 ... 7 2
4 HOBBIES_1_005_CA_1_validation HOBBIES_1_005 ... 2 4
[5 rows x 1919 columns]
calendar = pd.read_csv('calendar.csv')
print(calendar.head())
date wm_yr_wk weekday ... snap_CA snap_TX snap_WI
0 2011-01-29 11101 Saturday ... 0 0 0
1 2011-01-30 11101 Sunday ... 0 0 0
2 2011-01-31 11101 Monday ... 0 0 0
3 2011-02-01 11101 Tuesday ... 1 1 0
4 2011-02-02 11101 Wednesday ... 1 0 1
[5 rows x 14 columns]
sample_submission = pd.read_csv('sample_submission.csv')
print(sample_submission.head())
id F1 F2 F3 F4 ... F24 F25 F26 F27 F28
0 HOBBIES_1_001_CA_1_validation 0 0 0 0 ... 0 0 0 0 0
1 HOBBIES_1_002_CA_1_validation 0 0 0 0 ... 0 0 0 0 0
2 HOBBIES_1_003_CA_1_validation 0 0 0 0 ... 0 0 0 0 0
3 HOBBIES_1_004_CA_1_validation 0 0 0 0 ... 0 0 0 0 0
4 HOBBIES_1_005_CA_1_validation 0 0 0 0 ... 0 0 0 0 0
[5 rows x 29 columns]
sell_prices = pd.read_csv('sell_prices.csv')
print(sell_prices.head())
store_id item_id wm_yr_wk sell_price
0 CA_1 HOBBIES_1_001 11325 9.58
1 CA_1 HOBBIES_1_001 11326 9.58
2 CA_1 HOBBIES_1_001 11327 8.26
3 CA_1 HOBBIES_1_001 11328 8.26
4 CA_1 HOBBIES_1_001 11329 8.26
III. Data Exploration
- 데이터 탐색을 위해 사전준비를 진행해보자.
import pandas as pd
import numpy as np
import matplotlib.pylab as plt
import seaborn as sns
from itertools import cycle
pd.set_option('max_columns', 50)
plt.style.use('bmh')
color_pal = plt.rcParams['axes.prop_cycle'].by_key()['color']
color_cycle = cycle(plt.rcParams['axes.prop_cycle'].by_key()['color'])
pd.set_optinos('max_columns', 50)
, 컬럼 출력개수를 의미한다.- 그 외 나머지 코드는 그래프의 색상과 의미가 있다.
(1) 각 id
에 대한 시각화
- 다음과 같은 순서대로 시각화를 진행한다.
- item을 선택한다.
- id를 index로 지정 후,
sales
sales
데이터의column
만 지정한다. - 위 값을
column
으로 변환한다. - 데이터를 시각화 한다.
# extract sales data columns
d_cols = [c for c in sales_train_val.columns if 'd_' in c] # sales data columns
# print(d_cols)
sales_train_val.loc[sales_train_val['id'] == 'FOODS_3_090_CA_3_validation']\
.set_index('id')[d_cols]\
.T\
.plot(figsize=(15,5),
title = 'FOODS_3_090_CA_3 sales by "d" number', color = next(color_cycle))
plt.legend('')
plt.show()
T
는columns & index
위치를 바꿔주는 기능을 가지고 있다.
(2) 데이터 Merge
- 2개의 데이터를
Merge
하도록 한다.
temp = sales_train_val[sales_train_val['id'] == 'FOODS_3_090_CA_3_validation'][d_cols].T
print(temp.head())
8412
d_1 108
d_2 132
d_3 102
d_4 120
d_5 106
8412
의 column명을FOODS_3_090_CA_3_validation
로 변경한다.- 그리고
index
에d
로column
명을 변경 한다.
temp = temp.rename(columns={8412:'FOODS_3_090_CA_3'}).reset_index().rename(columns={'index': 'd'})
print(temp.head())
d FOODS_3_090_CA_3
0 d_1 108
1 d_2 132
2 d_3 102
3 d_4 120
4 d_5 106
calender
데이터셋과Merge
한다.
temp = temp.merge(calendar, how='left', validate='1:1')
print(temp.head())
d FOODS_3_090_CA_3 date wm_yr_wk weekday wday month year \
0 d_1 108 2011-01-29 11101 Saturday 1 1 2011
1 d_2 132 2011-01-30 11101 Sunday 2 1 2011
2 d_3 102 2011-01-31 11101 Monday 3 1 2011
3 d_4 120 2011-02-01 11101 Tuesday 4 2 2011
4 d_5 106 2011-02-02 11101 Wednesday 5 2 2011
event_name_1 event_type_1 event_name_2 event_type_2 snap_CA snap_TX \
0 NaN NaN NaN NaN 0 0
1 NaN NaN NaN NaN 0 0
2 NaN NaN NaN NaN 0 0
3 NaN NaN NaN NaN 1 1
4 NaN NaN NaN NaN 1 0
snap_WI
0 0
1 0
2 0
3 0
4 1
- 날짜별 기준으로
FOODS_3_090_CA_3
에 관한 그래프를 작성한다.
temp.set_index('date')['FOODS_3_090_CA_3']\
.plot(figsize=(15,5),
color=next(color_cycle),
title='FOODS_3_090_CA_3 sales by actual sale dates')
plt.show()
- 이번에는
HOBBIES_1_234_CA_3
에 대한 데이터를Merge
하여 시각화를 작성해보자.
temp2 = sales_train_val[sales_train_val['id'] == 'HOBBIES_1_234_CA_3_validation'][d_cols].T
temp2 = temp2.rename(columns={6324:'HOBBIES_1_234_CA_3'}) # name it correctly
temp2 = temp2.reset_index().rename(columns={'index':'d'}) # make the index 'd'
temp2 = temp2.merge(calendar, how='left', validate='1:1')
print(temp2.head())
d HOBBIES_1_234_CA_3 date wm_yr_wk weekday wday month \
0 d_1 0 2011-01-29 11101 Saturday 1 1
1 d_2 0 2011-01-30 11101 Sunday 2 1
2 d_3 0 2011-01-31 11101 Monday 3 1
3 d_4 0 2011-02-01 11101 Tuesday 4 2
4 d_5 0 2011-02-02 11101 Wednesday 5 2
year event_name_1 event_type_1 event_name_2 event_type_2 snap_CA snap_TX \
0 2011 NaN NaN NaN NaN 0 0
1 2011 NaN NaN NaN NaN 0 0
2 2011 NaN NaN NaN NaN 0 0
3 2011 NaN NaN NaN NaN 1 1
4 2011 NaN NaN NaN NaN 1 0
snap_WI
0 0
1 0
2 0
3 0
4 1
temp2.set_index('date')['HOBBIES_1_234_CA_3']\
.plot(figsize=(15,5),
color=next(color_cycle),
title='HOBBIES_1_234_CA_3 sales by actual sale dates')
plt.show()
- 이번에는
HOUSEHOLD_1_118_CA_3_validation
를Merge
하여 시각화를 진행해보자.
temp3 = sales_train_val[sales_train_val['id'] == 'HOUSEHOLD_1_118_CA_3_validation'][d_cols].T
temp3 = temp3.rename(columns={6776:'HOUSEHOLD_1_118_CA_3'}) # name it correctly
temp3 = temp3.reset_index().rename(columns={'index':'d'}) # make the index 'd'
temp3 = temp3.merge(calendar, how='left', validate='1:1')
temp3.set_index('date')['HOUSEHOLD_1_118_CA_3']\
.plot(figsize=(15,5),
color=next(color_cycle),
title='HOUSEHOLD_1_118_CA_3 sales by actual sale dates')
plt.show()
(3) 연월 요일 기준으로 한 Sales 시각화
- 연도, 월, 요일을 기준으로 위 3가지 데이터에 대한 값 시각화를 진행한다.
temps = ['FOODS_3_090_CA_3','HOBBIES_1_234_CA_3','HOUSEHOLD_1_118_CA_3']
temps_df = [temp, temp2, temp3]
for i in [0, 1, 2]:
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(15,3))
# wday 시각화
temps_df[i].groupby('wday').mean()[temps[i]]\
.plot(kind='line',
title='average sale: day of week',
lw = 5,
color=color_pal[0],
ax=ax1)
# month 시각화
temps_df[i].groupby('month').mean()[temps[i]]\
.plot(kind='line',
title='average sale: day of month',
lw = 5,
color=color_pal[4],
ax=ax2)
# year 시각화
temps_df[i].groupby('year').mean()[temps[i]]\
.plot(kind='line',
title='average sale: day of year',
lw = 5,
color=color_pal[2],
ax=ax3)
# suptitle
fig.suptitle(f'Trens for item: {temps[i]}',
size=20,
y=1.1)
plt.tight_layout()
plt.show()
tight_layout
함수는 각 데이터에 관한 여백(padding
)에 관련된subplot
파라미터를 조정한다.- 위 3개의
item
만 가지고 비교 했을 경우에는HOBBIES_1_234_CA_3
이 다른 두 아이템에 비해 평균적인sales
가 높은 것으로 확인되고 있다.
IV. 결론
- Kaggle에서 데이터를 다운로드 받는 부분을 수행하였고, 이 부분을 통해서 이제 여러분들이 적극적으로 코드를 경험하기를 바란다.
- 오늘 코드에서 중요한 부분은 서로 다른 데이터를 어떻게
Merge
할 것인가가 핵심이고, 이 때T
라는 함수를 활용하여 행과 열을transpose
하는 것이 주요 핵심 사항이다. - 다음에는
sample item
30개를 조회해서 시각화를 구현하고,sector
별로판매개수
추이를 확인할 수 있는 시각화를 진행한다.
V. Reference
- M5 Forecasting Start Data Exploration. Retrieved from https://www.kaggle.com/robikscube/m5-forecasting-starter-data-exploration