반응형
목차
1. 개요
2. Data 설명
3. EDA
4. 결론
5. 참고 url

# 개요

https://www.kaggle.com/c/instacart-market-basket-analysis

 

Instacart Market Basket Analysis

Which products will an Instacart consumer purchase again?

www.kaggle.com

당신이 꼼꼼하게 계획된 식료품 리스트를 기반으로 쇼핑을 하든, 충독적으로 쇼핑하든, 우리의 음식구매패턴은 우리가 누구인지 정의한다. 식료품 주문 및 배달 앱인 Instacart는 필요할 때 냉장고와 선반안에 당신이 가장 좋아하는 것으로 쉽게 채울 수 있도록 하는 것을 목표로 한다. 인스타카트 앱을 통해 상품을 고른 후, 자신의 장바구니를 검토하고 구매한다. 

Instacart의 데이터 분석팀은 이 즐거운 쇼핑 경험을 제공하는 데 큰 역할을 한다. 현재 그들은 사용자가 어떤 제품을 다시 구매할지 예측하거나, 처음 구매하거나, 다음에 장바구니에 추가할지를 예측하는 모델을 개발하기 위해 트랜잭션 데이터를 사용한다. 최근에, Instacart는 300만 개의 데이터를 오픈했다.


이 경쟁에서, Instacart는 kaggle 에서 어떤 제품이 사용자의 다음 구매에 포함될 것인지를 예측하기 위한 데이터분석 모델을 찾고 있다.


# Data 설명
Data Data Column
  • order_products_train_df : train(현재) 구매자군의 제품주문내역
  • order_products_prior_df : prior(과거) 구매자군의 제품주문내역
  • orders_df : 주문정보
  • products_df : 제품정보
  • aisles_df : 제품 상세카테고리
  • departments_df : 제품 카테고리
  • order_id : 주문 고유 아이디
  • user_id : 소비자 고유 아이디
  • product_id  : 제품 고유 아이디
  • eval_set : 소비자 군 ( prior / train / test )
  • order_number : 주문번호  
  • order_dow : 요일
  • order_hour_of_day : 일일 중 시간  
  • days_since_prior_order : 
  • add_to_cart_order : 장바구니 담은 제품 개수
  • reordered : 재주문 제품 개수 
  • product_name : 제품 이름 
  • aisle_id : 제품 상세카테고리 고유 아이디
  • department_id : 제품 카테고리 고유 아이디
  • aisle :  제품 상세카테고리
  • department : 제품 카테고리

# EDA

Step1 . 라이브러리 / DataSet 불러오기

 

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import matplotlib.pyplot as plt
import seaborn as sns
color = sns.color_palette()

%matplotlib inline

pd.options.mode.chained_assignment = None
# matplotlib 한글 폰트 깨짐 방지

from matplotlib import font_manager, rc
font_name = font_manager.FontProperties(fname="c:/Windows/Fonts/malgun.ttf").get_name()
rc('font', family=font_name) ​
order_products_train_df = pd.read_csv(r'파일저장 경로\order_products__train.csv')
order_products_prior_df = pd.read_csv(r'파일저장 경로\order_products__prior.csv')
orders_df = pd.read_csv(r'파일저장 경로\orders.csv')
products_df = pd.read_csv(r'파일저장 경로\products.csv')
aisles_df = pd.read_csv(r'파일저장 경로\aisles.csv')
departments_df = pd.read_csv(r'파일저장 경로\departments.csv')

 

Step 2 . EDA

 

  • 각 그룹군 그래프로 나타내기
cnt_srs = orders_df.eval_set.value_counts()
plt.figure(figsize=(12,8)) 
sns.barplot(cnt_srs.index, cnt_srs.values, alpha=0.8, color=color[1]) 
plt.ylabel('총 갯수', fontsize=12) 
plt.xlabel('고객 Type 군', fontsize=12) 
plt.title('각 고객군의 수', fontsize=15) 
plt.show()

def get_unique_count(x):
    return len(np.unique(x))

cnt_srs = orders_df.groupby("eval_set")["user_id"].aggregate(get_unique_count)
cnt_srs

 

  • 각 고객별로 가장 많이 주문한 개수를 그래프로 나타내기
cnt_srs = orders_df.groupby("user_id")["order_number"].aggregate(np.max).reset_index()
cnt_srs = cnt_srs.order_number.value_counts()

