kaggle 및 dacon

kaggle competition - H&M Recommendation EDA

jinmc 2022. 3. 20. 02:27
반응형

이번에 H&M contest를 시작해 보기로 합니다.

https://www.kaggle.com/c/h-and-m-personalized-fashion-recommendations

 

코드 리뷰 : https://www.kaggle.com/code/vanguarde/h-m-eda-first-look

 

데이터셋은 articles, customers, transactions 세 가지가 있습니다.

articles는 25가지의 column으로 이루어져 있습니다.

 

1. Articles EDA

 

articles.head() 로 볼 수 있죠.

 

article_id : A unique identifier of every article.
product_code, prod_name : A unique identifier of every product and its name (not the same).
product_type, product_type_name : The group of product_code and its name
graphical_appearance_no, graphical_appearance_name : The group of graphics and its name
colour_group_code, colour_group_name : The group of color and its name
perceived_colour_value_id, perceived_colour_value_name, perceived_colour_master_id, perceived_colour_master_name : The added color info
department_no, department_name: : A unique identifier of every dep and its name
index_code, index_name: : A unique identifier of every index and its name
index_group_no, index_group_name: : A group of indeces and its name
section_no, section_name: : A unique identifier of every section and its name
garment_group_no, garment_group_name: : A unique identifier of every garment and its name
detail_desc: : Details

 

matplotlib 의 pyplot과 seaborn을 통해서 index_name을 통해서 그룹한 histogram을 볼 수 가 있습니다.

import numpy as np
import pandas as pd
import seaborn as sns
from matplotlib import pyplot as plt
from tqdm.notebook import tqdm

라이브러리를 저장한 후에,

f, ax = plt.subplots(figsize=(15, 7))
ax = sns.histplot(data=articles, y='index_name', color='orange')
ax.set_xlabel('count by index name')
ax.set_ylabel('index name')
plt.show()

index_name이 아닌 다른 어떤 category로도 묶을 수 있겠죠!

histogram은 다음과 같이 나타납니다.

 

이번에는 의류의 카테고리별로 나누면서 그 안에서 남/녀/아동 층을 바탕으로 나눠보도록 하겠습니다.

코드는 다음과 같습니다.

 

f, ax = plt.subplots(figsize=(15, 7))
ax = sns.histplot(data=articles, y='garment_group_name', color='orange', hue='index_group_name', multiple="stack")
ax.set_xlabel('count by garment group')
ax.set_ylabel('garment group')
plt.show()

hue를 넣으면 그 안에서 또 나눠지고, stack 방식으로 그 나눠짐을 나타낸다는 사실을 알 수 있습니다.

다음과 같이 나옵니다.

 

articles, customers, transactions를 pandas를 이용해서 불러 주고, groupby와 count (둘 다 pandas library)를 통해서 실질적인 숫자를 확인해 봅시다.

 

articles = pd.read_csv("../input/h-and-m-personalized-fashion-recommendations/articles.csv")
customers = pd.read_csv("../input/h-and-m-personalized-fashion-recommendations/customers.csv")
transactions = pd.read_csv("../input/h-and-m-personalized-fashion-recommendations/transactions_train.csv")
articles.groupby(['index_group_name', 'index_name']).count()['article_id']

다음과 같이 나오게 됩니다

이중으로 분류도 가능합니다. 여기서 max_rows = None 부분을 빼주게 되면 10개의 row 만 나오게 되서, max_rows=None 코드도 추가해 줍니다.

pd.options.display.max_rows = None
articles.groupby(['product_group_name', 'product_type_name']).count()['article_id']

너무 길기 때문에 조금만 보여주도록 하겠습니다.

각 column 마다 얼마나 unique한 값들이 있는지를 봅시다

for col in articles.columns:
    if not 'no' in col and not 'code' in col and not 'id' in col:
        un_n = articles[col].nunique()
        print(f'n of unique {col}: {un_n}')

2. Customer eda

 

7개의 column이 있습니다.

pd.options.display.max_rows = 50
customers.head()

나이랑, 뉴스피드를 얼마나 자주 받는지, 지역은 어디인지, FN과 Active는 아직 잘 모르겠습니다.. ㅎㅎ

Discuss를 보니, FN은 Fashion news를 얼마나 받는지, Active 는 활동 여부라고 하네요!

