4

腾讯数据科学家手把手教你做用户行为分析(案例:出行选择)

 1 year ago
source link: https://www.iyunying.org/seo/dataanalysis/260428.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

腾讯数据科学家手把手教你做用户行为分析(案例:出行选择)

爱运营 • 2023年6月1日 下午4:03 • 数据分析

导读:生活中的选择行为无处不在,数据分析师面对的商业场景也存在大量的用户选择问题。系统、科学地研究用户选择问题,得到选择行为背后的客观规律并基于这些规律提出业务优化策略,这些能力对于数据分析师非常重要且极具价值。

本文将结合示例,讲解选择行为的经济学理论和计量分析模型,详细介绍用户选择行为的分析方法论。作者:周银河来源:大数据DT(ID:hzdashuju)

腾讯数据科学家手把手教你做用户行为分析(案例:出行选择)

01 引子:以出行为例剖析选择行为的具体逻辑下面以选择出行方式为例,剖析选择行为的具体逻辑,为后面的学习做好铺垫。1. 出行选择的场景还原出行就是“在某时从A点到达B点”,这一行为主要面临的选择是“以什么方式前往”,回想一下我们平时做出行选择时,是否有如下参考信息浮现在脑海。

  • 可以选择的交通方式有哪些?
  • 同程的人多不多?
  • 需要在什么时间到达?
  • 出行预算是多少?
  • 公共交通的便捷程度?
  • 出行方式是否受天气影响?

通常,我们会带着这些疑问打开出行类App看看各类交通方式的花费、耗时及路线,可能还会打开天气App看看未来一段时间是否下雨、是否有严重的雾霾,如图1-1所示。

腾讯数据科学家手把手教你做用户行为分析(案例:出行选择)

▲图1-1 打开App查看出行路线和天气2. 出行选择的决策逻辑接下来,我们通过一个更加具体的案例说明出行选择的决策逻辑:有200个家庭要进行家庭旅行,每个家庭的情况不同(包括出行人数、目的地、家庭年收入等),每个家庭都会在飞机、火车、长途巴士及自驾车中选择一种作为出行方式。不同的家庭会有不同的选择,在选择的表象下有着相似的决策逻辑。我们尝试置身于这个场景中,在大脑里构建一张类似图1-2的打分表。出行方式的属性可以主要归结为行程外(等车)耗时、行程中耗时、行程花费、舒适性等,确定这些出行方式的属性后,再结合自身属性(家庭收入、出行人数等),对每个选项进行定性/定量的排序,得到最适合自己的选择结果。

腾讯数据科学家手把手教你做用户行为分析(案例:出行选择)

▲图1-2 旅行出行方式打分表在选择的过程中,如果某个因素发生变化,就有可能对选择结果产生影响。例如:其他因素保持不变,由于航空公司促销,机票价格比火车票还便宜,你的选择是不是会从火车改为飞机呢?再假设,临行前你收获一笔超过预期的奖金,可支配的现金增多,是不是也会从火车改为飞机呢?回忆一下我们生活中其他方面的选择,其实也秉持类似的方式。经济学家、心理学家经过长期研究,发现人类个体间的“选择之道”存在较高相似性,对这些相似性加以总结就形成了一系列选择行为的经济学理论。这些长期沉淀下来的理论对于数据分析师来说是非常有价值的,它不仅能帮助我们从本质上理解相关计量选择模型的原理,还能在对业务方进行分析阐述时有理论背书,下面我们开始学习选择行为的经济学理论。02 选择行为的经济学理论选择行为主要有两个经济学派别,分别是理性人选择和行为经济学。尽管行为经济学在某些方面对理性人选择提出了挑战,但理性人选择仍然是群体选择行为分析的主流理论框架。本文后续内容均基于理性人选择。1. 理性人选择理论理性人选择是指经济决策的主体是充满理智的,他们对于所处环境具有完备的知识,能够找到实现目标的所有备选方案,有稳定且清晰的偏好,拥有很强的计算能力,能预测每种方案的选择后果,并依据某种衡量标准从这些方案中做出最优选择,选择的唯一目标是自身经济利益最大化。结合上文的出行案例,我们先来解释什么是理性人选择。当我们选择出行方式时,首先确认每种交通方式的重要属性(行程外耗时、行程中耗时、行程花费、舒适性)、自身属性(家庭收入、出行人数)、客观因素(天气);然后基于这些信息为每个方案计算一个偏好值并排序;最终选择偏好值最大的选项。如果选择了自驾车,那么说明综合多种因素,自驾是最能获得满足感的出行方式 。2. 效用理论消费者内心的满足感其实可以用一个经济学的词汇来表示,即“效用”。依照每种选择方案的“效用”排序进行选择的过程叫作“效用最大化”,这就是理性人选择理论最常用的准则,学术上的描述是当消费者面对一系列备选商品的时候,他们会清楚地计算每个商品的效用,并严格将所有商品按照效用排序,选择效用最大化的商品。读到这里你也许会有疑问,尽管我们认同选择时确实是基于理性人选择理论,但如此抽象的理论怎样才能在实际的数据分析中发挥作用呢?哪怕知道了影响选择行为的因素,也无法得出效用的计算公式。此时,我们需要继续学习揭示性偏好理论。3. 揭示性偏好理论揭示性偏好理论由美国经济学家保罗·安东尼·萨缪尔森提出。该理论表明:可以结合消费者历史消费行为分析消费者偏好,通过统计分析的方式得到相关因素的量化影响。该理论有以下两个重要假设

  1. 消费者在进行实际消费行为时,若从备选方案中选择了一个选项,即为首选选项,则该选项效用是最大的。
  2. 在给定的消费者预算、商品价格等因素不变的情况下,如果消费者购买了某种产品,那么他将始终做出相同的选择。