plt.figure(figsize=(12,8))
sns.barplot(cnt_srs.index, cnt_srs.values, alpha=0.8, color=color[2])
plt.ylabel('구매 발생 횟수', fontsize=12)
plt.xlabel('Maximum 구매 갯수', fontsize=12)
plt.xticks(rotation='vertical')
plt.show()

 

  • 요일별 구매량 추이 확인
plt.figure(figsize=(20,15))
sns.countplot(x="order_dow", data=orders_df, color=color[0]) # order_dow 는 요일을 의미
plt.xlabel('요일', fontsize=12)
plt.ylabel('구매량', fontsize=12)
plt.xticks([2,3,4,5,6,0,1],['월','화','수','목','금','토','일'])
plt.title("요일별 구매량", fontsize=15)
plt.show()

  • 각 시간대별로 구매개수 그래프로 나타내기
orders_df

                        order_id      user_id        eval_set        order_number    order_dow  order_hour_of_day  days_since_prior_order  

0 2539329 1 prior 1 2 8 NaN
1 2398795 1 prior 2 3 7 15.0
2 473747 1 prior 3 3 12 21.0
3 2254736 1 prior 4 4 7 29.0
4 431534 1 prior 5 4 15 28.0
... ... ... ... ... ... ... ...
3421078 2266710 206209 prior 10 5 18 29.0
3421079 1854736 206209 prior 11 4 10 30.0
3421080 626363 206209 prior 12 1 12 18.0
3421081 2977660 206209 prior 13 1 12 7.0
3421082 272231 206209 train 14 6 14 30.0
plt.figure(figsize=(12,8))
sns.countplot(x="order_hour_of_day", data=orders_df, color=color[1])
plt.ylabel('구매량', fontsize=12)
plt.xlabel('하루 중 시간', fontsize=12)
plt.title("하루 중 구매량", fontsize=15)
plt.show()

 

  • 요일별/ 시간대별 구매 추이 확인
grouped_df = orders_df.groupby(['order_dow','order_hour_of_day'])['order_number'].aggregate('count').reset_index()
grouped_df = grouped_df.pivot('order_dow','order_hour_of_day','order_number')

plt.figure(figsize = (18,9))
sns.heatmap(grouped_df)
plt.title('요일별/시간별 구매량')
plt.yticks([2,3,4,5,6,0,1],['월','화','수','목','금','토','일'])
plt.show()

 

  • prior 고객군 대상 분석
plt.figure(figsize=(12,8))
sns.countplot(x='days_since_prior_order', data= orders_df, color=color[3])
plt.ylabel('판매량',fontsize=12)
plt.xlabel('prior 주문 일수', fontsize = 12)
plt.xticks(rotation='vertical')
plt.title('prior 구매의 일별 빈도분포')

#판매량이 가장 높은 요일은 30일, 낮은 요일은 25일 이다. 1일~7일까지는 증가추세이고, 8일~29일까지는 감소추세이다.

# prior 고객군의 재주문율
order_products_prior_df.reordered.sum() / order_products_prior_df.shape[0]

0.5896974667922161

# train 고객군의 재주문율
order_products_train_df.reordered.sum() / order_products_train_df.shape[0]

0.5985944127509629

# prior 고객들 중 재주문한 경험이 있을 경우 1, 없을 경우 0 으로 데이터를 정제한다.

grouped_df = order_products_prior_df.groupby('order_id')['reordered'].aggregate('sum').reset_index()
grouped_df['reordered'].ix[grouped_df['reordered'] > 1] = 1
grouped_df.reordered.value_counts() / grouped_df.shape[0]

1 0.879151

0 0.120849 

 

해석 ) prior 고객들 중 재주문한 경험이 있는 경우는 약 88% prior 고객들 중 재주문한 경험이 없는 경우는 약 12%

 

# train 고객들 중 재주문한 경험이 있을 경우 1, 없을 경우 0 으로 데이터를 정제한다.

grouped_df = order_products_train_df.groupby('order_id')['reordered'].aggregate('sum').reset_index()
grouped_df['reordered'].ix[grouped_df['reordered'] > 1] = 1
grouped_df.reordered.value_counts() / grouped_df.shape[0]

 

1 0.93444

0 0.06556

 

