【Python】Eコマースサイトの販売データをabc_analysisプラグインでABCにグルーピングする【ECサイト】

ABC分析
この記事は約11分で読めます。

Eコマースサイトの販売データを利用して商品をABC分析します。
ABC分析をすることで、売れ筋商品、死に筋商品の見極めができ
商品開発や在庫管理をする際のヒントにします。


データはこちらを利用します。

E-Commerce Data
Actual transactions from UK retailer

コードの準備

Anacondaのjupyter notebookでコードを実行しています。
Pythonが動作する環境でしたらお好きな構成で構いません。

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

df = pd.read_csv('/ecommerce-data/data.csv', encoding="shift-jis")

def ABC_segmentation(perc):
    '''
    3つのクラスを作成する。
    次のパーセンテージによって分類する (A-70%, B-95%, C-5%)
    正規分布の1シータ、2シータに準じて70%–95%に分ける。グループCは残りの5%とする
    '''
    if perc > 0 and perc < 0.7:
        return 'A'
    elif perc >= 0.7 and perc < 0.95:
        return 'B'
    elif perc >= 0.95:
        return 'C'

df.head()

len(df)

df['StockCode'].nunique()

# 計算用にデータフレームを作成します。作成したデータフレームにカラムを追加していきます。
df_sub = df[['StockCode', 'Quantity', 'UnitPrice']].copy()

# Quantityが1以上のものを抽出
df_sub = df_sub.loc[df_sub['Quantity'] > 0]

# 販売レコードごとに商品価格と販売数で金額を算出します。
df_sub['Price'] = df_sub['UnitPrice'] * df_sub['Quantity']

# 商品ごとにグルーピングします。
df_sub = df_sub.groupby('StockCode')['Price'].sum().to_frame()
df_sub = df_sub.reset_index()

# 金額順でソートします。
df_sub = df_sub.sort_values(by=['Price'], ascending=False)

# 商品ごとに累積金額を算出します。
df_sub['RunCumPrice'] = df_sub['Price'].cumsum()

# 合計の列を作成します
df_sub['TotSum'] = df_sub['Price'].sum()

# 累積売上比の列を作成します
df_sub['RunPerc'] =  df_sub['RunCumPrice']/df_sub['TotSum']

# ABCセグメントの列Classを作成します
df_sub['Class'] = df_sub['RunPerc'].apply(ABC_segmentation)
df_sub['Price'] = df_sub['Price'].astype(np.int)

df_sub.head()

# 各クラスの合計数
df_sub.Class.value_counts()

# クラスごとの総売上
print ('Sales of Class A :', df_sub[df_sub.Class == 'A']['Price'].sum())
print ('Sales of Class B :', df_sub[df_sub.Class == 'B']['Price'].sum())
print ('Sales of Class C :', df_sub[df_sub.Class == 'C']['Price'].sum())

# クラスごとの総売上の割合
print ('Percent of Sales of Class A :', df_sub[df_sub.Class == 'A']['Price'].sum()/df_sub['Price'].sum())
print ('Percent of Sales of Class B :', df_sub[df_sub.Class == 'B']['Price'].sum()/df_sub['Price'].sum())
print ('Percent of Sales of Class C :', df_sub[df_sub.Class == 'C']['Price'].sum()/df_sub['Price'].sum())

performance = df_sub['Price'].tolist()
y_pos = np.arange(len(performance))

plt.plot(y_pos, performance)
plt.ylabel('Cost')
plt.title('ABC Analysis - Sales per StockCode')
plt.grid(True)
plt.ylim((0,250000))
plt.show()

performance = df_sub['RunPerc'].tolist()
y_pos = np.arange(len(performance))

plt.plot(y_pos, performance)
plt.ylabel('Running Total Percentage')
plt.title('ABC Analysis - Cumulative Sales per StockCode')
plt.grid(True)
plt.show()

df.head()

from abc_analysis import abc_analysis, abc_plot

# Perform an ABC analysis on a numeric vector (without plotting)
dctAnalysis = abc_analysis(df_sub['Price'])

# Plot saved results of an ABC analysis
abc_plot(dctAnalysis)

ライブラリのインポートとcsv読み込み

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

df = pd.read_csv('/ecommerce-data/data.csv', encoding="shift-jis")

商品をABCセグメントに分ける関数を宣言

