戰(zhàn):從RFM特征到K-Means分群運(yùn)營策略)
先說個真實(shí)需求場景。我去年接到過一份商場會員分析任務(wù)數(shù)據(jù)非常規(guī)整幾十萬條消費(fèi)記錄字段也就是會員ID、消費(fèi)時間、金額這些看起來不復(fù)雜。可運(yùn)營同事拿著會員列表完全不知道下一步該怎么辦——全場折扣高價值客戶覺得沒誠意只做滿減價格敏感客戶薅完羊毛就走。后來我們把這套需求真正做成了“商場客戶聚類”用無監(jiān)督學(xué)習(xí)把顧客按行為切成幾類運(yùn)營才有了可以落地的抓手。這篇文章把完整鏈路拆開講一遍從數(shù)據(jù)準(zhǔn)備、特征構(gòu)造、K-Means建模、K值選擇到聚類結(jié)果的業(yè)務(wù)解讀、運(yùn)營動作和效果評估再把實(shí)操中容易踩的坑單獨(dú)拉出來說。適合剛接觸客戶分群的數(shù)據(jù)分析同學(xué)也適合想了解聚類算法到底能幫業(yè)務(wù)做什么的運(yùn)營朋友。內(nèi)容都來自實(shí)際項(xiàng)目經(jīng)驗(yàn)代碼和參數(shù)可以直接拿去用但更重要的是理解每一步背后的取舍。1. 為什么商場客戶聚類會出現(xiàn)在業(yè)務(wù)需求里一刀切運(yùn)營的盡頭是分群1.1 傳統(tǒng)會員運(yùn)營的痛點(diǎn)商場和電商有個很大的區(qū)別線下消費(fèi)行為高度分散而且?guī)в忻黠@的隨機(jī)性。你打開一個商場的會員明細(xì)會發(fā)現(xiàn)顧客結(jié)構(gòu)遠(yuǎn)比想象中復(fù)雜。有人每月來四次每次順路買杯咖啡加一盒水果有人半年不來一次一來就在化妝品專柜花掉四五千還有人專門等大促節(jié)點(diǎn)不折扣不動手。這些顧客如果共用一套運(yùn)營策略結(jié)果通常是高價值客戶覺得被打擾價格敏感客戶養(yǎng)成了“非折扣不買”的習(xí)慣中間層的潛在客戶又得不到足夠的吸引力。我們當(dāng)時拉過一組數(shù)據(jù)統(tǒng)一發(fā)放的滿200減50優(yōu)惠券核銷率最高的客戶群恰好也是客單價最低的那批。營銷費(fèi)用花下去了ROI卻參差不齊。這種狀態(tài)下任何精細(xì)化運(yùn)營都無從談起。因?yàn)槟慵炔恢缿?yīng)該優(yōu)先服務(wù)誰也不知道每一類顧客真正在意什么。傳統(tǒng)的做法是拍幾個閾值比如“年消費(fèi)超過5000元算高價值客戶”“一年到店少于3次算沉睡客戶”然后按規(guī)則打標(biāo)簽。這種人工分箱方法的問題在于閾值是你定的不是數(shù)據(jù)告訴你的維度一多規(guī)則之間還會互相打臉。1.2 聚類在客戶分群中的定位聚類屬于無監(jiān)督學(xué)習(xí)和分類最大的區(qū)別是它不需要預(yù)先定義任何標(biāo)簽。你只需要準(zhǔn)備好顧客的行為特征讓算法自己去發(fā)現(xiàn)“哪些人扎堆、哪些人離群”。聚類結(jié)果追求的是組內(nèi)相似度高、組間差異大至于每個組叫什么名字、意味著什么那是建模之后由人來解讀的。放在商場場景里聚類最大的價值在于它能同時處理多個維度的組合。RFM三件套里的“最近消費(fèi)時間R、消費(fèi)頻率F、消費(fèi)金額M”如果只靠人工分箱你可能只分得出來“高價值/低價值”這樣的粗粒度結(jié)果。但聚類的搜索空間是連續(xù)的它可以發(fā)現(xiàn)“雖然頻率很高但客單價極低、對折扣極度敏感”的群體也可以發(fā)現(xiàn)“頻率不高但單次消費(fèi)金額特別高、從來不領(lǐng)券”的另類群體這些用幾套死規(guī)則根本描述不出來。1.3 項(xiàng)目需求和最終交付物在動手之前我先和運(yùn)營對齊了項(xiàng)目目標(biāo)。商場客戶聚類這個項(xiàng)目最終要交付四樣?xùn)|西第一清晰的客戶群劃分第二每個客戶群的命名和畫像描述第三針對不同客戶群的運(yùn)營建議第四一套可以每月重復(fù)運(yùn)行的腳本或流程。其中第四點(diǎn)特別關(guān)鍵客戶聚類不能做成一次性項(xiàng)目客戶行為每個季度都在變模型必須能低成本重跑。這里我要多說一句聚類本身只是中間產(chǎn)物它不直接產(chǎn)生業(yè)績。業(yè)績來自聚類結(jié)果被業(yè)務(wù)用起來之后的那一系列動作。所以從第一天起就要拉著運(yùn)營一起看特征定義、看聚類輸出而不是等全部建完模再丟給人家一張簇ID表。2. 數(shù)據(jù)準(zhǔn)備從會員交易流水到干凈的RFM特征表2.1 需要的表和核心字段商場客戶聚類需要的數(shù)據(jù)源一般來自會員系統(tǒng)和交易系統(tǒng)。最常用的表是會員檔案表和交易流水表。會員檔案表提供客戶ID、注冊時間、性別、生日等靜態(tài)屬性交易流水表提供每一筆訂單的消費(fèi)時間、金額、品類、門店、是否使用優(yōu)惠券等動態(tài)行為信息。還有一張營銷觸達(dá)表記錄客戶收到過哪些券、核銷了哪些券這類數(shù)據(jù)在刻畫價格敏感度時非常有用。核心字段其實(shí)沒那么多customer_id、order_date、amount加一個可選的coupon_flag和category_id就夠了。很多同學(xué)一上來就把所有字段都塞進(jìn)模型結(jié)果特征空間被性別、年齡段、偏好品類這些變量撐得很大K-Means在這種高維稀疏空間里效果非常差。我建議先把RFM三個核心維度做扎實(shí)再帶著明確的目的加擴(kuò)展特征。2.2 時間口徑與清洗邏輯時間窗口的選取是第一個容易出錯的地方。如果是做年度經(jīng)營規(guī)劃建議取過去12個月的數(shù)據(jù)如果關(guān)注的是客戶全生命周期行為可以用全部歷史數(shù)據(jù)。但無論選哪個必須固定一個分析截止日期cutoff date不能直接取系統(tǒng)當(dāng)前日期。因?yàn)楫?dāng)前日期每天都在變今天跑的R值和下周跑的R值完全不一樣后續(xù)月度重跑時口徑會亂掉。數(shù)據(jù)清洗有幾個隱藏陷阱需要重點(diǎn)處理。第一退款記錄不能直接當(dāng)作負(fù)金額參與匯總否則客戶的累計消費(fèi)金額M會被嚴(yán)重扭曲甚至出現(xiàn)負(fù)數(shù)。我當(dāng)時的做法是把退款訂單單獨(dú)拎出來只統(tǒng)計凈消費(fèi)如果平臺本身有凈支付字段直接用那個字段最省事。第二明顯測試訂單要剔除比如商品名包含“測試”字樣、單筆金額異常低0.01元或異常高超出正常區(qū)間的記錄。第三同一客戶同一天在同一門店的多筆訂單要按“日-客戶-門店”維度去重合并成一次到店消費(fèi)。否則客戶只是分了幾單付款頻率F就會虛高聚類結(jié)果被噪音干擾。2.3 從訂單表到RFM特征表的代碼清洗完數(shù)據(jù)后就可以構(gòu)造最基礎(chǔ)的RFM特征了。下面這段代碼是項(xiàng)目的核心起點(diǎn)import pandas as pd from datetime import timedelta df pd.read_csv(orders.csv) df[order_date] pd.to_datetime(df[order_date]) # 固定分析截止日最大訂單日期 1天 cutoff df[order_date].max() timedelta(days1) rfm df.groupby(customer_id).agg( recency(order_date, lambda d: (cutoff - d.max()).days), frequency(order_date, count), monetary(amount, sum) ).reset_index() print(rfm.head())這段代碼里最值得注意的就是recency的計算方式它用的是固定截止日和該客戶最后一次消費(fèi)日期的差單位是天。這個值越小說明客戶最近剛來過活躍度越高。frequency用訂單記錄數(shù)做統(tǒng)計因?yàn)槲覀円呀?jīng)在清洗階段把同日重復(fù)訂單合并了所以這里的count數(shù)可以近似代表到店消費(fèi)次數(shù)。monetary直接求和代表統(tǒng)計周期內(nèi)的累計消費(fèi)金額。到這里一張最干凈的RFM特征表就出來了。3. 特征工程RFM之外還需要哪些消費(fèi)行為變量3.1 RFM三件套的標(biāo)準(zhǔn)定義與計算細(xì)節(jié)RFM是客戶分群里最經(jīng)典的特征組合但在商場場景下有幾個細(xì)節(jié)需要較真。R值有一個容易被忽略的問題如果客戶統(tǒng)計周期內(nèi)沒有消費(fèi)R值會非常大。比如用過去12個月做窗口完全沒消費(fèi)的客戶R值就是365。這部分“注冊但無消費(fèi)”的客戶我建議單獨(dú)分出來不放進(jìn)K-Means。因?yàn)樗麄兊男袨樘卣魇羌兞闾畛鋾丫垲愔行睦蛞粋€不真實(shí)的位置。先把活躍客戶跑聚類再把沉睡客戶用規(guī)則兜底是更穩(wěn)妥的操作。F值這里有個“訂單數(shù)”和“到店次數(shù)”的選擇。商場消費(fèi)和電商不同顧客可能在一個門店買完衣服又去另一個門店買奶茶形成同一天多筆訂單。如果按原始訂單數(shù)統(tǒng)計一個人一天產(chǎn)生4筆訂單就會被當(dāng)成4次到店這顯然不符合直覺。我在項(xiàng)目里測試過兩種口徑的差異結(jié)論是按“日-客戶-門店”去重后的到店次數(shù)聚類結(jié)果在業(yè)務(wù)解釋性上明顯更好。M值建議使用實(shí)際支付金額也就是扣掉優(yōu)惠券抵扣后的金額。因?yàn)檫@個數(shù)字衡量的是客戶真實(shí)貢獻(xiàn)的現(xiàn)金流而不是商品的吊牌價。3.2 擴(kuò)展特征客單價、品類集中度、優(yōu)惠券敏感度RFM只能回答“最近來沒來、來得多不多、花了多少錢”但回答不了“為什么來、買什么、看重什么”。所以要在基礎(chǔ)特征之上挑幾個擴(kuò)展變量。我常用的是這三個第一平均客單價也就是M除以F。這個指標(biāo)可以區(qū)分“買得多”和“買得貴”兩種完全不同的人。有人一年來20次但每次只花30元買飲品有人一年來4次但每次花3000元買服飾。兩者的商業(yè)價值天差地別但RFM原始特征里可能體現(xiàn)不出來。第二品類集中度。用客戶購買Top品類消費(fèi)金額占總消費(fèi)金額的比例表示。比例接近1的客戶是目的性消費(fèi)比如專門沖某個品牌或品類來比例分散的客戶屬于逛購型更容易受活動和陳列影響。這兩類人的營銷方式完全不同前者要精確推送品牌信息后者適合用全場性活動引導(dǎo)。第三優(yōu)惠券使用率。這個特征在商場場景里特別重要它直接刻畫了客戶的價格敏感度。計算方式很簡單使用優(yōu)惠券的訂單數(shù)除以總訂單數(shù)。有些客戶領(lǐng)券率很高但核銷率很低說明優(yōu)惠門檻不一定合適這也是可以用的信息。3.3 為什么聚類前必須做標(biāo)準(zhǔn)化K-Means是基于歐氏距離的算法它對特征的量綱極度敏感。假設(shè)R值是0到365之間的數(shù)字F值是1到50M值可能是50到200000。如果不做任何處理M這一列在距離計算中會形成絕對支配地位——其他特征全變成噪聲聚類結(jié)果幾乎等價于“按消費(fèi)金額排隊劃分”。解決辦法是標(biāo)準(zhǔn)化。我用的是StandardScaler但在有極端大客戶的情況下建議先對M做對數(shù)壓縮再用StandardScalerimport numpy as np from sklearn.preprocessing import StandardScaler features rfm[[recency, frequency, monetary]].copy() features[log_monetary] np.log1p(features[monetary]) # 出于演示這里舍棄原始的monetary使用對數(shù)變換后的版本 X features[[recency, frequency, log_monetary]].values scaler StandardScaler() X_scaled scaler.fit_transform(X)這里要特別提醒一個順序問題標(biāo)準(zhǔn)化必須在聚類之前做。我們項(xiàng)目里有個新人曾經(jīng)先把數(shù)據(jù)喂給KMeans聚類完再標(biāo)準(zhǔn)化結(jié)果自然是一團(tuán)亂。因?yàn)镵-Means迭代時用的已經(jīng)是未縮放的距離了后補(bǔ)的標(biāo)準(zhǔn)化根本不會改變原來的聚類結(jié)果。4. K-Means選型與K值確定算法參數(shù)背后的權(quán)衡4.1 為什么是K-Means而不是DBSCAN做客戶聚類的算法不止K-Means一種但絕大多數(shù)場景里K-Means是最合理的第一選擇。它的優(yōu)點(diǎn)是計算快、可解釋性強(qiáng)、實(shí)現(xiàn)成本低幾十萬條樣本配合五六個特征運(yùn)行時間以秒計。和DBSCAN比K-Means雖然需要預(yù)先指定簇數(shù)K但也因此換來了更穩(wěn)定的結(jié)果和層次聚類比K-Means的復(fù)雜度低得多能夠輕松應(yīng)付全量客戶數(shù)據(jù)。我整理了一個簡單的選型對照表算法適用場景優(yōu)點(diǎn)缺點(diǎn)K-Means凸形簇、數(shù)據(jù)量大、維度不高速度快、可解釋、易規(guī)?;柚付↘、對離群值敏感DBSCAN任意形狀簇、需識別離群點(diǎn)不需要K、能自動識別噪聲密度差異大時不穩(wěn)、參數(shù)難調(diào)層次聚類小樣本、需要樹狀結(jié)構(gòu)樹狀圖直觀、無需預(yù)設(shè)K計算復(fù)雜度高、不適合幾十萬條數(shù)據(jù)GMM高斯混合橢球形分布、需要“屬于各簇概率”軟聚類、更靈活參數(shù)多、計算量大、易過擬合商場客戶的行為特征通常不是特別復(fù)雜的不規(guī)則形狀用K-Means已經(jīng)能得到可讀的群體劃分。如果你的目標(biāo)是想知道“這個客戶70%屬于高價值群、30%屬于價格敏感群”那可以考慮GMM它會輸出隸屬概率。但對絕大多數(shù)運(yùn)營場景來說一個硬標(biāo)簽已經(jīng)夠用了。4.2 K-Means超參數(shù)背后需要注意什么K-Means看似參數(shù)很少但有兩個參數(shù)直接影響結(jié)果質(zhì)量不能不重視random_state和n_init。random_state控制隨機(jī)數(shù)種子。K-Means的初始中心點(diǎn)是隨機(jī)選擇的換個種子最終聚類結(jié)果可能就變了。為了保證項(xiàng)目可復(fù)現(xiàn)、同事之間能對齊結(jié)果必須固定它我一般用42。n_init表示算法會用多少個不同初始中心去跑最后返回其中SSE簇內(nèi)平方和最小的結(jié)果。舊版sklearn里默認(rèn)值是10但新版本里這個參數(shù)改成了auto你如果不顯式指定的話實(shí)際運(yùn)行次數(shù)可能不夠穩(wěn)定。建議顯式設(shè)成n_init10避免在不同機(jī)器上跑出差異很大的結(jié)果。還有一個容易被忽略的是max_iter。默認(rèn)300已經(jīng)足夠但如果特征維度多、樣本量大迭代次數(shù)不夠可能導(dǎo)致模型未收斂。訓(xùn)練完看一眼km.n_iter_如果它已經(jīng)達(dá)到max_iter說明需要調(diào)大迭代上限。4.3 K值確定肘部法則、輪廓系數(shù)與業(yè)務(wù)對齊確定K值是K-Means流程里最核心的一步我習(xí)慣用三件套交叉驗(yàn)證。第一件套是肘部法則。畫出K從2到10的SSE下降曲線找曲率變化最大的點(diǎn)import matplotlib.pyplot as plt from sklearn.cluster import KMeans sse [] for k in range(2, 11): km KMeans(n_clustersk, n_init10, random_state42) km.fit(X_scaled) sse.append(km.inertia_) plt.plot(range(2, 11), sse, markero) plt.xlabel(k) plt.ylabel(SSE) plt.title(Elbow Method) plt.show()需要提醒的是商場客戶數(shù)據(jù)的肘部往往不會特別明顯。SSE下降曲線通常是一條平滑遞減的弧線“拐點(diǎn)”靠肉眼判斷經(jīng)常有爭議。所以肘部法則只能作為參考區(qū)間不能當(dāng)成唯一依據(jù)。第二件套是輪廓系數(shù)。輪廓系數(shù)衡量每個樣本與自己簇內(nèi)樣本的緊密度和對其他簇的分離度取值范圍從-1到1越大越好from sklearn.metrics import silhouette_score for k in range(2, 7): km KMeans(n_clustersk, n_init10, random_state42).fit(X_scaled) score silhouette_score(X_scaled, km.labels_) print(fk{k}, silhouette_score{score:.4f})輪廓系數(shù)高說明簇內(nèi)緊湊、簇間分離。但注意輪廓系數(shù)高不等于業(yè)務(wù)可解釋。有些K值在數(shù)學(xué)上漂亮分出來的簇卻沒法命名、沒法對應(yīng)運(yùn)營動作這時候還是要回到業(yè)務(wù)判斷。第三件套是業(yè)務(wù)對齊也是最終決策依據(jù)。把每個K值對應(yīng)的簇中心結(jié)果打印出來和運(yùn)營同事一起看分出來的每個群體能不能用一句話說清楚每一簇的占比是否合理有沒有占比低于3%的碎簇我當(dāng)時最終選擇K4是因?yàn)镵4時每個簇的人數(shù)占比在19%到33%之間特征均值差異明顯運(yùn)營能直接給每一類客戶起名字、想策略。K5時多出一個占比只有2.7%的怪簇顯然沒有實(shí)際意義。5. 聚類結(jié)果怎么解讀簇ID如何變成客戶標(biāo)簽和畫像5.1 簇中心就是畫像的錨點(diǎn)K-Means訓(xùn)練完成后每個客戶會得到一個cluster_id真正難的是把這個數(shù)字翻譯成業(yè)務(wù)語言。我的突破口是cluster centers也就是簇在特征空間里的中心點(diǎn)。但有個關(guān)鍵細(xì)節(jié)模型里存的是標(biāo)準(zhǔn)化后的中心坐標(biāo)必須用scaler.inverse_transform()還原成原始量綱才能解讀。centers km.cluster_centers_ original_centers scaler.inverse_transform(centers) for i, center in enumerate(original_centers): print(fCluster {i}: R{center[0]:.1f}天, F{center[1]:.1f}次, M{np.expm1(center[2]):.1f}元)除了簇中心我還建議看每個簇各特征的中位數(shù)而不是只依賴均值。因?yàn)橄M(fèi)金額往往右偏個別大客戶會把均值拉高中位數(shù)更能代表群體的一般水平。5.2 一個四簇結(jié)果的示例解讀為了更直觀我拿當(dāng)時項(xiàng)目里一版四簇結(jié)果做示例數(shù)據(jù)已做脫敏變形處理但結(jié)構(gòu)是真實(shí)的簇人數(shù)占比平均R天平均F次/年平均M元/年初步命名024%9141280高頻穩(wěn)定客119%2162200中頻高額客233%353460低頻價格敏感客324%1121.4210沉睡流失客這個表格一放出來運(yùn)營同事瞬間就理解了。高頻穩(wěn)定客是商場的“基本盤”來的次數(shù)多總消費(fèi)中等適合維護(hù)忠誠度中頻高額客雖然來得不頻繁但單次消費(fèi)高是最值得用高價值權(quán)益去激活的一批人低頻價格敏感客人數(shù)最多來的少且花得少但對折扣反應(yīng)明顯沉睡流失客基本處于流失邊緣需要決定是召回還是放棄。再結(jié)合擴(kuò)展特征之后畫像會更立體。比如低頻價格敏感客里很大比例是沖著超市和餐飲折扣來的幾乎不逛服飾中頻高額客則集中在美妝和精品零售對停車權(quán)益比價格折扣更敏感。這些信息讓后續(xù)運(yùn)營策略有據(jù)可依。5.3 可視化PCA降維散點(diǎn)圖與雷達(dá)圖聚類結(jié)果交付業(yè)務(wù)方時圖表比表格更能說明問題。最常用的可視化手段是PCA降維散點(diǎn)圖。把標(biāo)準(zhǔn)化后的特征降到二維給每個客戶的點(diǎn)按簇著色一眼就能看到各類客戶在空間上的分離程度from sklearn.decomposition import PCA pca PCA(n_components2, random_state42) coords pca.fit_transform(X_scaled) plt.figure(figsize(8, 6)) scatter plt.scatter(coords[:, 0], coords[:, 1], ckm.labels_, cmapSet2, s5, alpha0.6) plt.colorbar(scatter) plt.xlabel(PC1) plt.ylabel(PC2) plt.title(Customer Clusters Visualization) plt.show()這里有個非常重要的提醒PCA降維后的散點(diǎn)圖只能用于查看簇的分離程度不能把PC1、PC2直接解讀成業(yè)務(wù)維度。它們只是用來保留最大方差的兩個數(shù)學(xué)方向投射到二維平面后距離關(guān)系會被壓縮甚至扭曲。不少新人拿著PCA圖去跟運(yùn)營講“PC1軸代表消費(fèi)力”這是完全錯誤的。如果要展示各簇在具體業(yè)務(wù)維度上的差異雷達(dá)圖比PCA圖更合適??梢园磮F(tuán)隊習(xí)慣用Python的matplotlib或直接導(dǎo)數(shù)據(jù)到Excel里畫每條軸線代表一個業(yè)務(wù)指標(biāo)最近消費(fèi)間隔、消費(fèi)頻率、客單價、品類集中度、優(yōu)惠券使用率把每個簇相對總體均值的位置連成多邊形。這樣運(yùn)營一眼就能看出哪個簇“價格敏感”哪個簇“消費(fèi)力強(qiáng)”哪個簇“逛購型為主”。6. 分群后的運(yùn)營打法每一類客戶對應(yīng)的差異化動作6.1 四類客戶的策略對照表聚類的最終價值必須落到運(yùn)營動作上。不同類型客戶的維護(hù)目標(biāo)和觸達(dá)策略完全不同我整理了一個可以直接參照的策略表客戶群核心目標(biāo)運(yùn)營動作建議觸達(dá)節(jié)奏高頻穩(wěn)定客維持忠誠度、提升客單價專屬會員價、積分加速、新品優(yōu)先購、專屬停車權(quán)益私域每周一次控制打擾強(qiáng)度中頻高額客提升到店頻次高價值品類定向券、生日禮、專屬導(dǎo)購預(yù)約短信App每兩周一次低頻價格敏感客提升頻次和客單滿減券、大促預(yù)熱提醒、積分抵現(xiàn)、打包套餐短信公眾號每月一次沉睡流失客召回或低成本放棄召回禮包、限時權(quán)益、跨品類推薦短信低頻觸達(dá)季度一次具體到我的項(xiàng)目里最明顯的效果來自中頻高額客。這群人消費(fèi)能力強(qiáng)、客單價高但到店頻率只有每年6次左右。運(yùn)營原來只給他們發(fā)全場通用的滿200減30券他們根本無感。后來換成本項(xiàng)目里沉淀的“停車權(quán)益高價值品牌定向券”組合兩個月內(nèi)這批客戶的到店頻次提升了明顯的一截。核心邏輯很樸素這群人缺的不是優(yōu)惠是來商場的理由。6.2 商場場景的落地動作細(xì)節(jié)商場和電商有一個很大的不同商場運(yùn)營能調(diào)動的杠桿不只是券還有場地、樓層、業(yè)態(tài)和現(xiàn)場體驗(yàn)。聚類結(jié)果可以在好幾個層面落地。具體到樓層導(dǎo)購可以按簇畫像重新設(shè)計引導(dǎo)動線。中頻高額客應(yīng)該被引導(dǎo)到美妝、精品零售所在的樓層高頻穩(wěn)定客的活動動線通常在超市、餐飲之間可以順路設(shè)計一些中間層的促銷點(diǎn)位。會員日活動也可以分群排期。低頻價格敏感客對折扣反饋熱烈把他們安排到大促預(yù)熱期的爆發(fā)節(jié)點(diǎn)高頻穩(wěn)定客反而需要避開極端擁擠時段設(shè)置“會員專屬安靜時段”提供更舒適的消費(fèi)體驗(yàn)??头捫g(shù)也能分群。沉睡客戶觸達(dá)時避免用“歡迎回歸”這類通用文案而是根據(jù)畫像直接說“您常用的品牌上新了”或者“您消費(fèi)最高的品類正在做會員專屬活動”召回效果差別很大。6.3 效果評估AB測試和指標(biāo)體系聚類做完不等于項(xiàng)目結(jié)束還要設(shè)計一套效果評估體系。我建議在每個客戶群內(nèi)部做AB測試同一客群里的用戶隨機(jī)分成實(shí)驗(yàn)組和對照組實(shí)驗(yàn)組接收個性化策略對照組沿用原來的統(tǒng)一營銷觀察6到8周的差異。核心指標(biāo)建議盯四個復(fù)購率、月活躍消費(fèi)率、客單價、季度LTV。領(lǐng)取和核銷率只能是過程指標(biāo)它不代表真實(shí)業(yè)績提升。統(tǒng)計上樣本量夠大時直接用獨(dú)立雙樣本檢驗(yàn)或回歸模型控制混淆變量。有一點(diǎn)必須強(qiáng)調(diào)不要用簡單的“活動前后對比”來證明策略有效因?yàn)楣?jié)假日、天氣、換季都會影響商場客流你很難把增量單獨(dú)歸因到運(yùn)營策略上。7. 實(shí)戰(zhàn)中我踩過的坑與兩個可進(jìn)階的方向7.1 數(shù)據(jù)泄漏客戶聚類里最隱蔽的坑先講數(shù)據(jù)泄漏。我們第一版特征工程犯過一個很低級的錯誤客戶最近消費(fèi)時間R值用的是“今天”減最后消費(fèi)日而不是“固定截止日”減最終消費(fèi)日。結(jié)果每天重跑同一份數(shù)據(jù)聚類結(jié)果都在變后來才意識到是日期口徑的問題。但更隱蔽的是另一種泄漏構(gòu)造擴(kuò)展特征時用全量數(shù)據(jù)的中位數(shù)去填充缺失值。這樣做會導(dǎo)致新樣本被歷史數(shù)據(jù)“污染”后續(xù)每個月重新聚類時新舊數(shù)據(jù)的口徑不一致結(jié)果不可比。正確的做法是先確定分析截止日所有特征都只用截止日之前的數(shù)據(jù)標(biāo)準(zhǔn)化時先記錄當(dāng)前批次的scaler參數(shù)后續(xù)新數(shù)據(jù)重跑時沿用這套參數(shù)而不是重新fit。這樣每個月生產(chǎn)出來的特征才具有可比性。7.2 離群值、隨機(jī)種子與冷啟動K-Means對離群值非常敏感。商場里總有極少數(shù)年消費(fèi)幾十萬的大客戶他們單獨(dú)形成一個簇后雖然簇中心看起來“價值高”但人數(shù)太少談不上運(yùn)營策略。我的處理方式是把客戶按累計消費(fèi)金額排序Top 1%單獨(dú)拿出來不參與K-Means聚類而是另一套人工規(guī)則分析。剩下的中間層客戶再用聚類切分結(jié)果穩(wěn)定得多。冷啟動是另一個容易頭疼的問題。新注冊客戶沒有足夠的歷史行為數(shù)據(jù)用訓(xùn)練好的KMeans直接predict會把他分進(jìn)某一個已有的簇但這個分群實(shí)際上毫無依據(jù)。我們的做法是設(shè)定一個簡單門檻frequency 1且monetary低于閾值的客戶直接標(biāo)記為“新客待觀察”不進(jìn)模型預(yù)測。等他們產(chǎn)生2到3次消費(fèi)行為后再納入下次聚類。關(guān)于隨機(jī)種子我再強(qiáng)調(diào)一次必須固定random_state并且要在項(xiàng)目文檔里記錄使用的庫版本。換一個環(huán)境、換一版sklearn同樣的代碼也可能產(chǎn)生不同結(jié)果。另外不同月份的聚類結(jié)果中同一個簇ID的客戶群體含義可能完全不同。千萬不要偷懶以為下標(biāo)0永遠(yuǎn)是“高頻客”每個月重跑后都重新檢查簇中心并重建畫像。7.3 進(jìn)階方向Mini-Batch K-Means、GMM與可解釋規(guī)則如果數(shù)據(jù)量繼續(xù)膨脹到百萬級常規(guī)KMeans可能吃緊可以考慮Mini-Batch K-Means。它在每次迭代時只隨機(jī)采樣一小批樣本更新中心計算速度和內(nèi)存占用都會好很多聚類精度損失在可接受范圍內(nèi)。如果業(yè)務(wù)想獲得軟標(biāo)簽也就是每個客戶屬于每個簇的概率而不是硬性的簇ID可以用高斯混合模型GMM。它允許簇與簇之間存在重疊適合那些行為特征介于兩個群體之間的客戶。還有一個對業(yè)務(wù)落地特別有用的方向可解釋聚類。聚類結(jié)果是黑盒標(biāo)簽但可以在聚類完成后以cluster_id為目標(biāo)訓(xùn)練一棵簡單的決策樹用樹模型提取“R小于15天且F大于10次則為高頻穩(wěn)定客”這類顯式規(guī)則。這樣運(yùn)營系統(tǒng)不需要每次都調(diào)聚類模型用幾條規(guī)則就能在CRM里實(shí)時打標(biāo)簽。最后說一點(diǎn)個人體會。做這類項(xiàng)目K-Means本身只占三成工作量其余七成精力幾乎都消耗在數(shù)據(jù)口徑、特征定義和業(yè)務(wù)對齊上。每次組織重跑聚類之前先問清楚業(yè)務(wù)當(dāng)前最想解決什么問題——是提升客單價、喚醒沉睡客戶還是調(diào)整品類結(jié)構(gòu)。目標(biāo)不一樣特征選擇和數(shù)據(jù)窗口都會完全不同。先和運(yùn)營把“想解決什么問題”聊透再安排建模的工作這個順序千萬不要反。