해석 ) prior 고객들 중 재주문한 경험이 있는 경우는 약 93% prior 고객들 중 재주문한 경험이 없는 경우는 약 7%

# grouped_df 은 구매자별로 add_to_cart_order 에 담았던 제품의 총 개수

grouped_df = order_products_train_df.groupby('order_id')['add_to_cart_order'].aggregate('max').reset_index()

# cnt_srs 는 add_to_cart_order 에 담긴 각각의 값이 나온 개수
cnt_srs = grouped_df['add_to_cart_order'].value_counts()

 

plt.figure(figsize=(12,8))
sns.barplot(cnt_srs.index, cnt_srs.values, alpha=0.8)
plt.ylabel('발생 건수', fontsize = 12)
plt.xlabel('add_to_cart_order 에 담긴 제품의 개수', fontsize = 12)
plt.xticks(rotation='vertical')
plt.show()

order_products_prior_df.head()

                                      order_id                    product_id              add_to_cart_order     reordered

0 2 33120 1 1
1 2 28985 2 1
2 2 9327 3 0
3 2 45918 4 1
4 2 30035 5 0
order_products_prior_df.tail()

                                           order_id                   product_id        add_to_cart_order        reordered

32434484 3421083 39678 6 1
32434485 3421083 11352 7 0
32434486 3421083 4600 8 0
32434487 3421083 24852 9 1
32434488 3421083 5020 10 1
order_products_prior_df = pd.merge(order_products_prior_df, products_df, on= "product_id" , how="left")
order_products_prior_df = pd.merge(order_products_prior_df, aisles_df, on='aisle_id', how='left')
order_products_prior_df = pd.merge(order_products_prior_df, departments_df, on='department_id', how='left')
order_products_prior_df.head()

                  order_id    product_id   add_to_cart_order reordered  product_name  aisle_id  department_id  aisle  department

0 2 33120 1 1 Organic Egg Whites 86 16 eggs dairy eggs
1 2 28985 2 1 Michigan Organic Kale 83 4 fresh vegetables produce
2 2 9327 3 0 Garlic Powder 104 13 spices seasonings pantry
3 2 45918 4 1 Coconut Butter 19 13 oils vinegars pantry
4 2 30035 5 0 Natural Sweetener 17 13 baking ingredients pantry

 

  • 판매개수 높은 제품 확인
cnt_srs = order_products_prior_df['product_name'].value_counts().sort_values(ascending=False).reset_index().head(20)
cnt_srs.columns = ['제품 이름','판매 갯수']
cnt_srs

# organic 제품이 대다수의 상위권을 차지한 것을 알 수 있다

                                                          제품 이름                                  판매 갯수

0 Banana 472565
1 Bag of Organic Bananas 379450
2 Organic Strawberries 264683
3 Organic Baby Spinach 241921
4 Organic Hass Avocado 213584
5 Organic Avocado 176815
6 Large Lemon 152657
7 Strawberries 142951
8 Limes 140627
9 Organic Whole Milk 137905
10 Organic Raspberries 137057
11 Organic Yellow Onion 113426
12 Organic Garlic 109778
13 Organic Zucchini 104823
14 Organic Blueberries 100060
15 Cucumber Kirby 97315
16 Organic Fuji Apple 89632
17 Organic Lemon 87746
18 Apple Honeycrisp Organic 85020
19 Organic Grape Tomatoes 84255

 

  • 제품의 각 상세 카테고리별 판매량
cnt_srs = order_products_prior_df['aisle'].value_counts().head(20)
plt.figure(figsize=(12,8))
sns.barplot(cnt_srs.index, cnt_srs)
plt.xlabel('제품 상세 카테고리' , fontsize= 15)
plt.ylabel('구매량', fontsize= 15)
plt.xticks(fontsize = 15, rotation='vertical')
plt.show()

plt.figure(figsize=(10,10))
temp_series = order_products_prior_df['department'].value_counts()
labels = np.array(temp_series.index)
sizes = np.array((temp_series / temp_series.sum())* 100)
plt.pie(sizes, labels=labels, autopct='%1.1f%%' , startangle= 200)
plt.title('제품 카테고리 분포', fontsize= 15)
plt.show()

