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