聚类分析在用户行为中的实例_《数据分析实战》书中案例分析 - 进阶篇(三):用户行为分析【决策树分析】 - python实现...
分析进阶篇(三):通过决策树分析,探明具有哪些行为的用户会是长期用户案例背景:《黑猫游戏》相比其他应用,很多用户开始游戏后不久就离开了。为改善这种情况,通过数据分析探明,开始游戏后,什么样的用户行为能促使用户今后也持续登录游戏,从而帮助改进游戏设计。由于用户在初期的游戏行为,主要包括3类:战斗、协作、发送消息,那么,通过量化这3类社交行为(每日行为发送次数、每日行为比率、每日行为次数的主成分数据)
分析进阶篇(三):通过决策树分析,探明具有哪些行为的用户会是长期用户
案例背景:
《黑猫游戏》相比其他应用,很多用户开始游戏后不久就离开了。
为改善这种情况,通过数据分析探明,开始游戏后,什么样的用户行为能促使用户今后也持续登录游戏,从而帮助改进游戏设计。
由于用户在初期的游戏行为,主要包括3类:战斗、协作、发送消息,那么,通过量化这3类社交行为(每日行为发送次数、每日行为比率、每日行为次数的主成分数据),来参与分析。
同时,如果把所有分析属性放在一起分析,得到的结果可能难以解释。可以通过先将各分析属性和各自的社交行为进行聚类,以得到的类作为自变量。这样,我们就能清楚知道,哪种分析属性用来分析哪种社交行为最能解释模型。
模型的因变量,选择用户一周时间内的登录密度(登陆天数/7)
时间区间的切分——
以用户开始游戏后一周内(0-6天)的行为数据作为自变量,
登陆密度的计算,则通过下一周(7-13天)数据得到。
使用数据:
●DAU:日活数据
●Install:用户安装数据,包括用户属性等
●战斗行为日志:某一天,某个用户,战斗行为发生的次数
●发送消息行为日志:某一天,某个用户,发送消息行为发生的次数
●协作行为日志:某一天,某个用户,协作行为发生的次数
分析流程:加载常用库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import sklearn
import seaborn as sns读入数据
path = 'yourpath/R/sample-data/section9/daily/'
install_path = 'yourpath/R/sample-data/section9/snapshot/install/game-01/2013-09-30/install.csv'
datearray = pd.date_range('2013-06-01','2013-08-31',freq='D')
datedau = pd.date_range('2013-06-01','2013-09-30',freq='D')
from datetime import datetime
dau = pd.DataFrame()
for i in datedau:
date = datetime.date(i)
app_name = 'game-01'
path_small = path
path_pro = f'{path_small}dau/{app_name}/{date}/dau.csv'
data = pd.read_csv(path_pro)
data = pd.DataFrame(data)
dau = pd.concat([dau,data],ignore_index=True,axis=0)
battle = pd.DataFrame()
for i in datearray:
date = datetime.date(i)
app_name = 'game-01'
path_small = path
path_pro = f'{path_small}action/{app_name}/battle/{date}/battle.csv'
data = pd.read_csv(path_pro)
data = pd.DataFrame(data)
battle = pd.concat([battle,data],ignore_index=True,axis=0)
help1 = pd.DataFrame()
for i in datearray:
date = datetime.date(i)
app_name = 'game-01'
path_small = path
path_pro = f'{path_small}action/{app_name}/help/{date}/help.csv'
data = pd.read_csv(path_pro)
data = pd.DataFrame(data)
help1 = pd.concat([help1,data],ignore_index=True,axis=0)
message = pd.DataFrame()
for i in datearray:
date = datetime.date(i)
app_name = 'game-01'
path_small = path
path_pro = f'{path_small}action/{app_name}/message/{date}/message.csv'
data = pd.read_csv(path_pro)
data = pd.DataFrame(data)
message = pd.concat([message,data],ignore_index=True,axis=0)
install = pd.read_csv(install_path)安装数据和日活数据一览
三种行为日志数据一览预处理数据
通过联结dau和install表,生成用户活跃日期和初次安装日期的时间间隔,便于我们筛选不同时间间隔的数据。
#联立dau和install表
login_interval = pd.merge(dau,install,on='user_id',how= 'left',suffixes=['','_install'])
#定义一个函数,返回时间间隔,利用apply,在整个df上运行
def time_interval(series):
end_date = datetime.strptime(series['log_date'],'%Y-%m-%d')
first_date = datetime.strptime(series['log_date_install'],'%Y-%m-%d')
interval = int((end_date-first_date).days)
return interval
login_interval['interval'] = login_interval.apply(time_interval,axis=1)
取出用户首次访问后第7-13天的数据,根据用户在第7-13天区间内登录天数/7,得到登录密度,作为模型的因变量
interval713 = login_interval[(login_interval.interval>=7)&(login_interval.interval<=13)]
ds713 = round(interval713.groupby('user_id')['interval'].count()/7,4)
ds713 = pd.DataFrame(ds713).reset_index()
#合并分析对象用户和登录密度数据
#选择安装日期在2013-06-01到2013-08-25的数据
install_713_ds = pd.merge(install[(install.log_date>='2013-06-01')&(install.log_date<='2013-08-25')],ds713,on='user_id',how='left')
install_713_ds.fillna(0,inplace=True)
install_713_ds.rename(columns={'interval':'density'},inplace=True)用作分析的用户的相关信息和第二周登陆密度数据
生成三类社交行为的每日次数数据、每日行为比率、和每日行为主成分数据。此处只展示战斗的处理过程,协作行为和发送信息的行为处理类似。
#生成关于战斗的数据
#合并战斗数据和首次访问数据
battle_install = pd.merge(battle,install,on='user_id',suffixes=['','_install'])
#计算战斗时间和首次访问时间差
battle_install['interval'] = battle_install.apply(time_interval,axis=1)
#取出时间差在一周内(0-6)天的数据
battle_install2 = battle_install[(battle_install.interval>=0)&(battle_install.interval<=6)]
#将0-6天内的战斗数据结构,以每天作为列,战斗次数作为值。
battle_install2 = battle_install2[['user_id','count','interval']]
battle_count_06 = battle_install2.pivot_table(index='user_id',columns='interval',
aggfunc='sum',fill_value=0).droplevel(0,axis=1).reset_index()
battle_count_06.rename(columns={0:'d0',1:'d1',2:'d2',3:'d3',4:'d4',5:'d5',6:'d6'},inplace=True)
#生成比率数据和PCA后数据
#比率即每日发生行为次数/7日行为总次数
battle_pct_06 = battle_count_06.iloc[:,1:]
battle_pct_06 = round(battle_pct_06.div(battle_pct_06.sum(axis=1),axis=0),3)
battle_pct_06['user_id'] = battle_count_06['user_id']
#输出主成分数据,减小变量间的相关性
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
battle_pca_06 = battle_count_06.iloc[:,1:]
pca_battle = PCA()
ss = StandardScaler()
battle_pca_06_2 = ss.fit_transform(battle_pca_06)
pca_battle.fit(battle_pca_06_2)
battle_pca_06_3 = pca_battle.transform(battle_pca_06_2)
battle_pca_06 = pd.DataFrame(battle_pca_06_3)
battle_pca_06['user_id'] = battle_count_06['user_id']
battle_pca_06.rename(columns={0:'PC1',1:'PC2',2:'PC3',3:'PC4',4:'PC5',5:'PC6',6:'PC7'},inplace=True)处理后的战斗行为数据一览
同样的方法处理协作行为数据、发送消息行为数据。社交行为的聚类分析
对battle,message,help的count,ratio,pca成分,分别进行3-6类的KMeans聚类(因为不确定聚几类最好,但通常分析选择3-6类),将类作为新的自变量。则共产生3*3*4=36个变量。
写一个函数,来循环聚类,这样只需要调用3次方法就可,不用反复聚类。
from sklearn.cluster import KMeans
# 用来生成关于类数据的函数
def behavior_cluster(x_count,x_ratio,x_pca):
df = pd.DataFrame()
user = x_count.iloc[:,0]
for i in np.arange(3,7,1):
km_count = KMeans(n_clusters=i,max_iter=500)
km_ratio = KMeans(n_clusters=i,max_iter=500)
km_pca = KMeans(n_clusters=i,max_iter=500)
x_count = x_count.iloc[:,1:]
x_ratio = x_ratio.iloc[:,:-1]
x_pca = x_pca.iloc[:,:-1]
count_class = km_count.fit_predict(x_count)
ratio_class = km_ratio.fit_predict(x_ratio)
pca_class = km_pca.fit_predict(x_pca)
count_class = pd.Series(count_class,name=f'count_class{i}_clusterid')
ratio_class = pd.Series(ratio_class,name=f'ratio_class{i}_clusterid')
pca_class =pd.Series(pca_class,name=f'pca_class{i}_clusterid')
df = pd.concat([df,count_class],axis=1)
df = pd.concat([df,ratio_class],axis=1)
df = pd.concat([df,pca_class],axis=1)
df = df.applymap(lambda x:x+1)
df['user_id'] = user
return df
battle_class = behavior_cluster(battle_count_06,battle_pct_06,battle_pca_06)
message_class = behavior_cluster(message_count_06,message_pct_06,message_pca_06)
help_class = behavior_cluster(help_count_06,help_pct_06,help_pca_06)聚类后的3类社交行为
我们将用户的登录密度和与“战斗”相关的类数据合并。与“发送消息”相关的类数据合并,与“协作”相关的类数据合并,用0替换“NA”(部分用户没有发生三类社交行为,这里用0类来代替,python的聚类输出的label是以0开始,我在上述的聚类方法里,将所有label加1后再输出,这里就可以用0类来指代无社交行为的用户)。
cluster_data = pd.merge(install_713_ds,battle_class,on='user_id',how='left')
cluster_data = pd.merge(cluster_data,message_class,on='user_id',how='left',
suffixes=['_battle',''])
cluster_data = pd.merge(cluster_data,help_class,on='user_id',how='left',
suffixes=['_message','_help'])
#将缺失行为聚类数据的,统一用0类填充
cluster_data.fillna(0,inplace=True)
再按照每类的登录密度,由小到大对每种聚类内部进行重新排列
cluster_data_melt = cluster_data.drop(columns=['log_date','install_time','gender'
,'generation','device_type'])
cluster_data_melt = cluster_data_melt.melt(id_vars=['user_id','density'])
cluster_data_avg = cluster_data_melt.groupby(['variable','value'])['density'].mean().reset_index().rename(columns = {'density':'avg_density'})
#按照【类别,均值】升序排列,每类里,根据均值生成新的升序排序号
cluster_data_avg.sort_values(by=['variable','avg_density'],inplace=True)
g_cluster = cluster_data_avg.groupby('variable')
cluster_data_avg['value2'] = g_cluster['value'].transform(lambda x:np.sort(x))
# 按照新的类编号进行合并,将每种行为聚类的均值,添加到用户表中
cluster_data_melt2 = pd.merge(cluster_data_melt,cluster_data_avg,on=['variable','value'])
cluster_data_melt2.head()按照平均密度对各聚类内部进行重新排序,value2为新的各类内部排序编号
再pivot上表,以value2(新的排序编号)作为值。产生的数据表作为自变量输入决策树模型中。
cluster_data2 = pd.pivot_table(data=cluster_data_melt2,index=['user_id','density'],
columns='variable',values='value2')
cluster_data2.reset_index(inplace=True)以社交行为的聚类结果作为自变量进行决策树分析,并可视化输出
from sklearn.tree import export_graphviz
from sklearn.tree import DecisionTreeClassifier
dtc = DecisionTreeClassifier()
X = cluster_data2.iloc[:,2:]
y =cluster_data2.iloc[:,1].astype('str')
dtc.fit(X=X,y=y)
dtc_tree = export_graphviz(dtc,out_file='yourpath/dtc_tree.dot',
feature_names=X.columns,class_names=np.unique(y.values),filled=True,
rounded=True,special_characters=True)可视化决策树
由可视化决策树结果,可以看到第一重要的是ratio_class4_clusterid_help,说明,用比率数据来分析协作行为的模式,对分析登陆密度最好。
那么,来查看下,类为4的协作的比率类的平均登录密度。
cluster_data3 = cluster_data_melt2[cluster_data_melt2.variable == 'ratio_class4_clusterid_help'][['user_id','avg_density','value2']]
cluster_data3.rename(columns={'value2':'cluster'},inplace=True)
sns.scatterplot(cluster_data3.cluster,cluster_data3.avg_density)协作行为比率聚4类的各类平均登录密度
可以看到,1,2类,在第2周的平均登录密度很低,只有0.2不到,平均只有1天。
第4类最好,登录密度在0.6左右,大概在4天左右。
接着我们来观察各个类中协作行为的比率随经过天数的变化情况
help_pct_06_class = pd.merge(help_pct_06,cluster_data3,on = 'user_id')
#计算4个类的协作行为比率随天数变化的均值
draw_help_pca_06 = help_pca_06_class.pivot_table(index='cluster').drop(
columns=['user_id','avg_density'])
draw_help_pct_06.T.plot()协作行为聚4类的各类比率每日变化
可以看到,第1类,第2类用户协作行为都集中在前2天,后续没有产生协作行为,最终第二周登录密度很低。
由数据结果看来,第一周的协作行为发生过多集中发生前2天的用户,第二周的登录密度都不高。而最好的第4类用户,协作行为在第4天有明显的增加。并且保持着持续的稳定发生。
所以考虑通过设计,来促进用户在第3、4天后的协作行为发生。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)