# produce(29.2%) 제품군 > dairy eggs(16.7%) > snacks(8.9%) > beverages(8.3%)제품군이 가장 많이 판매됬음을 알 수 있다

 

  • 제품 카테고리 별 재주문 현황

 

grouped_df = order_products_prior_df.groupby(['department'])['reordered'].aggregate('mean').reset_index()

plt.figure(figsize=(12,8))
sns.pointplot(grouped_df['department'].values,grouped_df['reordered'].values, alpha = 0.8 , color= color[2])
plt.xlabel('제품 카테고리', fontsize = 18)
plt.ylabel('재주문율' , fontsize= 18)
plt.xticks(rotation = 'vertical', fontsize = 15)
plt.yticks(fontsize = 15)
plt.title('제품 카테고리의 재주문율 ')
plt.show()

# dairy eggs 제품군의 재주문율이 가장 높다 personal care 제품군의 재주문율이 가장 낮다.

grouped_df = order_products_prior_df.groupby(['department_id', 'aisle'])['reordered'].aggregate('mean').reset_index()

fig, ax = plt.subplots(figsize=(15,20))
ax.scatter(grouped_df.reordered.values, grouped_df.department_id.values)

for i, txt in enumerate(grouped_df.aisle.values):
    ax.annotate(txt, (grouped_df.reordered.values[i],grouped_df.department_id.values[i]), rotation=45 , ha='center',va='center', color='green')

plt.xlabel('재주문율',fontsize = 20)
plt.ylabel('제품 카테고리 id',fontsize = 20)
plt.title('다른 제품 카테고리의 재주문율' , fontsize =20)
plt.show()

  • 장바구니에 추가와 재주문율의 상관관계에 대해 알아보기
order_products_prior_df['add_to_cart_order_mod'] = order_products_prior_df['add_to_cart_order'].copy()
order_products_prior_df['add_to_cart_order_mod'].ix[order_products_prior_df['add_to_cart_order_mod'] > 70] = 70
grouped_df = order_products_prior_df.groupby(['add_to_cart_order_mod'])['reordered'].aggregate('mean').reset_index()

plt.figure(figsize=(12,8))
sns.pointplot(grouped_df['add_to_cart_order_mod'].values, grouped_df['reordered'].values, alpha=0.8, color=color[2])
plt.xlabel('장바구니에 추가' , fontsize = 15)
plt.ylabel('재주문율', fontsize= 15)
plt.title('장바구니 추가와 재주문율 관계', fontsize=15)
plt.xticks(rotation= 'vertical')
plt.show()


# 제일 처음 장바구니에 추가된 제품이 나중에 추가된 제품에 비해 다시 주문될 가능성이 높다.
#이를 통해, 소비자들이 자주 사용하는 제품 먼저 주문 후 새로운 제품을 찾는 경향을 가지고 있음을 알 수 있다.

 

 

  • 요일별 재주문 추이 
order_products_train_df = pd.merge(order_products_train_df,orders_df,on='order_id',how='left')
grouped_df = order_products_train_df.groupby(['order_dow'])['reordered'].aggregate('mean').reset_index()

plt.figure(figsize=(12,8))
sns.barplot(grouped_df['order_dow'].values, grouped_df['reordered'].values,alpha=0.8, color = color[3])
plt.xlabel('요일', fontsize = 15)
plt.ylabel('재주문율',fontsize  =15)
plt.xticks(rotation='vertical')
plt.ylim(0.5,0.7)
plt.show()

 

  • 일일 시간대별 재주문율 추이
grouped_df= order_products_train_df.groupby('order_hour_of_day')['reordered'].aggregate('mean').reset_index()
plt.figure(figsize=(12,8))
sns.barplot(grouped_df['order_hour_of_day'].values, grouped_df['reordered'].values, alpha=0.8,color=color[4])
plt.xlabel('하루 중 시간', fontsize =15)
plt.ylabel('재주문율', fontsize =15)
plt.title('일별 재주문율', fontsize = 15)
plt.ylim(0.5,0.7)
plt.show()

 

  • 요일별/ 일일 시간대별 재주문율 현황확인
order_products_train_df

       order_id  product_id add_to_cart_order reordered  user_id eval_set  order_number  order_dow  order_hour_of_day  days_since_prior_order

