談到用戶分類模型,,最被談及的應該就是RFM模型了。大部分人常把RFM模型掛在嘴邊,,而在實際使用中的卻很難真正的利用起來,。這里暫時不去討論RFM是好是壞。今天的介紹的是另外一個拓展的模型:航空公司客戶價值分析模型LRFCM RFM模型的復習 在客戶分類中,,RFM模型是一個經(jīng)典的分類模型,,模型利用通用交易環(huán)節(jié)中最核心的三個維度——最近消費(Recency)、消費頻率(Frequency),、消費金額(Monetary)細分客戶群體,,從而分析不同群體的客戶價值。在某些商業(yè)形態(tài)中,,客戶與企業(yè)產(chǎn)生連接的核心指標會因產(chǎn)品特性而改變,。如互聯(lián)網(wǎng)產(chǎn)品中,以上三項指標可以相應地變?yōu)橄聢D中的三項:最近一次登錄,、登錄頻率,、在線時長。 LRFCM模型簡介 我們說RFM模型由R(最近消費時間間隔),、F(消費頻次)和M(消費總額)三個指標構成,,通過該模型識別出高價值客戶。但該模型并不完全適合所有行業(yè),,如航空行業(yè),,直接使用M指標并不能反映客戶的真實價值,,因為“長途低等艙”可能沒有“短途高等艙”價值高??紤]到商用航空行業(yè)與一般商業(yè)形態(tài)的不同,,決定在RFM模型的基礎上,增加2個指標用于客戶分群與價值分析,,得到航空行業(yè)的LRFMC模型: L:客戶關系長度,。客戶加入會員的日期至觀測窗口結束日期的間隔,。(反映可能的活躍時長) R:最近一次乘機時間,。最近一次乘機日期至觀測窗口結束日期的間隔。(反映當前的活躍狀態(tài)) F:乘機頻率,??蛻粼谟^測窗口期內(nèi)乘坐飛機的次數(shù)。(反映客戶的忠誠度) M:飛行總里程,??蛻粼谟^測窗口期內(nèi)的飛行總里程。(反映客戶對乘機的依賴性) C:平均折扣率,。客戶在觀測窗口期內(nèi)的平均折扣率,。(艙位等級對應的折扣系數(shù),,側面反映客戶價值高低) LRFCM實戰(zhàn) 這里使用網(wǎng)上發(fā)布的一份數(shù)據(jù)做演示,數(shù)據(jù)地址: https://www./vinzzhang/aircompanycustomerinfo 字段說明: MEMBER_NO:會員卡號 FFP_DATE:入會日期(辦理會員卡的日期) FIRST_FLIGHT_DATE:第一次飛行日期 GENDER:性別 FFP_TIER:會員卡級別 WORK_CITY:工作地所在城市 WORK_PROVINCE:工作地所在身份 WORK_COUNTRY:工作地所在身份 AGE:年齡 LOAD_TIME:觀測窗口的結束時間(選取樣本的時間寬度,,距離現(xiàn)在最近的時間) FLIGHT_COUNT:觀測窗口內(nèi)的飛行次數(shù)(頻數(shù)) BP_SUM:觀測窗口總基本積分(航空公里的里程就相當于積分,,積累一定分數(shù)可以兌換獎品和免費里程) EP_SUM_YR_1:第一年精英資格積分 EP_SUM_YR_2:第二年精英資格積分 SUM_YR_1:第一年總票價 SUM_YR_2:第二年總票價 SEG_KM_SUM:觀測窗口總飛行公里數(shù) WEIGHTED_SEG_KM:觀測窗口總加權飛行公里數(shù)(Σ艙位折扣×航段距離) LAST_FLIGHT_DATE:最后一次飛行日期 AVG_FLIGHT_COUNT:觀測窗口季度平均飛行次數(shù) AVG_BP_SUM:觀測窗口季度平均基本積分累積 BEGIN_TO_FIRST:觀察窗口內(nèi)第一次乘機時間至MAX(觀察窗口始端,入會時間)時長 LAST_TO_END:最后一次乘機時間至觀察窗口末端時長 AVG_INTERVAL:平均乘機時間間隔 MAX_INTERVAL:觀察窗口內(nèi)最大乘機間隔 ADD_POINTS_SUM_YR_1:觀測窗口中第1年其他積分(合作伙伴,、促銷,、外航轉入等) ADD_POINTS_SUM_YR_2:觀測窗口中第2年其他積分(合作伙伴、促銷,、外航轉入等) EXCHANGE_COUNT:積分兌換次數(shù) avg_discount:平均折扣率 P1Y_Flight_Count:第1年乘機次數(shù) L1Y_Flight_Count:第2年乘機次數(shù) P1Y_BP_SUM:第1年里程積分 L1Y_BP_SUM:第2年里程積分 EP_SUM:觀測窗口總精英積分 ADD_Point_SUM:觀測窗口中其他積分(合作伙伴,、促銷、外航轉入等) Eli_Add_Point_Sum:非乘機積分總和 L1Y_ELi_Add_Points:第2年非乘機積分總和 Points_Sum:總累計積分 L1Y_Points_Sum:第2年觀測窗口總累計積分 Ration_L1Y_Flight_Count:第2年的乘機次數(shù)比率 Ration_P1Y_Flight_Count:第1年的乘機次數(shù)比率 Ration_P1Y_BPS:第1年里程積分占最近兩年積分比例 Ration_L1Y_BPS:第2年里程積分占最近兩年積分比例 Point_NotFlight:非乘機的積分變動次數(shù) 1,、數(shù)據(jù)準備 import pandas as pdimport numpy as npfrom sklearn.cluster import KMeansimport matplotlib.pyplot as plt data = pd.read_csv('data/air_data.csv') # 觀察各列數(shù)據(jù)# print(data.head())# explore = data.describe(percentiles=[], include='all').T# explore['null'] = len(data) - explore['count']# print(explore.head())# print(data.isnull().sum()) # 去除臟數(shù)據(jù)并只保留需要使用得字段data_cleaned = data[data['SUM_YR_1'].notnull() & data['SUM_YR_2'].notnull()]flag1 = data['SUM_YR_1'] != 0flag2 = data['SUM_YR_2'] != 0flag3 = (data['SEG_KM_SUM'] == 0) & (data['avg_discount'] == 0)data_cleaned = data_cleaned[flag1 | flag2 | flag3]data_cleaned = data_cleaned.reset_index(drop=True)data_sepc = data_cleaned[['LOAD_TIME', 'FFP_DATE', 'LAST_TO_END', 'FLIGHT_COUNT', 'SEG_KM_SUM', 'avg_discount']] # 將數(shù)據(jù)字段轉換成LRFMCdata_sepc['LOAD_TIME'] = pd.to_datetime(data_sepc['LOAD_TIME'])data_sepc['FFP_DATE'] = pd.to_datetime(data_sepc['FFP_DATE'])data_LRFMC = pd.DataFrame()data_LRFMC['L'] = ((data_sepc['LOAD_TIME'] - data_sepc['FFP_DATE']) / np.timedelta64(1, 'D')) / 30data_LRFMC['R'] = data_sepc['LAST_TO_END']data_LRFMC['F'] = data_sepc['FLIGHT_COUNT']data_LRFMC['M'] = data_sepc['SEG_KM_SUM']data_LRFMC['C'] = data_sepc['avg_discount'] # 對LRFMC進行規(guī)格化處理data_std_scale = (data_LRFMC - data_LRFMC.mean(axis=0)) / (data_LRFMC.std(axis=0))data_std_scale.columns = ['Z' i for i in data_std_scale.columns]# print(data_std_scale.head()) 2,、使用Kmeans進行聚類def distEclud(vecA, vecB): ''' 計算兩個向量的歐式距離的平方,并返回 ''' return np.sum(np.power(vecA - vecB, 2)) def test_Kmeans_nclusters(data_train): ''' 計算不同的k值時,,SSE的大小變化 ''' data_train = data_train.values nums = range(2, 10) SSE = [] for num in nums: sse = 0 kmodel = KMeans(n_clusters=num, n_jobs=4) kmodel.fit(data_train) cluster_ceter_list = kmodel.cluster_centers_ cluster_list = kmodel.labels_.tolist() for index in range(len(data_train)): # 計算殘差平方和 cluster_num = cluster_list[index] sse = distEclud(data_train[index, :], cluster_ceter_list[cluster_num]) print('簇數(shù)是', num, '時,; SSE是', sse) SSE.append(sse) return nums, SSE # 畫圖,通過觀察SSE與k的取值嘗試找出合適的k值nums, SSE = test_Kmeans_nclusters(data_std_scale)plt.rcParams['font.size'] = 12.0plt.style.use('ggplot')fig = plt.figure(figsize=(10, 10))ax = fig.add_subplot(1, 1, 1)ax.plot(nums, SSE, marker=' ')ax.set_xlabel('n_clusters', fontsize=18)ax.set_ylabel('SSE', fontsize=18)fig.suptitle('KMeans', fontsize=20)plt.show() 從上圖可大致確定拐點在5左右,,接下來選擇k=5進行聚類 # 獲取聚類結果k = 5kmodel = KMeans(k)kmodel.fit(data_std_scale)r = pd.concat([data_std_scale, pd.Series(kmodel.labels_, index=data_std_scale.index)], axis=1)r.columns = list(data_std_scale.columns) ['mem_class']print(r.head()) # 獲取聚類中心點結果r1 = pd.Series(kmodel.labels_).value_counts() # 統(tǒng)計各個類別的數(shù)目r2 = pd.DataFrame(kmodel.cluster_centers_) # 找出聚類中心max_v = r2.values.max()min_v = r2.values.min()r_center = pd.concat([r2, r1], axis=1) # 橫向連接(0是縱向),,得到聚類中心對應的類別下的數(shù)目r_center.columns = list(data_std_scale.columns) ['mem_class']# mem_class = r.groupby('mem_class').size().reset_index(name='counts') 聚類結果: 聚類中心點結果: 3,、對聚類結果進行可是化展現(xiàn)# 查看每個類別下,每個數(shù)值得分布數(shù)據(jù)for i in range(k): data_std_scale[r['mem_class'] == i].plot(kind='kde', linewidth=2, subplots=True, sharex=False, layout=(1, data_std_scale.shape[1]), figsize=(16, 2)) # data_std_scale[r['mem_class'] == i].plot(kind='hist', linewidth=2, subplots=True, sharex=False, # layout=(1, data_std_scale.shape[1]), figsize=(16, 2)) plt.legend()plt.show() # 將各個類別中心點值在同一圖形上展示(便于對比)clu = kmodel.cluster_centers_feature = ['L', 'R', 'F', 'M', 'C']colors = ['red', 'green', 'yellow', 'blue', 'black']for i in range(k): plt.plot(feature, clu[i], label='clustre ' str(i), linewidth=2, color=colors[i], marker='o')plt.ylabel('values')plt.show() # 以雷達圖得方式展示(更加直觀)fig = plt.figure(figsize=(10, 8))ax = fig.add_subplot(111, polar=True)center_num = r_center.valuesN = len(feature)for i, v in enumerate(center_num): # 設置雷達圖的角度,,用于平分切開一個圓面 angles = np.linspace(0, 2 * np.pi, N, endpoint=False) # 為了使雷達圖一圈封閉起來,,需要下面的步驟 center = np.concatenate((v[:-1], [v[0]])) angles = np.concatenate((angles, [angles[0]])) # 繪制折線圖 ax.plot(angles, center, 'o-', linewidth=2, label='category_%d : %d' % (i 1, v[-1])) # 填充顏色 ax.fill(angles, center, alpha=0.25) # 添加每個特征的標簽 ax.set_thetagrids(angles * 180 / np.pi, feature, fontsize=15) # 設置雷達圖的范圍 ax.set_ylim(min_v - 0.1, max_v 0.1) # 添加標題 plt.title('LRFCM', fontsize=20) # 添加網(wǎng)格線 ax.grid(True) # 設置圖例 plt.legend(loc='upper right', bbox_to_anchor=(1.3, 1.0), ncol=1, fancybox=True, shadow=True)# 顯示圖形plt.show() 4、對聚類結果進行分析及定義 通過以上數(shù)據(jù)我們就可以根據(jù)具體每個分類得值進行會員劃分: 將用戶定義為5個等級: 重要保持客戶:平均折扣率高(C↑),,最近有乘機記錄(R↓),,乘機次數(shù)高(F↑)或里程高(M↑)這類客戶機票票價高,不在意機票折扣,,經(jīng)常乘機,,是最理想的客戶類型公司應優(yōu)先將資源投放到他們身上,維持這類客戶的忠誠度 重要發(fā)展客戶平均折扣率高(C↑),,最近有乘機記錄(R↓),,乘機次數(shù)低(F↓)或里程低(M↓)這類客戶機票票價高,不在意機票折扣,,最近有乘機記錄,,但總里程低,具有很大的發(fā)展?jié)摿緫訌娺@類客戶的滿意度,,使他們逐漸成為忠誠客戶 重要挽留客戶平均折扣率高(C↑),,乘機次數(shù)高(F↑)或里程高(M↑),最近無乘機記錄(R↑)這類客戶總里程高,,但較長時間沒有乘機,,可能處于流失狀態(tài)公司應加強與這類客戶的互動,召回用戶,,延長客戶的生命周期 一般客戶平均折扣率低(C↓),,最近無乘機記錄(R↑),乘機次數(shù)低(F↓)或里程低(M↓),,入會時間短(L↓)這類客戶機票票價低,,經(jīng)常買折扣機票,最近無乘機記錄,,可能是趁著折扣而選擇購買,,對品牌無忠誠度公司需要在資源支持的情況下強化對這類客戶的聯(lián)系 低價值客戶平均折扣率低(C↓),最近無乘機記錄(R↑),,乘機次數(shù)低(F↓)或里程高(M↓),,入會時間長(L↑)這類客戶與一般客戶類似,機票票價低,,經(jīng)常買折扣機票,,最近無乘機記錄,可能是趁著折扣而選擇購買,,對品牌無忠誠度 可以看出重要保持客戶,、重要發(fā)展客戶,、重要挽留客戶是最具價值的前三名客戶類型,為了深度挖掘航空公司各類型客戶的價值,,需要提升重要發(fā)展客戶的價值,、穩(wěn)定和延長重要保持客戶的高水平消費、對重要挽留客戶積極進行關系恢復,,并策劃相應的營銷策略加強鞏固客戶關系,。 |
|
來自: 昵稱16619343 > 《待分類》