在该理论提出之初,包含的影响因素有消费者预算、商品价格以及其他商品或消费者属性。对这些因素进行归纳和拓展,再结合上述假设,形成了离散选择模型的模型框架。03 离散选择模型了解了必要的理论知识后,我们开始学习离散选择模型(Discrete Choice Models,DCM)。DCM不是单一模型,而是一个模型簇,它包含了一系列应对不同选择场景的模型,例如逻辑回归(Logistics Regression,LR)、多项Logit模型(Multinomial Logit Model,MNL)及嵌套Logit模型(Nested Logit Model,NL Model)等。如图1-3所示,DCM主要包括5个部分,分别是决策者(决策者属性)、备选项集合、备选项属性、决策准则和选择结果,数学表达形式如下。选择结果 = F(决策者, 备选项集合, 备选项属性)其中,F是决策准则,即效用最大化准则。模型最终实现的功能是在给定决策者, 备选项集合, 备选项属性后,基于效用最大化准则,得到选择结果。

腾讯数据科学家手把手教你做用户行为分析(案例:出行选择)

▲图1-3 离散选择模型的元素及结构回到旅行出行方式选择的案例中,我们对例子中的元素进行映射。

  • 决策者:一次选择行为的主体(决策者属性包括家庭收入、出行人数、天气)。
  • 备选项集合:飞机、火车、长途巴士、自驾车(不同决策者的备选项集合可以不同)。
  • 备选项属性:行程外耗时、行程中耗时、行程花费、舒适性(不同备选项的属性也可以不同)。
  • 选择准则:效用的最大化准则。
  • 选择结果:备选项中的一个选项(每个选择过程均存在选择结果)。

04 案例分析:使用逻辑回归分析自驾选择问题基于前文的介绍,相信读者已经迫不及待使用MNL或NL模型进行建模分析了,这里先从LR的实操讲起。LR是目前应用最广泛的可解释二分类模型之一,深入了解LR对我们的日常工作有很大帮助。通过对案例数据进行一定的处理,可以得到一份满足LR模型要求的宽格式数据。具体数据描述如下所示,场景逻辑如图1-5所示。

  • OBS_ID:离散,选择行为ID
  • HINC:连续,家庭收入
  • PSIZE:连续 or 离散,出行人数
  • TTME_AIR:连续,站点等待时间(飞机)
  • TTME_TRAIN:连续,站点等待时间(火车)
  • TTME_BUS:连续,站点等待时间(长途巴士)
  • INVC_AIR:连续,金钱成本(飞机)
  • INVC_TRAIN:连续,金钱成本(火车)
  • INVC_BUS:连续,金钱成本(长途巴士)
  • INVC_CAR:连续,金钱成本(自驾)
  • INVT_AIR:连续,行程中 -时间成本(飞机)
  • INVT_TRAIN:连续,行程中 -时间成本(火车)
  • INVT_BUS:连续,行程中 -时间成本(长途巴士)
  • INVT_CAR:连续,行程中 -时间成本(自驾)
  • y:离散,是否选择自驾

腾讯数据科学家手把手教你做用户行为分析(案例:出行选择)

▲图1-5 LR的场景逻辑示意图了解数据形式后,开始进行具体的模型搭建工作。第1步:软件包引入,数据读取重要的软件包在代码的备注中,如代码清单1-3所示。

  • 代码清单1-3 软件包引入及数据读取
importnumpyasnp#引入基础软件包numpyimportpandasaspd#引入基础软件包pandasimportstatsmodels.apiassm#引入Logisticregression软件包statsmodelsfromsklearn.model_selectionimporttrain_test_split#引入训练集/测试集构造工具包fromsklearnimportmetrics#引入模型评价指标AUC计算工具包importmatplotlib.pyplotasplt#引入绘图软件包importscipy#引入scipy软件包完成卡方检验#数据读入data_path='wide_data.csv'raw_data=pd.read_table(data_path,sep=',',header=0)

