本文是對攜程用戶流失預測案例的一個總結,主要任務是對客戶流失率進行建模分析,并挖掘出影響用戶流失的關鍵因素。
目錄:
● 項目介紹
● 問題分析
● 數據探索
● 特征工程
● 建模分析
● 總結
一、項目介紹
攜程作為中國領先的綜合性旅行服務公司,每天向超過2.5億會員提供全方位的旅行服務,在這海量的網站訪問量中,我們可分析用戶的行為數據來挖掘潛在的信息資源。其中,客戶流失率是考量業務成績的一個非常關鍵的指標。數據是由攜程官方提供的經過脫敏處理的一周用戶訪問數據,不包含用戶ID等信息,目的是為了深入了解用戶畫像及行為偏好,找到最優算法,挖掘出影響用戶流失的關鍵因素。
二、 問題分析
這個項目要解決的問題是關于用戶流失的,在官方提供的字段和解釋中,有一個label字段,這個是目標變量,也就是我們需要進行預測的值。label=1代表客戶流失,label=0代表客戶未流失,很顯然這是個分類的預測問題。
對于本項目而言,最終的評價標準是要求在精確度達到97%的情況下,最大化召回率。從業務角度這個評價標準很好理解,平臺一定不允許有客戶流失的情況發生,但是挽回可能流失的客戶需要成本,所以要求召回率盡可能高。
如無特別說明,一般用的是PR曲線和ROC曲線。ROC曲線有一個突出優勢,就是不受樣本不均衡的影響。
三、 數據探索
1、數據總體情況
官方共提供2個數據集,分別為訓練集userlostprob_train.txt和測試集userlostprob_test.txt。訓練集為2016.05.15-2016.05.21期間一周的訪問數據,測試集為2016.05.22-2016.05.28期間一周的訪問數據。本文采用測試集數據,為保護客戶隱私,不提供uid等信息。數據經過了脫敏,和實際商品的訂單量、瀏覽量、轉化率等有一些差距,但是不會影響這個問題的可解性。
數據共有51個字段,除了目標變量label,還有50個特征。
拿到一份數據,首先要做的是基于業務情況,理解每個字段背后的含義。在特征變量超過10個的情況,一般要先對其進行分類。通過觀察和業務情況,我將該數據大概分成三類:客戶行為指標、訂單指標和酒店指標如下圖。當然我也參考了網絡上一些大神的分類,可能還是存在一些偏差。訂單相關的指標:如入住日期、訂單數、取消率等;客戶行為相關的指標:如星級偏好、用戶偏好價格等;酒店相關的指標,如酒店評分均值、酒店評分人數、平均價格等。
從字段的描述信息來看,可以得到以下異常信息:
某些特征列存在不同程度的缺失;
有的特征列存在極值的情況,后面在進行缺失值填充的時候需要注意分布形態,另外對極值也需要處理一下,減小異常點對預測的影響;
類似'delta_price'等代表價格的特征存在負值,這屬于異常情況,后面需要對負值進行處理。
na_rate = (len(df)-df.count())/len(df) # 缺失率計算
a = na_rate.sort_values(ascending=False)
a1 = pd.DataFrame(a)
plt.style.use('bmh')
plt.figure(figsize = (10,12))
plt.barh(range(df.shape[1]),a1[0])
plt.xlabel('na_rate')
plt.xlim([0,1])
plt.yticks(range(df.shape[1]),a1.index.values.tolist())
for x,y in enumerate(a1[0]):
plt.text(y,x,'%.3f'%y, va='bottom')
2、各特征的分布
查看所有數值型特征的分布情況,一方面有利于特征工程中根據數據分布合理選用處理方法,包括異常值、缺失值處理,連續特征離散化處理;另一方面有助于深入了解用戶行為。
for i in range(4,50):
plt.hist(df[df.columns[i]].dropna().get_values())
plt.xlabel(df.columns[i])
plt.show()
忽略兩端極值的影響,可以把businessrate_pre、businessrate_pre2、cancelrate_pre這3個特征近似看作正態分布,使用平均值填充缺失值。
諸如starprefer、consuming_capacity、price_sensitive這些特征,近似看作偏態分布,可以使用中位數填充缺失值。
四、 特征工程
數據和特征決定了機器學習效果的上限,而模型和算法只是逼近這個上限。特征工程是建模前的關鍵步驟,特征處理得好,可以提升模型的性能。
整個特征工程的任務主要包括:格式轉換、缺失值處理、衍生特征、聚類特征、獨熱編碼、標準化等。
1、時間特征處理
(1)格式轉換
時間特征不存在缺失值,可以先處理。訪問日期d和入住日期arrival是字符串格式,需要進行格式轉換。這里使用pandas中常用的時間函數to_datetime(),將字符串格式轉換為日期格式。
df['d'] = pd.to_datetime(df['d'], format = '%Y-%m-%d')
df['arrival'] = pd.to_datetime(df['arrival'], format='%Y-%m-%d')
(2)衍生特征
衍生特征是根據現有特征衍生出來的一些特征,比如訪問日期和實際入住日期之間的差值,入住日期是周幾,入住日期否為周末。在機器學習中,是否為周末這個特征往往是非常重要的。
# 查看用戶周幾入住
df['week2day'] = df['arrival'].map(lambda x: x.weekday())
# 查看用戶入住日期與訪問(預訂)日期的差值
df['booking_gap'] = (df['arrival'] -df['d']).map(lambda x: x.days).astype(int)
# 查看用戶入住的日期是否為周末
def is_weekend(a):
if int(a) in [0,1,2,3,4]:
return 0 # 0代表是工作日
else:
return 1 # 1代表是周末
df['is_weekend'] = df['week2day'].apply(is_weekend)
使用完這兩個時間特征之后,和sampleid一起刪除,這些特征對預測用戶流失沒有實質的幫助。
df.drop(['d','arrival','sampleid'],axis=1,inplace=True) # 刪除特征
2、異常值處理
用戶偏好價格delta_price1、delta_price2,以及當前酒店可訂最低價lowestprice存在大量的負值,理論上酒店的價格不可能為負。同時數據分布比較集中,因此采取中位數填充。而客戶價值customer_value_profit、ctrip_profits也不應該為負值,這里將其填充為0。deltaprice_pre2_t1是酒店價格與對手價差均值,可以為負值,無需處理。
# 查看最小值為負值的特征
df_min=df.min().iloc[4:]
df_min[df_min<0]
neg1=['delta_price1','delta_price2','lowestprice']
neg2=['customer_value_profit','ctrip_profits']
for col in neg1:
df.loc[df[col]<0,col]=df[col].median() # 填充中位數
for col in neg2:
df.loc[df[col]<0,col]=0 # 填充0
3、缺失值處理
缺失值全部為數值型數據,結合各個特征的數據分布情況,這里用了平均值和中位數填充兩種方式。對于近似正態分布的數據,采用平均值填充,而近似偏態分布的數據,以及其他數值型數據,全部采用中位數填充。缺失率在80%以上的,如historyvisit_7ordernum,已經沒有太多分析價值,直接去掉。
df=df.drop('historyvisit_7ordernum',axis=1) # 刪除特征
fillwithmean=['businessrate_pre','businessrate_pre2','cancelrate_pre']
for col in df.columns:
if col in fillwithmean:
fillvalue = df[col].mean()
df[col] = df[col].fillna(fillvalue) # 填充平均值
else:
fillvalue = df[col].median()
df[col] = df[col].fillna(fillvalue) # 填充中位數
4、聚類特征
在實際行為中用戶ID對我們的分析流失起到重要的作用,但是由于數據敏感性問題,樣本數據中并沒有給出,但是我們可以通過將一些特征信息進行聚類,對這些樣本進行用戶分組,同理也可對酒店分組。把這兩類主體進行一個聚類,并把類的標簽作為一個新的特征。這里使用KMeans的方法做聚類處理,分別將用戶和酒店分成3個類別。
# 標準化
from sklearn.preprocessing import StandardScaler #標準化
ss = StandardScaler()
# 用戶聚類
from sklearn.cluster import KMeans
user_group = df[['historyvisit_totalordernum','ordercanncelednum','ordercanceledprecent','historyvisit_visit_detailpagenum','historyvisit_avghotelnum','lowestprice_pre']]
for i in range(len(user_group.columns)):
user_group[user_group.columns[i]] = ss.fit_transform(user_group[user_group.columns[i]].values.reshape(-1,1)) # reshape(-1,1)將array轉換為一列
# 酒店聚類
hotel_group = df[['commentnums','novoters','cancelrate','hoteluv','hotelcr','lowestprice']]
for i in range(len(hotel_group.columns)):
hotel_group[hotel_group.columns[i]] = ss.fit_transform(hotel_group[hotel_group.columns[i]].values.reshape(-1,1))
df['user_type'] = KMeans(n_clusters=3, init='k-means++').fit_predict(user_group) # KMeans方法,分3類
df['hotel_type'] = KMeans(n_clusters=3, init='k-means++').fit_predict(hotel_group) # KMeans方法,分3類
5、連續特征離散化
在這個案例中,將某些數值型特征轉換成類別呈現更有意義,比如用戶決策習慣、星級偏好、平均價格、消費能力指數等,同一類別表現出相似的屬性。同時可以使得算法減少噪聲的干擾。而且在機器學習中,一般很少直接將連續值作為邏輯回歸模型的特征輸入。特征離散化以后,可以簡化邏輯回歸模型,降低了模型過擬合的風險。后面會用到邏輯回歸模型,所以在這里還是先做離散化處理。
根據業務經驗選擇合適的連續型特征,在一定的數值范圍內劃分分區。
def deal_decisionhabit_user(x):
if x<10:
return 0
elif x<30:
return 1
else:
return 2
def deal_starprefer(x):
if x<50:
return 0
elif x<80:
return 1
else:
return 2
def deal_avgprice(x):
if x<400:
return 0
elif x<1000:
return 1
else:
return 2
def deal_consuming_capacity(x):
if x<40:
return 0
elif x<80:
return 1
else:
return 2
離散化之后的特征,以及酒店和用戶這兩個聚類特征,均為數值型,都需要轉換為字符串型,以便接下來進行獨熱編碼。
df['decisionhabit_user'] = df['decisionhabit_user'].map(lambda x:str(deal_decisionhabit_user(int(x))))
df["starprefer"] = df["starprefer"].map(lambda x:str(deal_starprefer(int(x))))
df["consuming_capacity"] = df["consuming_capacity"].map(lambda x: str(deal_consuming_capacity(int(x))))
df['avgprice'] = df['avgprice'].map(lambda x: str(deal_avgprice(int(x))))
df[["user_type","hotel_type"]]=df[["user_type","hotel_type"]].applymap(str)
6、分類變量one-hot-encode
對分類變量進行獨熱編碼,可以解決分類器不好處理屬性數據的問題,編碼后的特征都可以看做是連續的特征,并且在一定程度上也起到了擴充特征的作用。這里使用get_dummies方法實現one-hot-encode。
df=pd.get_dummies(df)
7、用戶分組特征
由于數據集沒有提供用戶uid,需要根據已有特征對用戶進行分組,生成用戶標簽usertag。這里采取了一種近似的方法,如果用戶的某些行為特征相同,則認為是同一個用戶的行為。后面需要根據用戶標簽分割數據集,同一個用戶的信息不能同時出現在訓練集和測試集中,否則模型會過擬合。
這里用于判斷是否為同一用戶行為的特征有:用戶一年內取消訂單數、近3個月用戶歷史日均訪問酒店數、用戶年訂單數、客戶價值_近1年、客戶價值、用戶轉化率、年訪問次數,并且使用hash函數處理字符串。
df['usertag']= df.ordercanncelednum.map(str) \
+ df.historyvisit_avghotelnum.map(str) \
+ df.ordernum_oneyear.map(str) \
+ df.customer_value_profit.map(str) \
+ df.ctrip_profits.map(str) \
+ df.cr.map(str) \
+ df.visitnum_oneyear.map(str)
df.usertag = df.usertag.map(lambda x: hash(x)) # 生成哈希值
8、標準化
對于一些基于距離的模型,需要標準化處理,比如回歸分析、神經網絡、SVM。
而對于與距離計算無關的樹模型,不需要標準化處理,比如決策樹、隨機森林等,因為樹中節點的選擇只關注當前特征在哪里切分對分類更好,即只在意特征內部的相對大小,而與特征間的相對大小無關。
這里還是標準化處理下,后面會用到不同的模型做對比。注意只用對部分數值型特征進行標準化,label列(0/1)、新生成的獨熱編碼(0/1)、用戶標簽usertag無需參與標準化。所以先對數據進行拆分,處理之后再使用concat合并。
df1=df
df2=pd.DataFrame(df1['label']) # label
df3=df1.iloc[:,1:-24] # 需要標準化的特征
df4=df1.iloc[:,-24:] # 獨熱編碼和用戶標簽
columns=df3.columns.tolist() # 提取df3的列名,存放在列表中
# 對拆分后的df3進行標準化
scaler = StandardScaler()
scaler.fit(df3)
df3=scaler.transform(df3)
df3=pd.DataFrame(df3,columns=columns) # 標準化處理后的數據是array,轉換為DataFrame
df_concat1=pd.concat([df2,df3],axis=1) # 與df2合并
df_concat2=pd.concat([df_concat1,df4],axis=1) # 與df4合并
df_new=df_concat2 # 生成新的DataFrame
8、分割數據集
在使用數據集訓練模型之前,我們需要先將整個數據集分為訓練集、驗證集、測試集。訓練集是用來訓練模型的,通過嘗試不同的方法和思路使用訓練集來訓練不同的模型,再通過驗證集使用交叉驗證來挑選最優的模型,通過不斷的迭代來改善模型在驗證集上的性能,最后再通過測試集來評估模型的性能。
由于官方提供的數據已經劃分好訓練集和測試集,我們現在需要在原始訓練集中劃分出訓練集和驗證集,這里是70%劃分為訓練集,30%劃分為驗證集。
那究竟依據什么特性進行劃分呢?劃分數據集需注意時間性、地域性、層次性(stratifiedKFold)。前面已經提到過,在做本地數據集劃分的時候需要基于用戶進行劃分,也就是要保證劃分前后的數據是滿足獨立同分布的。另外,由于提供的是一周的數據,時間序列特性不是很明顯,所以沒有按時間線對數據進行劃分。
splitnum=int(len(df_new.index)* 0.7) # 分割點:70%
df_new=df_new.sort_values(by="usertag") # 按照usertag排序
# 前70%行數據生成訓練集
df_new.iloc[:splitnum,].to_csv(r'data/userlostprob_train.csv', sep='\t', index=False)
# 其余數據生成測試集
df_new.iloc[splitnum:, ].to_csv(r'data/userlostprob_test.csv', sep='\t', index=False)
五、建模分析
對于一個分類問題,一般經常使用的模型有邏輯回歸、隨機森林、xgboost。在正常的情況下,xgboost會比隨機森林效果更好,但是如果數據的噪聲比較大的話,也會出現隨機森林的效果更好的情況。為了比較不同模型在這個分類問題中的性能表現,這里使用了三個模型分別訓練和評估。
導入包,使用sklearn庫完成建模分析。
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import accuracy_score
from sklearn import metrics
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import GridSearchCV
from sklearn.feature_selection import SelectFromModel
導入處理后的數據集,并刪除usertag標簽。
train=r'data/userlostprob_train.csv'
test=r'data/userlostprob_test.csv'
trainData = pd.read_csv(train,sep="\t").drop(["usertag"],axis=1)
testData = pd.read_csv(test,sep="\t").drop(["usertag"],axis=1)
從訓練集和測試集中分別提取特征和目標變量label,訓練模型后,用測試集評估模型的性能。
train_X = trainData.iloc[:,1:] # 特征從第1列開始選
train_Y = trainData.iloc[:,0] # 第0列是label
test_X = testData.iloc[:,1:]
test_Y = testData.iloc[:,0]
1、邏輯回歸模型
(1)導入模型
from sklearn import linear_model
from sklearn.linear_model import LogisticRegression
(2)模型性能評估
輸出準確率accuracy、AUC面積以及精確度precision≥0.97條件下的最大召回率recall。
lr = LogisticRegression()
lr.fit(train_X,train_Y) # 訓練模型
test_pred_lr = lr.predict_proba(test_X)[:,1] # 預測為1的可能性
fpr_lr,tpr_lr,threshold = metrics.roc_curve(test_Y,test_pred_lr)
auc = metrics.auc(fpr_lr,tpr_lr)
score = metrics.accuracy_score(test_Y,lr.predict(test_X)) # 輸入真實值和預測值
print([score,auc]) # 準確率、AUC面積
precision_lr, recall_lr, thresholds = precision_recall_curve(test_Y, test_pred_lr)
pr_lr = pd.DataFrame({"precision": precision_lr, "recall": recall_lr})
prc_lr = pr_lr[pr_lr.precision >= 0.97].recall.max()
print(prc_lr) # 精確度≥0.97條件下的最大召回率
邏輯回歸模型過于簡單,預測準確率比較低,在precision≥0.97的情況下,最大recall僅為0.0001。
2、隨機森林模型
(1)導入分類器
from sklearn.ensemble import RandomForestClassifier
(2)模型性能評估
輸出準確率accuracy、AUC面積以及精確度precision≥0.97條件下的最大召回率recall。
rfc = RandomForestClassifier(n_estimators=200)
rfc.fit(train_X,train_Y) # 訓練模型
test_pred_rfc = rfc.predict_proba(test_X)[:,1] # 預測為1的可能性
fpr_rfc,tpr_rfc,thre_rfchold = metrics.roc_curve(test_Y,test_pred_rfc)
auc = metrics.auc(fpr_rfc,tpr_rfc)
score = metrics.accuracy_score(test_Y,rfc.predict(test_X)) # 輸入真實值和預測值
print([score,auc]) # 準確率、AUC面積
precision_rfc, recall_rfc, thresholds = precision_recall_curve(test_Y, test_pred_rfc)
pr_rfc = pd.DataFrame({"precision": precision_rfc, "recall": recall_rfc})
prc_rfc = pr_rfc[pr_rfc.precision >= 0.97].recall.max()
print(prc_rfc) # 精確度≥0.97條件下的最大召回率
[0.90051888068642982, 0.95880960471941379]
0.636531495094
對于這個項目,隨機森林模型表現較好,迭代200次以后模型準確率0.900,在precision≥0.97的情況下,最大recall已經可以達到0.636。
(3)特征重要性
使用feature_importance方法,可以得到特征的重要性排序。當然,還可以使用plot_importance方法,默認的importance_type=“weight”,將其設置為“gain”,可以得到和feature_importance方法相同的結果。
importance = rfc.feature_importances_
indices = np.argsort(importance)[::-1] # np.argsort()返回數值升序排列的索引,[::-1]表示倒序
features = train_X.columns
for f in range(train_X.shape[1]):
print("%2d) %3d %20s (%.4f)" %(f+1,indices[f],features[indices[f]], importance[indices[f]]))
# 作圖
plt.figure(figsize=(15,8))
plt.title('Feature importance')
plt.bar(range(train_X.shape[1]),importance[indices],color='blue')
plt.xticks(range(train_X.shape[1]),indices)
plt.xlim([-1,train_X.shape[1]])
plt.show()
在前15個特征中,用戶相關的指標有:年訪問次數、訪問時間點、一年內距上次訪問時長、用戶轉化率、一年內距離上次下單時長、提前預定時間、用戶價值。酒店相關的指標有:24小時內已訪問酒店商務屬性指數均值、24小時內已訪問酒店可訂最低價均值、24小時歷史瀏覽次數最多酒店歷史uv、24小時內已訪問次數最多酒店可訂最低價、24小時歷史瀏覽酒店歷史uv均值。城市相關的指標:昨日提交當前城市同入住日期的app訂單數、昨日訪問當前城市同入住日期的app uv數。
(4)篩選特征
根據特征重要性結果挑選特征,重新進行模型訓練和評估。這里篩選的閾值設定為0.005。不過篩選特征后模型性能沒有得到明顯提升。
selection = SelectFromModel(rfc, threshold=0.005, prefit=True)
select_train_X = selection.transform(train_X)
select_test_X = selection.transform(test_X)
3、xgboost模型
(1)導入分類器
import xgboost as xgb
from xgboost.sklearn import XGBClassifier
(2)模型調參
使用GridSearchCV(網格搜索)的方法調節xgboost模型的參數,主要的影響參數有樹的最大深度、最小葉子節點樣本權重和、懲罰項系數gamma、使用數據占比、使用特征占比。這里分步調節,尋找最優參數。
param_test1 = {
'max_depth': range(3, 10, 2),
'min_child_weight': range(1, 6, 2)}
param_test2 = {
'gamma': [i / 10.0 for i in range(0, 5)]}
param_test3 = {
'subsample': [i / 10.0 for i in range(6, 10)],
'colsample_bytree': [i / 10.0 for i in range(6, 10)]}
gsearch = GridSearchCV(estimator=XGBClassifier(learning_rate =0.1, n_estimators=1000, max_depth=5,min_child_weight=1, gamma=0, subsample=0.8, colsample_bytree=0.8, objective= 'binary:logistic', nthread=1, scale_pos_weight=1, seed=27),param_grid =param_test1,scoring='roc_auc',n_jobs=1,iid=False, cv=5)
gsearch.fit(train_X ,train_Y )
means = gsearch.cv_results_['mean_test_score']
params = gsearch.cv_results_['params']
print(means, params)
# 模型最好的分數、模型最好的參數、模型最好的評估器
print(gsearch.best_score_ ,gsearch.best_params_,gsearch.best_estimator_)
(3)模型性能評估
使用上一步找到的最優參數組合,代入模型進行訓練和評估。輸出準確率accuracy、AUC面積以及精確度precision≥0.97條件下的最大召回率recall。
model = XGBClassifier(base_score=0.5, booster='gbtree', colsample_bylevel=1,
colsample_bytree=0.8, gamma=0, learning_rate=0.1, max_delta_step=0,
max_depth=9, min_child_weight=1, missing=None, n_estimators=1000,
reg_alpha=0, reg_lambda=1, scale_pos_weight=1, seed=27, silent=True,
subsample=0.9)
model.fit(train_X ,train_Y) # 訓練模型
test_pred_xgb = model.predict_proba(test_X)[:,1] # 預測為1的可能性
fpr_xgb,tpr_xgb,threshold = metrics.roc_curve(test_Y,test_pred_xgb)
auc = metrics.auc(fpr_xgb,tpr_xgb)
score = metrics.accuracy_score(test_Y,model.predict(test_X)) # 輸入真實值和預測值
print([score,auc]) # 準確率、AUC面積
precision_xgb, recall_xgb, thresholds = precision_recall_curve(test_Y, test_pred_xgb)
pr_xgb = pd.DataFrame({"precision": precision_xgb, "recall": recall_xgb})
prc_xgb = pr_xgb[pr_xgb.precision >= 0.97].recall.max()
print(prc_xgb) # 精確度≥0.97條件下的最大召回率
[0.9064082247903219, 0.95434695969275529]
0.587697393873
迭代1000次之后,得到的模型準確率0.906,在precision≥0.97的情況下,最大recall可以達到0.587。
(4)特征重要性
從xgboost模型也可以得到影響用戶流失的特征,按照重要性排序,有24小時內是否訪問訂單填寫頁、提前預訂時間、用戶轉化率、用戶決策、訪問時間點、用戶年訂單數、當前酒店歷史cr、用戶類型、24小時內已訪問酒店商務屬性指數均值等。
其中酒店相關的指標有:當前酒店歷史cr、24小時內已訪問酒店商務屬性指數均值。用戶相關的指標有:24小時內是否訪問訂單填寫頁、提前預訂時間、用戶轉化率、用戶決策、訪問時間點、用戶年訂單數、用戶類型。
使用隨機森林模型和xgboost模型得到的在top10特征差異較大,重合的特征只有4個,訪問時間點、提前預訂時間、用戶轉化率、24小時內已訪問酒店商務屬性指數均值。
這兩個模型的ROC曲線和PR曲線差異不大,總體而言隨機森林模型比xgboost模型表現好。從評定標準來看,隨機森林的召回率比xgboost稍高一些。認為可能是因為數據缺失較多,造成了噪音比較大。
六、總結
1、特征工程
缺失值和異常值處理是關鍵,根據數據和模型選擇是否需要獨熱編碼和標準化,按照業務經驗合理構造衍生特征和聚類特征。篩選特征的方法有很多種,比如方差、卡方值、相關系數等,這里用了樹模型的特征重要性。特征工程決定了機器學習效果的上限,模型優化只能無限接近這個上限。
2、模型對比結果
使用邏輯回歸、隨機森林和xgboost三種模型做對比分析,按照評定標準,在精確度≥0.97的條件下,隨機森林模型的性能最優,召回率可以達到0.636。該模型可以直接上線用于用戶流失預測。
3、影響用戶流失的關鍵因素
從模型表現上看,隨機森林效果最優。根據特征重要性排序,提取影響用戶流失的最關鍵因素。其中用戶相關的指標有:年訪問次數、訪問時間點、一年內距上次訪問時長、用戶轉化率、一年內距離上次下單時長。酒店相關的指標有:24小時內已訪問酒店商務屬性指數均值、24小時內已訪問酒店可訂最低價均值、24小時歷史瀏覽次數最多酒店歷史uv、24小時內已訪問次數最多酒店可訂最低價、24小時歷史瀏覽酒店歷史uv均值。城市相關的指標:昨日提交當前城市同入住日期的app訂單數、昨日訪問當前城市同入住日期的app uv數。