“
推薦系統將成為未來十年里最重要的變革
社會化網站將由推薦系統所驅動
--- John Riedl明尼蘇達大學教授
01
前言
智能推薦和泛的營銷完全不同,后者是將產品賣給客戶作為最終目標;而智能推薦是以“客戶需求”為導向的,是給客戶帶來價值的。常見的如淘寶的 “你可能還喜歡”,亞馬遜的 “購買此商品的用戶也購買了” 便是實例。本文就將詳細介紹如何用Python實現智能推薦算法,主要將分為兩個部分:
詳細原理介紹
Python代碼實戰
02
常見的推薦系統與算法
常見的推薦系統分類有:
基於應用領域: 電子商務/社交好友推薦等
基於設計思想: 基於協同過濾的推薦等
基於使用數據: 基於用戶標簽的推薦等
“ 京騰 ” 合作構建用戶畫像標簽圖
常見的推薦算法有:
本文將專注於理解起來最容易且又十分經典常用的基於關聯規則的購物籃推薦。商品的關聯度分析對於提高商品的活力、挖掘消費者的購買力、促進最大化銷售有很大幫助。其建模理念為:物品被同時購買的模式反映了客戶的需求模式,適用場景:無需個性化定制的場景;有銷售記錄的產品,向老客戶推薦;套餐設計與產品擺放。
03
購物籃簡介
問:什么是購物籃?主要運用在什么場景?
答:單個客戶一次購買商品的綜合稱為一個購物籃,即某個客戶本次的消費小票。常用場景:超市貨架布局:互補品與互斥品;套餐設計。
問:購物籃的常用算法?
答:常用算法有
不考慮購物順序:關聯規則。購物籃分析其實就是一個因果分析。關聯規則其實是一個很方便的發現兩樣商品關系的算法。共同提升的關系表示兩者是正相關,可以作為互補品,如豆瓣醬和蔥一起賣也才是最棒的。替代品的概念便是我買了這個就不用買另外一個。
考慮購物順序:序貫模型。多在電商中使用,比如今天你將這個商品加入了購物車,過幾天又將另一個商品加入了購物車,這就有了一個前后順序。但許多實體商店因為沒有實名認證,所以無法記錄用戶的消費順序。
問:求出互補品與互斥品后對布局有什么用?
答:根據關聯規則求出的商品間的關聯關系后,可能會發現商品間存在強關聯,弱關聯與排斥三種關系。每種清醒有各自對應的布局方式。
強關聯:關聯度的值需要視實際情況而定,在不同的行業不同的也業態是不同的。強關聯的商品彼此陳列在一起會提高雙方的銷售量。雙向關聯的商品如果陳列位置允許的話應該相關聯陳列,即A產品旁邊有B,B產品邊上也一定會有A,比如常見的剃須膏與剃須刀,男士發油與定型梳;而對於那些單向關聯的商品,只需要被關聯的商品陳列在關聯商品旁邊就行,如大瓶可樂旁邊擺紙杯,而紙杯旁邊則不擺大瓶可樂,畢竟買大可樂的消費者大概率需要紙杯,而購買紙杯的顧客再購買大可樂的概率不大。
弱關聯:關聯度不高的商品,可以嘗試擺在一起,然后再分析關聯度是否有變化,如果關聯度大幅提高,則說明原來的弱關聯有可能是陳列的原因造成的。
排斥關系:指兩個產品基本上不會出現在同一張購物小票中,這種商品盡量不要陳列在一起。
根據購物籃的信息來進行商品關聯度的分析不僅僅只有如上三種關系,它們僅代表商品關聯度分析的一個方面(可信度)。全面系統的商品關聯分析必須有三度的概念,三度包括支持度,可信度和提升度。
04
關聯規則
直接根據關聯三度所定義的概念去理解會有不少難度,尤其是可信度喝提升度中的“ 誰對誰 ”的問題。其實可以換一種方式來看:
規則 X 的支持度 = 規則 X 的交易次數 / 交易的總數。理解:支持度表示規則 X 是否普遍。
規則 X(A→B) 的置信度 = 規則 X 的交易次數/規則X中商品B 的交易次數。理解:置信度是一種條件概率,表示購買了A產品的客戶再購買B產品的概率。
為方便理解這些規則,我們通過下面五個購物籃的例子來練習一下
不難發現,支持度的分母都是5,也就是購物籃的數量,分子則是選取這個規則中的所有商品同時出現在一個籃子的次數。以A->D為例,同時包含A和D的籃子有2個,總的交易數量(籃子總數)有5個,所以規則A->D的支持度為2/5;有商品 A 的籃子個數為3,在這三個籃子中,其中2個籃子又包含商品D,所以該規則的置信度(可信度)為2/3。有關關聯規則,還有以下兩個問題想補充:
問:僅看支持度和置信度是否靠譜?
答:看一個案例:食堂賣飯,1000份打飯記錄中,買米飯的有800人次,買牛肉的有600人次,兩個共同買的有400人次,那么可以得出對於規則(牛肉 - > 米飯)Support=P(牛肉&米飯)= 400/1000=0.40;Confidence=P(米飯|牛肉)=400/600=0.67置信度和支持度都很高,但是給買牛肉的人推薦米飯有意義嗎?顯然是沒有任何意義的。因為無任何條件下用戶購買米飯的概率:P(米飯)=800/1000=0.8,都已經大過買了牛肉的前提下再買米飯的概率 0.67,畢竟米飯本來就比牛肉要暢銷啊。
這個案例便引出了提升度的概念:提升度 = 置信度/無條件概率=0.67/0.8。規則 X(A→B) 的提升度為 n 時:向購買了 A 的客戶推薦 B 的話,這個客戶購買 B 的概率是 TA 自然而然購買 B 的 n × 100% 左右。生活理解:消費者平時較少單獨購買桌角防撞海綿,可能偶爾想到或自己小孩碰到的時候才會想起購買,如果我們在桌子(書桌飯桌)的成功下單頁面添加桌角防撞海綿的推薦,則很大程度上可以提高防撞海綿的銷量。這也符合我們希望通過暢銷商品帶動相對非暢銷商品的宗旨。
問:除了公式的含義,關聯三度(支持度,置信度,提升度)還有什么關聯嗎?
答:可以這樣理解:
支持度代表這組關聯商品的份額是否夠大
置信度(可信度)代表關聯度的強弱
而提升度則是看該關聯規則是否有利用價值和值得推廣,用了(客戶購買后推薦)比沒用(客戶自然而然的購買)要提高多少。
所以 1.0 是提升度的一個分界值,剛才的買飯案例中給買了牛肉的用戶推薦米飯的這種騷操作的提升度小於 1 也就不難理解了。另外,高置信度的兩個商品(假設達到了 100%,意味着它們總是成雙成對的出現),但如果支持度很低(意味着份額低),那它對整體銷售提升的幫助也不會大。
05
基於Apriori 算法的Python實戰
由於有關Apriori等算法的研究已經很成熟,我們在用Python實戰時無需一步一步計算,直接調用現有函數即可,主要是要明白背后的原理與不同算法的使用場景與優劣比較。
探索性分析
首先導入相關庫並進行數據探索性分析
import pandas as pd
import numpy as np
df = pd.read_csv('bike_data.csv', encoding='gbk')
df.info(); df.head()
數據參數解釋
OrderNumber:客戶昵稱
LineNumber:購買順序,如前三行分別表示同一個客戶購買的三樣商品的順序
Model:商品名
接着來看看商品的種類
print(f"數據集中共有{df['Model'].nunique()}種商品")
model_names = df['Model'].unique()
print("商品名分別為:")
# 5 個為一行顯示
for i in range(0, len(model_names), 5):
print(model_names[i:i+5])
再來看看最暢銷的 15 種商品
再進行一些簡單的可視化
top_15 = grouped.sort_values(by='count', ascending=False).head(15)
plt.figure(figsize=(8, 6))
sns.barplot(data=top_15, x='count', y='Model')
plt.grid(True)
使用 Apriori 算法求解關聯規則
首先生成購物籃,並將同一個客戶購買的所有商品放入同一個購物籃,需要提前使用pip install Apriori安裝,之后我們使用 Apriori 包中的 dataconvert 函數,下面是需要傳入的參數解釋
arulesdata:數據集 -- DataFrame
tidvar: “分類的索引”,即划分購物籃的標准,本案例是根據客戶 OrderNumber -- object類型
itemvar:將什么東西放進籃子里,本案例是將數據集中的商品,就是 Model 列放入籃子 -- object類型
data_type: 默認選擇 'inverted',庫中提供的不變
注意:需要注意傳入的參數類型,只要對了,直接套用就不是什么難事
import Apriori as apri
# 需要稍微等待一下
baskets = apri.dataconvert(arulesdata=df, tidvar='OrderNumber',
itemvar='Model', data_type='inverted')
# 返回的購物籃是一個大列表,大列表中的每一個小列表表示一個籃子
# 購物籃個數剛好等於數據集中的客戶數量
type(baskets), len(baskets) == df['OrderNumber'].nunique()
# (list, True)
現在查看前五個購物籃中的物品
現在生成關聯規則,根據排列組合,可知這些交易將會產生 21255×21254÷2 這么多個關聯規則。首先就要滿足支持度的要求,太小則直接被刪去,支持度的大小可根據關聯規則的多少調整 如果關聯規則很少,可根據實際情況放寬支持度的要求。相關參數說明:
+ minSupport:最小支持度閾值
+ minConf:最小置信度閾值
+ minlen:規則最小長度
+ maxlen:規則最大長度,一般2就夠了
這里,minSupport 或 minConf 設定越低,產生的規則越多,計算量也就越大
結果說明: 以 result 第一行為例
+ lhs: 被稱為左手規則,通俗理解即用戶購買的商品 - 山地車內胎
+ rhs: 被稱為右手規則,通俗理解即根據用戶購買某商品來推薦的另一件商品 - ll山地胎
+ support: 支持度,山地車內胎 和 ll山地胎 同時出現在一張購物小票中的概率
+ confidence: 置信度,購買了 山地車內胎 的前提下,同時購買 ll山地胎 的概率
+ lift:向購買了 山地車內胎 的客戶推薦 ll山地胎 的話,這個客戶購買 ll山地胎 的概率是這個客戶自然而然購買 ll山地胎 的 400% 左右,即高了300% 多!
現在我們篩選互補品和互斥品,代碼如下
# 互補品
# lift 提升度首先要大於1,然后再排序選擇自己希望深究的前 n 個
hubu = result[result['lift'] > 1].sort_values(by='lift',
ascending=False).head(20)
# 互斥品
huchi = result[result['lift'] < 1].sort_values(by='lift',
ascending=True).head(20)
hubu.head(5) # 結果也合情合理
對結果簡單分析一些,不要期望每個規則都有意義,要結合業務思考,比如競速型賽道自行車與運動水壺互斥實屬正常,競速講究輕量化,還配個水壺干什么... 比如山地車配一個競速公路車用的運動型頭盔...互斥產品則是成對出現的!
根據關聯規則結果推薦產品
需要結合業務需求
獲得最大營銷響應度?-- 看置信度,越高越好
銷售最大化?-- 看提升度,越高越好
用戶未產生消費,我們向其推薦商品?
# 注意數據類型,frozenset,需要拆一下
result['lhs'][1], type(result['lhs'][1])
# (frozenset({'山地車內胎'}), frozenset)
以獲得最高的營銷相應率為目標
如果一個新客戶剛剛下單了山地車英騎這個產品,如果希望獲得最高的營銷響應率,那在他付費成功頁面上最應該推薦什么產品?
目標:獲得最高的營銷響應率
以最大化總體銷售額為目標
如果一個新客戶剛下單了山地英騎這個產品,如果希望最大化提升總體的銷售額,那么在他付費成功的頁面上應該推薦什么產品?
目標:最大化銷售額
再次重申提升度通俗含義:提升度是相對於自然而然購買而言,A對B的提升度為4.0的理解如下:向購買了A的用戶推薦B,則該用戶購買B的概率是該用戶單獨(即自然而然的購買)購買B的概率的 400% 向購買了A的用戶推薦B,則該用戶購買B的概率比該用戶單獨(即自然而然的購買)購買B的概率高300%!
用戶並未產生消費,為其推薦某樣商品
最后總結一下,基於關聯規則的 Apriori 算法是智能推薦領域十分經典的應用之一,簡單易上手。其實推薦領域的難點不一定在於算法,而在於過大的客戶量與其產生的數據,所以一般到了最后用的都是混合推薦。至於更深層次的序貫模型與協同過濾,幾乎沒有人使用 Python 或 R 來實現,大部分都是使用分布式框架如 Spark,后續也會推出相關文章。
如果對本文使用的數據及源碼感興趣,可以關注如下公眾號回復 0827 下載。
點個“在看”支持一下????