第2步:数据预处理数据预处理工作对于任何模型搭建都是必要的,这里结合LR及后续将介绍的MNL、NL模型的特点着重讲3个数据预处理的要点:①不要存在缺失值;②每一列均为为数值型;③多枚举值离散变量入模前要进行哑变量处理,如代码清单1-4所示。

  • 代码清单1-4 数据预处理
#1.缺失值探查&简单处理model_data.info()#查看每一列的数据类型和数值缺失情况#|RangeIndex:210entries,0to209#|Datacolumns(total9columns):#|...#|HINC210non-nullint64#|...model_data=model_data.dropna()#缺失值处理——删除model_data=model_data.fillna(0)#缺失值处理——填充(零、均值、中位数、预测值等)#2.数值型核查(连续变量应为int64或float数据类型)#若上一步中存在应为连续数值变量的字段为object,则执行下列代码,这里假设'HINC'存在为字符串'null'的值。importre#正则表达式工具包float_patten='^(-?\d+)(\.\d+)?$'#定义浮点数正则pattenfloat_re=re.compile(float_patten)#编译model_data['HINC'][model_data['HINC'].apply(lambdax:'not_float'iffloat_re.match(str(x))==Noneelse'float')=='not_float']#查看非浮点型数据#|2null#|Name:distance,dtype:objectmodel_data=model_data[model_data['HINC']!='null']model_data['HINC']=model_data['HINC'].astype(float)

第3步:单变量分析在建模之前需要先对每个自变量进行单变量分析,确定是否纳入模型,变量分为离散变量和连续变量两种,其分析方式也有所不同。对于离散变量,我们使用k-1自由度的卡方检验,其中k为离散变量的值个数;对于连续变量,比较简单的分析方法是直接对单变量进行逻辑回归,查看回归系数的显著性,根据AUC分析自变量对y的解释能力。保留显著的自变量进入到后续的操作,如代码清单1-5所示。

  • 代码清单1-5 单变量分析
#离散变量分析crosstab=pd.crosstab(model_data['y'],model_data['PSIZE'])p=scipy.stats.chi2_contingency(crosstab)[1]print("PSIZE:",p)#PSIZE:0.0024577358937625327#连续变量分析logistic=sm.Logit(model_data['y'],model_data['INVT_CAR']).fit()p=logistic.pvalues['INVT_CAR']y_predict=logistic.predict(model_data['INVT_CAR'])AUC=metrics.roc_auc_score(model_data['y'],y_predict)result='INVT_CAR:'+str(p)+'AUC:'+str(AUC)print(result)#INVT_CAR:2.971604856310474e-09AUC:0.6242563699629587

第4步:共线性检验由于LR模型是一种广义线性模型,变量间严重的共线性会对参数估计的准确性及泛化能力产生影响,因此需要对自变量间的共线性进行分析。若vif值大于10,可认为变量间具有很强的共线性,需要进行相应的处理,最简单的处理方式就是进行自变量剔除,保留单变量分析中AUC最大的变量。共线性检验示例如代码清单1-6所示。

  • 代码清单1-6 共线性检验
fromstatsmodels.stats.outliers_influenceimportvariance_inflation_factor#共线性诊断包X=raw_data[['INVT_AIR','INVT_TRAIN','INVT_BUS','INVT_CAR']]vif=pd.DataFrame()vif['VIFFactor']=[variance_inflation_factor(X.values,i)foriinrange(X.shape[1])]vif['features']=X.columnsprint('================多重共线性==============')print(vif)#|014.229424INVT_AIR#|172.782420INVT_TRAIN#|280.279742INVT_BUS#|335.003438INVT_CAR

第5步:模型搭建这里需要注意的是,对于3值及以上的离散变量要进行哑变量处理(需要记住去掉的枚举值),并且增加截距项Intercept,同时进行训练集和测试集的拆分(目的是防止模型的过拟合,确定分析结论可以泛化),代码如清单1-7所示。

  • 代码清单1-7 搭建LR模型
