728x90
반응형

 

https://www.kaggle.com/competitions/competitive-data-science-predict-future-sales/data

 

Predict Future Sales | Kaggle

 

www.kaggle.com

1. 향후 판매량 예측

 

==> 2013년 1월 부터 2015년 10월까지 판매 데이터를 기반으로 2015년 11월 판매량 예측

 

 

독립변수(피처) : 상점 및 상품에 관한 정보

 

종속변수(타깃값) : 월간 판매량

 

==> 월간 판매량은 0~20개 사이여야 한다. ==> 판매량이 20개보다 많으면 20개로 간주한다는 뜻이다.

 

2. 탐색적 데이터 분석

1> sales_train 데이터

 

sales_train.head()

sales_train 데이터


==>  date 피처는 날짜를 의미

==> date_block_num 피처는 편의상 상용하는 날짜(월) 구분자, 0은 2013년 2월, 1은 2013년 3월

==> item_cnt_Day 피처는 당일 판매량을 나타낸다.

==> 각 상점의 상품별 일일 판매량을 월별로 합친 값이 곧 각 상점의 상품별 월간 판매량이다.

==> date_block_num 피처를 기준으로 그룹화해서 item_cnt_day 값을 합하면 타깃값(월간 판매량)이 된다.

 

 

sales_train.info(show_counts = True) # show_counts 는 비결측값 개수 표시

sales_info

 

==> 메모리 사용량이 134.4MB

==> 제공한 데이터는 시계열 데이터이다.

==> 시계열 데이터는 시간 흐름이 중요하다.

==> 2013년 1월부터 2015년 9월까지 판매 내역을 훈련 데이터로 사용하고,

==> 2015년 10월 판매 내역을 검증 데이터로 사용한다.

==> 앞 장에서는 여러 폴드로 나눠 훈련 데이터와 검증 데이터를 지정했다.(oof 예측) 하지만 시계열 데이터는 이러면 과거와 미래가 섞이기 때문에 이용할 수 없다.

 

 

※ OOF(Out of Fold Prediction) 방식


 ==> K 폴드 교차 검증을 수행하면서 각 폴드마다 테스트 데이터로 예측하는 방식이다.

==> K 폴드 교차 검증을 하면서 폴드마다

 

1) 훈련 데이터로 모델을 훈련하고,

 

2)검증 데이터로 모델 성능을 측정하며 ,

 

3) 테스트 데이터로 최종 타깃 확률도 예측한다. 훈련된 모델로 마지막에 한 번만 예측하는 것이 아니다. 각 폴드별 모델로 여러번 예측해 평균을 내는 방식이다.

 

 

2> shops 데이터

shops 데이터

==> shop_name 피처의 값들의 맨 앞 단어들이 도시 이름이다.

 

==> shop_id 의 경우 sales_train에도 있던 피처이므로 병합이 가능하다.

 

3> items 데이터

 

items 데이터

==> 상품명에서는 유용한 정보를 얻기 힘들어, 모델링 할 땐 제거한다.

 

==> item_id 피처는 sales_train 데이터에도 존재하는 피처이므로, item_id 피처를 기준으로 sales_train과 items를 병합할 수 있다.

 

 

4> item_categories 데이터

 

item category

==> 상품분류명과 상품분류 ID로 구성되어 있다.

 

5> test 데이터

 

test

==> 테스트 데이터 식별자인 ID와 상점 ID , 상품ID로 구성돼 있다.

여기서 각 상점의 상품별 월간 판매량을 예측해야한다.

 

3. 데이터 병합

train = sales_train.merge(shops , on = 'shop_id' , how ='left')
train = train.merge(items , on = 'item_id' , how = 'left')
train = train.merge(item_categories , on = 'item_category_id' , how = 'left')

train

train , shops, items , item_categories 병합

요약표

 

def resumetable(df):
    print(f'데이터셋 형상 : {df.shape}')
    summary = pd.DataFrame(df.dtypes , columns = ['데이터타입'])
    summary = summary.reset_index()
    summary = summary.rename(columns= {'index' : '피처'})
    summary['결측값 개수'] = df.isnull().sum().values # 결측값의 개수 세기
    summary['고윳값 개수'] = df.nunique().values # 고윳값의 개수 ㅅ기
    summary['첫 번째 값'] = df.loc[0].values
    summary['두 번째 값'] = df.loc[1].values

    return summary

resumetable(train)

피처요약표

==> shop_id , shop_name  ==> 개수 동일

 

==> item_category_id , item_category_name ==> 개수 동일 

 

==> id와 name은 일대일로 매칭된다는 뜻이다.

 

 

4. 데이터 시각화

import seaborn as sns
import matplotlib as mpl
import matplotlib.pyplot as plt
%matplotlib inline

sns.boxplot(y='item_cnt_day' , data = train)

# 이상치가 많아 모양이 납작해졌다. 과한 이상치는 제거해야 한다.

박스플롯

==> 이상치 범위가 과도하게 넓어서 납작해보인다.

 

 

1> 그룹화

 

# 그룹화는 회귀 문제에서 자주 쓰인다. groupby() 함수

group = train.groupby('date_block_num').agg({'item_cnt_day' : 'sum'})
# date_block_num 피처를 기준으로 그룹화해 item_cnt_day 피처의 합(sum)을 구하는 코드이다.
# 월별(date_block_num) 월간 판매량(item_cnt_day)의 합을 구한다는 말이다.
group.reset_index()

groupby

 

 

 groupby 원리

1. DataFrame에 있는 한 개 이상의 피처를 기준으로 데이터를 분리한다.

 2. 분리된 각 그룹에 함수를 적용해 집계값을 구한다.(agg() 메서드로 item_cnt_day 피처에 'sum'함수를 적용해 판매량 합계를 구한다.

 3. 기준 피처별로 집계값 결과를 하나로 결합한다.

# sum , mean ,median ,std ,var , count , min , max

 

 

mpl.rc('font' , size = 13)
figure , ax = plt.subplots()
figure.set_size_inches(11,5)

# 월별 총 상품 판매량

group_month_sum = train.groupby('date_block_num').agg({'item_cnt_day' : 'sum'})
group_month_sum = group_month_sum.reset_index()

# 월별 총 상품 판매량 막대 그래프

sns.barplot(x = 'date_block_num' , y ='item_cnt_day' , data = group_month_sum)

# 그래프 제목 , x축 라벨, y축 라벨명 설정
ax.set(title = 'Distribution of monthly item counts by date block number' ,
       xlabel = 'Date block number' ,
       ylabel = 'Monthly item counts')

groupby 시각화

figure, ax = plt.subplots()
figure.set_size_inches(11,5)

# 상품분류별 총 상품 판매량

group_cat_sum = train.groupby('item_category_id').agg({'item_cnt_day' : 'sum'})
group_cat_sum = group_cat_sum.reset_index()

# 월간 판매량이 10,000개를 초과하는 상품분류만 추출
group_cat_sum = group_cat_sum[group_cat_sum['item_cnt_day'] > 10000]

# 상품분류별 총 상품 판매량 막대 그래프
sns.barplot(x = 'item_category_id' , y = 'item_cnt_day' , data = group_cat_sum)
ax.set(title = 'Distribution of total item counts by item category id' ,
       xlabel = 'Date block number',
       ylabel = 'Total item counts')
ax.tick_params(axis = 'x' , labelrotation = 90) # x축 라벨 회전

groupby 시각화

figure , ax = plt.subplots()
figure.set_size_inches(11,5)

# 상점별 총 상품 판매량
group_shop_sum = train.groupby('shop_id').agg({'item_cnt_day' : 'sum'})
group_shop_sum = group_shop_sum.reset_index()

group_shop_sum = group_shop_sum[group_shop_sum['item_cnt_day'] > 10000]

# 상점별 총 상품 판매량 막대 그래프
sns.barplot(x = 'shop_id' , y= 'item_cnt_day' , data = group_shop_sum)
ax.set(title = 'Distribution of total item counts by shop id',
       xlabel = 'Date block number',
       ylabel = 'Total item counts')
ax.tick_params(axis = 'x' , labelrotation =90)
728x90
반응형

+ Recent posts