iT邦幫忙

2026 iThome 鐵人賽

DAY 17
0
自我挑戰組

拯救混亂數據:30 天 Python 輕量級 ETL 與電商關聯資料分析系列 第 20 篇

[Day 20] 既然買家不回購,就在結帳時榨乾價值!用 Python 打造購物籃共現分析

  • 分享至 

  • xImage
  •  

回購無望時,唯一能救營收的解藥

在 Day 19 的顧客留存隊列分析中,熱力圖狠狠戳破了許多人對電商「自然回購」的幻想:Olist 的首月留存率低於 1%,這是一家徹底由「新客獲取」驅動的一次性撮合市集。

面對這種「客人在這輩子只打算付一次錢」的平台體質,行銷與產品團隊如果還把預算花在召回沈睡客,ROI 只會慘不忍睹。

真正的破局關鍵只有一個:極大化單次消費價值。

既然他這輩子只結帳這一次,我們就必須在結帳當下,想盡辦法讓他在購物車裡多塞一件商品!
這在零售與電商領域稱為「連帶率(Cross-selling Ratio)」與「購物籃分析(Market Basket Analysis)」。

今天我們將跳出單一品項思維,深入訂單明細表 order_items,篩選出多品項訂單,運用 Python 的 itertools 模組計算「品類共現矩陣(Category Co-occurrence Matrix)」,找出最適合搭售與結帳頁加價購的黃金品類搭檔!

步驟一:資料體檢——全平台有多少人會「一次買多件」?

在開始做關聯分析前,我們必須先摸清平台的底牌:全平台近 10 萬筆訂單中,
買家一次購買多件商品的比例到底有多高?

import pandas as pd
import numpy as np
from itertools import combinations
from collections import Counter
import matplotlib.pyplot as plt
import seaborn as sns

# 1. 取出訂單明細與已翻譯英文品類的商品資料 (來自 Day 12)
items = olist_db['olist_order_items_dataset'].copy()
products_en = pd.merge(
    olist_db['olist_products_dataset'],
    olist_db['product_category_name_translation'],
    on='product_category_name',
    how='left'
)

# 2. 統計每筆訂單包含的商品品項數量 (Item Count)
order_item_counts = items.groupby('order_id')['order_item_id'].count()

# 3. 檢視購物籃深度分佈
basket_distribution = order_item_counts.value_counts(normalize=True).head(5) * 100
print("--- 購物籃商品數量佔比 (%) ---")
print(basket_distribution.round(2))

實作 :

https://ithelp.ithome.com.tw/upload/images/20260928/20136155NLadAl45Bz.png

資料陷阱拆解:
數據揭示了另一個殘酷現實:高達 90% 的買家是「單件購買者」。
但正因為多品項訂單僅佔約 9%,這群「願意在同一張訂單放多件商品」的交易才更顯珍貴。
這 9% 的多品項訂單就是我們提煉搭售規則的黃金樣本。

步驟二:串聯英文品類,建構訂單品類清單 (Baskets)

同一張訂單裡可能買了「同一件商品的 2 個數量」,也可能買了「不同品類的互補品」。
為了挖掘跨品類交叉銷售(Cross-selling)機會,我們以 order_id 為單位,收集每筆訂單所購買的相異英文品類集合(Distinct Categories):

# 1. 明細表串接英文品類名稱
order_product_cat = pd.merge(
    items[['order_id', 'product_id']],
    products_en[['product_id', 'product_category_name_english']],
    on='product_id',
    how='inner'
)

# 2. 排除品類名稱缺失的極少數雜訊
order_product_cat.dropna(subset=['product_category_name_english'], inplace=True)

# 3. 核心轉換:依 order_id 聚合,取得每筆訂單包含的「不重複品類清單」
baskets = order_product_cat.groupby('order_id')['product_category_name_english'].unique()

# 4. 篩選出真正包含 2 個(含)以上「不同品類」的多品類訂單
cross_cat_baskets = baskets[baskets.apply(len) >= 2]

print(f"有效訂單總數: {len(baskets):,} 筆")
print(f"包含 2 種以上相異品類的訂單數: {len(cross_cat_baskets):,} 筆")

實作 :
https://ithelp.ithome.com.tw/upload/images/20260928/20136155RzY8iBEgn6.png

步驟三:共現特徵工程——利用 itertools.combinations 提取搭售對

當一張訂單同時包含 ['bed_bath_table', 'furniture_decor', 'home_confort'] 時,它代表這三個品類兩兩之間都產生了一次共現(Co-occurrence)。

我們利用 Python 標準函式庫 itertools.combinations,針對每筆購物籃進行兩兩組合拆解,並以字典進行計數:

# 1. 建立組合計數器
pair_counter = Counter()

# 2. 遍歷所有跨品類購物籃,提取無序兩兩配對 (Pairwise Combinations)
for cat_list in cross_cat_baskets:
    # 排序確保組合的唯一性 (例如 A+B 與 B+A 視為同一組)
    sorted_cats = sorted(cat_list)
    # 生成所有 2 個品類的組合
    for pair in combinations(sorted_cats, 2):
        pair_counter[pair] += 1

# 3. 轉化為 DataFrame 結構
pair_df = pd.DataFrame(
    pair_counter.most_common(20),
    columns=['category_pair', 'co_occurrence_count']
)

# 拆分欄位以利呈現
pair_df['Category_A'] = pair_df['category_pair'].apply(lambda x: x[0])
pair_df['Category_B'] = pair_df['category_pair'].apply(lambda x: x[1])
pair_df = pair_df[['Category_A', 'Category_B', 'co_occurrence_count']]

# 檢視最常被一起打包結帳的 Top 5 品類組合
pair_df.head(5)

實作:

https://ithelp.ithome.com.tw/upload/images/20260928/20136155Y5NvppkIyu.png

步驟四:視覺化與落地策略——打造交叉銷售搭售矩陣

我們取出共現頻次最高的品類群體,繪製出共現熱力圖,將數據轉化為產品與行銷團隊可落地的推薦策略:

# 1. 取出高頻品類建立二維共現矩陣
top_cats = list(set(pair_df.head(10)['Category_A']).union(set(pair_df.head(10)['Category_B'])))
matrix_df = pd.DataFrame(0, index=top_cats, columns=top_cats)

for _, row in pair_df.iterrows():
    c1, c2, cnt = row['Category_A'], row['Category_B'], row['co_occurrence_count']
    if c1 in top_cats and c2 in top_cats:
        matrix_df.loc[c1, c2] = cnt
        matrix_df.loc[c2, c1] = cnt

# 2. 繪製共現熱力矩陣
plt.figure(figsize=(9, 7))
sns.heatmap(matrix_df, annot=True, fmt='d', cmap='Reds', cbar_kws={'label': 'Co-occurrence Frequency'})
plt.title('Top Product Category Co-occurrence Matrix (Market Basket)', fontsize=13, fontweight='bold', pad=12)
plt.xticks(rotation=45, ha='right', fontsize=9)
plt.yticks(fontsize=9)
plt.tight_layout()
plt.show()

實作:

https://ithelp.ithome.com.tw/upload/images/20260928/201361553qkCpTSSil.png

如何用「搭售推薦」撬動客單價?

根據共現分析的結果,我們能為電商產品與營運團隊端出具體的改版提案:

1.居家場景黃金搭檔(Bed/Bath/Table + Furniture/Decor):

數據顯示,這兩個品類的共現次數遠超其他所有組合。買家在佈置新家或翻新房間時,極具「空間一體化採購」的傾向。

落地戰術: 在寢具商品頁面新增「常搭配購買(Frequently Bought Together)」模組,或推出「臥室軟裝套裝包」,提供 5% 組合折價。

2.結帳頁面的加價購(Cart Abandonment & BOGO):

針對單件購買率高達 89% 的現況,在買家進入購物車但尚未付款的最後一哩路,依據購物車內的商品品類,動態推播低客單、高共現率的小物(如裝飾品、清潔耗材),並設定「滿 120 BRL 即可免運」的湊單門檻,刺激買家順手多帶一件。

3.打破平台品類孤島:

避免推薦毫不相干的隨機商品(例如買家具推薦汽車零配件),將演算法算出的關聯矩陣直接注入站內推薦系統的規則庫,用冷啟動規則大幅提升點擊轉換率(CTR)。


今天我們攻克了提升單次購買價值的核心武器:

  • 摸清購物籃結構: 發現 89% 單件購買的局限,明確以提升「客單價與連帶率」作為突破口。

  • 掌握共現特徵工程: 善用 itertools.combinations 拆解無序配對,建立高效的關聯統計流程。

  • 產出搭售策略矩陣: 定位出全平台以「居家軟裝」為首的黃金搭售組合,為前端產品推薦與行銷促銷提供精準打擊方向。

至此,我們已經從總體營收、地理落差、運費負擔、物流跳票、賣家履約、支付金流、RFM 分群、留存隊列,
一路分析到了購物籃搭售。
但在電商物流的背後,還有一個決定性的物理維度我們尚未精密計算——地理空間距離。

明天 Day 21,我們將跨入空間資料分析—— 地理空間進階計算:利用經緯度 (Geolocation) 計算買賣雙方直線距離與物流阻礙!


上一篇
[Day 19] 揭開電商回購的殘酷真相:繪製留存熱力圖揪出 Olist 的「回購斷崖」
系列文
拯救混亂數據:30 天 Python 輕量級 ETL 與電商關聯資料分析 共 20 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言