customer_id 에 duplicate은 없는지 확실하게 보겠습니다.

customers.shape[0] - customers['customer_id'].nunique()

0 이 나오는군요. duplicate은 없는 것으로 보입니다.

postal code로 group_by 와 count를 한 이후 customer_id로 sort해보니 12만 명이 모여 있네요.

아마도 null이거나 집하장 주소 같은 것으로 보입니다.

data_postal = customers.groupby('postal_code', as_index=False).count().sort_values('customer_id', ascending=False)
data_postal.head()

어떤 customer들이 있는지를 보려면, 다음과 같은 코드를 사용할 수 있을 것 같습니다.

customers[customers['postal_code']=='2c29ae653a9282cce4151bd87643c907644e09541abc28ae87dea0d1f6603b1c'].head(5)

나이대를 살펴볼까요

import seaborn as sns
from matplotlib import pyplot as plt
sns.set_style("darkgrid")
f, ax = plt.subplots(figsize=(10,5))
ax = sns.histplot(data=customers, x='age', bins=50, color='orange')
ax.set_xlabel('Distribution of the customers age')
plt.show()

20대 초반이 확실히 많네요.

뉴스레터를 받는 사람의 비중을 어떻게 되는지도 알아봅시다.

 

pie_data = customers[['customer_id', 'fashion_news_frequency']].groupby('fashion_news_frequency').count()
sns.set_style("darkgrid")
f, ax = plt.subplots(figsize=(10,5))
# ax = sns.histplot(data=customers, x='fashion_news_frequency', color='orange')
# ax = sns.pie(data=customers, x='fashion_news_frequency', color='orange')
colors = sns.color_palette('pastel')
ax.pie(pie_data.customer_id, labels=pie_data.index, colors = colors)
ax.set_facecolor('lightgrey')
ax.set_xlabel('Distribution of fashion news frequency')
plt.show()

3. Transactions

 

가장 중요한 거래 데이터 입니다.

5개의 column이 있네요.

 

sales_channel_id는 뭔지 잘 모르겠네요.

price의 box plot을 살펴보도록 하겠습니다.

sns.set_style("darkgrid")
f, ax = plt.subplots(figsize=(10,5))
ax = sns.boxplot(data=transactions, x='price', color='orange')
ax.set_xlabel('Price outliers')
plt.show()

price가 0.02, 0.03 가 평균이네요. 단위가 달러인가요? 굉장히 낮네요

가장 많은 아이템을 산 열 명을 살펴보죠

transactions_byid = transactions.groupby('customer_id').count()
transactions_byid.sort_values(by='price', ascending=False)['price'][:10]

 

1895번 산 사람이 있네요..

product_group_name을 분류로 해서 box_plot을 그려볼까요

sns.set_style("darkgrid")
f, ax = plt.subplots(figsize=(25,18))
ax = sns.boxplot(data=articles_for_merge, x='price', y='product_group_name')
ax.set_xlabel('Price outliers', fontsize=22)
ax.set_ylabel('Index names', fontsize=22)
ax.xaxis.set_tick_params(labelsize=22)
ax.yaxis.set_tick_params(labelsize=22)

plt.show()

악세사리만 찾아볼까요

sns.set_style("darkgrid")
f, ax = plt.subplots(figsize=(25,18))
_ = articles_for_merge[articles_for_merge['product_group_name'] == 'Accessories']
ax = sns.boxplot(data=_, x='price', y='product_type_name')
ax.set_xlabel('Price outliers', fontsize=22)
ax.set_ylabel('Index names', fontsize=22)
ax.xaxis.set_tick_params(labelsize=22)
ax.yaxis.set_tick_params(labelsize=22)
del _

plt.show()

평균 가격으로 볼까요? index_name으로 분류해 보았습니다.

articles_index = articles_for_merge[['index_name', 'price']].groupby('index_name').mean()
sns.set_style("darkgrid")
f, ax = plt.subplots(figsize=(10,5))
ax = sns.barplot(x=articles_index.price, y=articles_index.index, color='orange', alpha=0.8)
ax.set_xlabel('Price by index')
ax.set_ylabel('Index')
plt.show()

이정도로 하겠습니다.

본문은 더 있는데 Seaborn과 matplotlib의 pyplot, pandas 에 대해서 많이 알아봤습니다.

 

반응형