0 1 49302 1 1 112108 train 4 4 10 9.0
1 1 11109 2 1 112108 train 4 4 10 9.0
2 1 10246 3 0 112108 train 4 4 10 9.0
3 1 49683 4 0 112108 train 4 4 10 9.0
4 1 43633 5 1 112108 train 4 4 10 9.0
... ... ... ... ... ... ... ... ... ... ...
1384612 3421063 14233 3 1 169679 train 30 0 10 4.0
1384613 3421063 35548 4 1 169679 train 30 0 10 4.0
1384614 3421070 35951 1 1 139822 train 15 6 10 8.0
1384615 3421070 16953 2 1 139822 train 15 6 10 8.0
1384616 3421070 4724 3 1 139822 train 15 6 10 8.0
grouped_df = order_products_train_df.groupby(['order_dow', 'order_hour_of_day'])['reordered'].aggregate('mean').reset_index()
grouped_df = grouped_df.pivot(values = 'reordered', columns= 'order_hour_of_day',index='order_dow')
plt.figure(figsize=(12,8))
sns.heatmap(grouped_df)
plt.title('요일별 재주문율 vs 일일별 재주문율 ')
plt.xlabel('하루 중 구매시간')
plt.ylabel('요일')
plt.yticks([2,3,4,5,6,0,1],['월','화','수','목','금','토','일'])
plt.show()


# 결과

 

prior 고객군 insight

  • prior 고객군의 최대 구매시간은 토요일 오후 1~3시 와 일요일 10시이다.
train 고객군 insight

  • train 고객군의 최대 구매시간은 수요일과 토요일 아침 6~7시간대이다.
  • train 고객군은 하루 중 6,7,8시에 재주문율이 가장 높고 9시 ~12시까지 주문율이 감소하는 경향을 보인다.

종합 insight

  • 시간별 판매량 : 아침 9시에 판매량이 가장 높고, 새벽 3시에 판매량이 가장 낮다.아침 9시~ 17시까지이 판매량의 70% 를 차지한다.
  • 요일별 판매량 : 판매량이 가장 높은 요일은 30일, 낮은 요일은 25일 이다. 1일~7일까지는 증가추세이고, 8일~29일까지는 감소추세이다.
  • 제품군에 따른 주문율 :produce(29.2%) 제품군 > dairy eggs(16.7%) > snacks(8.9%) > beverages(8.3%)제품군이 가장 많이 판매됬음을 알 수 있다
  • 상세 제품군에 따른 주문율 : organic 제품이 대다수의 판매 상위권을 차지한 것을 알 수 있다
  • 상세 제품군에 따른 재주문율 : dairy eggs 제품군의 재주문율이 가장 높다 personal care 제품군의 재주문율이 가장 낮다.
  • 장바구니와 관련된 구매성향 : 제일 처음 장바구니에 추가된 제품이 나중에 추가된 제품에 비해 다시 주문될 가능성이 높다. 이를 통해, 소비자들이 자주 사용하는 제품 먼저 주문 후 새로운 제품을 찾는 경향을 가지고 있음을 알 수 있다.

# 필사 참고 URL

 

https://www.kaggle.com/sudalairajkumar/simple-exploration-notebook-instacart

 

 

Simple Exploration Notebook - Instacart

Explore and run machine learning code with Kaggle Notebooks | Using data from Instacart Market Basket Analysis

www.kaggle.com

반응형

'Kaggle' 카테고리의 다른 글

[ Kaggle ] 초간단 Kaggle 에서 API로 데이터셋 다운받기  (0) 2020.03.30
반응형

1. CMD 창에서 kaggle 다운받기

$ pip install kaggle

 

2. Kaggle > My Count > API 에서 Create New API Token 을 누른 후 C:\Users\<Username>\.kaggle 에 다운받기

 

api token 다운받을 경로

3. 호출하려는 API 주소를 복사한다. 

 

예를들어 Instacart Market Basket Analysis 의 DataSet 을 다운로드하려고 한다.

맨 아래로 스크롤을 내려 Data API 주소를 클릭해 복사한다

 

4. 복사한 API 주소를 CMD 창에 붙여넣는다

5. 다운로드 완료된 것을 확인한다

 

 

 

참고 링크

https://github.com/Kaggle/kaggle-api

 

Kaggle/kaggle-api

Official Kaggle API. Contribute to Kaggle/kaggle-api development by creating an account on GitHub.

github.com

 

반응형

+ Recent posts