def ABC_segmentation(perc):
    '''
    3つのクラスを作成する。
    次のパーセンテージによって分類する (A-70%, B-95%, C-5%)
    正規分布の1シータ、2シータに準じて70%–95%に分ける。グループCは残りの5%とする
    '''
    if perc > 0 and perc < 0.7:
        return 'A'
    elif perc >= 0.7 and perc < 0.95:
        return 'B'
    elif perc >= 0.95:
        return 'C'

データの中身を確認する

df.head()

len(df)

df['StockCode'].nunique()

前処理を行う

# 計算用にデータフレームを作成します。作成したデータフレームにカラムを追加していきます。
df_sub = df[['StockCode', 'Quantity', 'UnitPrice']].copy()

# Quantityが1以上のものを抽出
df_sub = df_sub.loc[df_sub['Quantity'] > 0]

# 販売レコードごとに商品価格と販売数で金額を算出します。
df_sub['Price'] = df_sub['UnitPrice'] * df_sub['Quantity']

# 商品ごとにグルーピングします。
df_sub = df_sub.groupby('StockCode')['Price'].sum().to_frame()
df_sub = df_sub.reset_index()

# 金額順でソートします。
df_sub = df_sub.sort_values(by=['Price'], ascending=False)

# 商品ごとに累積金額を算出します。
df_sub['RunCumPrice'] = df_sub['Price'].cumsum()

# 合計の列を作成します
df_sub['TotSum'] = df_sub['Price'].sum()

# 累積売上比の列を作成します
df_sub['RunPerc'] =  df_sub['RunCumPrice']/df_sub['TotSum']

# ABCグループの列を作成します
df_sub['Class'] = df_sub['RunPerc'].apply(ABC_segmentation)
df_sub['Price'] = df_sub['Price'].astype(np.int)

df_sub.head()

結果を確認する

# 各クラスの合計数
df_sub.Class.value_counts()

# クラスごとの総売上
print ('Sales of Class A :', df_sub[df_sub.Class == 'A']['Price'].sum())
print ('Sales of Class B :', df_sub[df_sub.Class == 'B']['Price'].sum())
print ('Sales of Class C :', df_sub[df_sub.Class == 'C']['Price'].sum())

# クラスごとの総売上の割合
print ('Percent of Sales of Class A :', df_sub[df_sub.Class == 'A']['Price'].sum()/df_sub['Price'].sum())
print ('Percent of Sales of Class B :', df_sub[df_sub.Class == 'B']['Price'].sum()/df_sub['Price'].sum())
print ('Percent of Sales of Class C :', df_sub[df_sub.Class == 'C']['Price'].sum()/df_sub['Price'].sum())

performance = df_sub['Price'].tolist()
y_pos = np.arange(len(performance))

plt.plot(y_pos, performance)
plt.ylabel('Cost')
plt.title('ABC Analysis - Sales per StockCode')
plt.grid(True)
plt.ylim((0,250000))
plt.show()

performance = df_sub['RunPerc'].tolist()
y_pos = np.arange(len(performance))

plt.plot(y_pos, performance)
plt.ylabel('Running Total Percentage')
plt.title('ABC Analysis - Cumulative Sales per StockCode')
plt.grid(True)
plt.show()

df.head()
Sales of Class A : 7447895
Sales of Class B : 2662765
Sales of Class C : 531945
Percent of Sales of Class A : 0.6998187943647256
Percent of Sales of Class B : 0.250198612087924
Percent of Sales of Class C : 0.04998259354735048

ABC分析を行う

from abc_analysis import abc_analysis, abc_plot

# Perform an ABC analysis on a numeric vector (without plotting)
dctAnalysis = abc_analysis(df_sub['Price'])

# Plot saved results of an ABC analysis
abc_plot(dctAnalysis)

abc_analysisに対し、データテーブルの価格を引数で渡すと
80%がA群、90%がB群、残り10%がC群に振り分けられました。

前処理で、正規分布のシータごとに分類しましたが、この結果に応じてセグメント関数を
変更しても良いです。
ABC分析は具体的にA群が80%とかB群が90%などルールは存在せず
データを見ながら判断する必要があります。

さいごに

ABC分析は実際に運営している実店舗およびWebサービスであれば適応できる分析手法です。
カフェ、レストランなどの飲食店はもちろんのこと、Eコマースサイトのデータを準備すれば
分析が可能になっています。上記コード例のcsvの部分を変更すれば応用可能です。

必要なデータは、商品コード、商品価格、販売数の3つです。
決済日付や、顧客番号は必要ありません。
運営しているサービスでやってみてはいかがでしょうか

タイトルとURLをコピーしました