#建模数据构造X=model_data[['HINC','PSIZE','TTME_TRAIN','INVC_CAR']]y=raw_data['y']#哑变量处理dummies=pd.get_dummies(X['PSIZE'],drop_first=False)dummies.columns=['PSIZE'+'_'+str(x)forxindummies.columns.values]X=pd.concat([X,dummies],axis=1)X=X.drop('PSIZE',axis=1)#删去原离散变量X=X.drop('PSIZE_4',axis=1)#删去过于稀疏字段X=X.drop('PSIZE_5',axis=1)#删去过于稀疏字段X=X.drop('PSIZE_6',axis=1)#删去过于稀疏字段X['Intercept']=1#增加截距项#训练集与测试集的比例为80%和20%X_train,X_test,y_train,y_test=train_test_split(X,y,train_size=0.8,random_state=1234)#建模logistic=sm.Logit(y_train,X_train).fit()print(logistic.summary2())#重要返回信息#|------------------------------------------------------------------#|Coef.Std.Err.zP>|z|[0.0250.975]#|------------------------------------------------------------------#|HINC0.02640.01002.64770.00810.00680.0459#|TTME_TRAIN0.03890.01951.99160.04640.00060.0772#|INVC_CAR-0.05120.0204-2.51030.0121-0.0913-0.0112#|PSIZE_1-0.30770.7317-0.42060.6741-1.74191.1264#|PSIZE_2-1.08000.6417-1.68290.0924-2.33780.1778#|PSIZE_3-0.75850.7582-1.00040.3171-2.24440.7275#|Intercept-1.88791.1138-1.69510.0901-4.07080.2950#|=================================================================#模型评价print("========训练集AUC========")y_train_predict=logistic.predict(X_train)print(metrics.roc_auc_score(y_train,y_train_predict))print("========测试集AUC========")y_test_predict=logistic.predict(X_test)print(metrics.roc_auc_score(y_test,y_test_predict))#|========训练集AUC========#|0.7533854166666667#|========测试集AUC========#|0.6510263929618768

第6步:模型修正可以看到由于不显著变量的影响,模型的测试集AUC与训练集AUC存在较大差异,我们需要对不显著变量进行剔除。可以看到,新建模型的拟合优度尚可(AUC接近0.75),且自变量显著(p < 0.05),可以进行后续解读,如代码清单1-8所示。

  • 代码清单1-8 修正LR模型
X=X.drop('PSIZE_1',axis=1)X=X.drop('PSIZE_2',axis=1)X=X.drop('PSIZE_3',axis=1)#训练集与测试集的比例为80%和20%X_train,X_test,y_train,y_test=train_test_split(X,y,train_size=0.8,random_state=1234)#建模logistic=sm.Logit(y_train,X_train).fit()print(logistic.summary2())#重要返回信息#|------------------------------------------------------------------#|Coef.Std.Err.zP>|z|[0.0250.975]#|------------------------------------------------------------------#|HINC0.02660.00962.77310.00560.00780.0454#|TTME_TRAIN0.03350.01612.08380.03720.00200.0650#|INVC_CAR-0.04500.0168-2.68050.0074-0.0778-0.0121#|Intercept-2.34860.8275-2.83840.0045-3.9704-0.7269#|=================================================================print("========训练集AUC========")y_train_predict=logistic.predict(X_train)print(metrics.roc_auc_score(y_train,y_train_predict))print("========测试集AUC========")y_test_predict=logistic.predict(X_test)print(metrics.roc_auc_score(y_test,y_test_predict))#|========训练集AUC========#|0.7344618055555555#|========测试集AUC========#|0.7419354838709677

第7步:模型解读DCM模型解读的对象可以分为概率(probability)和几率(odds)。在本例中,概率为“选择自驾的概率”,几率为“选择自驾的概率/不选择自驾的概率”。限于模型的数学性质,无法直接从模型参数中快速得到概率,需要经过一定计算,这部分会在复杂的MNL及NL模型中介绍。得益于LR的数学性质,分析师可以基于模型参数直接对几率进行解读(这一点类似于线性回归)。模型解读的话术为“在其他条件保持不变的情况下,某因素增长一个单位(或属性a相对属性b),几率会变化(增长或降低)多少”,计算公式如下。

  • 连续变量:odd(xi+1)/odd(xi)-1=exp(βi)-1
  • 离散变量:odd(xj=1)/odd(xj=0)-1=exp(βj)-1

例如,根据模型可知,在其他条件保持不变的情况下,家庭收入增长1个单位,选择自驾的odds会变化,exp(β“HINC” )-1=exp(0.0266)-1=0.027,即增加0.027倍。在其他条件保持不变的情况下,自驾成本上升1个单位,选择自驾的odds会变化exp(β“INVC_CAR” )-1=exp(-0.0450)-1=-0.044,即下降0.044倍。关于作者:周银河,现任腾讯数据科学家,曾任滴滴数据科学家,清华大学商学院及哥伦比亚大学商学院商业分析硕士项目指导嘉宾。拥有丰富的数据分析、统计建模及实验设计经验。本文摘编自《数据科学工程实践:用户行为分析与建模、A/B实验、SQLFlow》,经出版方授权发布。

原文始发于微信公众号(大数据DT)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK