diff --git a/src/views/portraitModel/components/AARRRAnalysis.vue b/src/views/portraitModel/components/AARRRAnalysis.vue index 0c002d7..61e5014 100644 --- a/src/views/portraitModel/components/AARRRAnalysis.vue +++ b/src/views/portraitModel/components/AARRRAnalysis.vue @@ -84,6 +84,10 @@ https://help.fanruan.com/finebi5.1/doc-view-1256.html" +
+ X + +

2、哪种渠道的获客质量最高:

@@ -93,6 +97,10 @@ https://help.fanruan.com/finebi5.1/doc-view-1256.html" +
+ X + +
提交
@@ -125,12 +133,20 @@ https://help.fanruan.com/finebi5.1/doc-view-1256.html" +
+ X + +

2、需要重点分析哪个月的激活率:

+
+ X + +
提交
@@ -172,6 +188,10 @@ https://help.fanruan.com/finebi5.1/doc-view-1256.html" +
+ X + +

2、从哪个时间段开始留存下来的客户,是公司的忠诚用户:

@@ -180,6 +200,10 @@ https://help.fanruan.com/finebi5.1/doc-view-1256.html" +
+ X + +
提交
@@ -216,15 +240,27 @@ https://help.fanruan.com/finebi5.1/doc-view-1256.html"

低活跃用户:

- + % +
+ X + +

普通用户:

- + % +
+ X + +

会员用户:

- + % +
+ X + +
@@ -235,6 +271,10 @@ https://help.fanruan.com/finebi5.1/doc-view-1256.html" +
+ X + +
提交
@@ -278,6 +318,10 @@ https://help.fanruan.com/finebi5.1/doc-view-1256.html"

该买菜app的K值为:(计算结果保留两位小数)

+
+ X + +
@@ -303,6 +347,7 @@ import { downBlobFile } from "@/utils/index.js"; import * as echarts from "echarts"; const { proxy } = getCurrentInstance(); const baseUrl = import.meta.env.VITE_APP_BASE_API; +const showAnswerFlag = ref(false); const knowledgeHtml = ref( `

从事市场营销工作必须建立相关的理论知识体系,才能从更好地理解市场环境、消费者行为和竞争态势等复杂因素,制定出更有效的营销策略和指导具体的营销实践工作,取得更佳的营销效果。

营销理论模型使用特定的框架或图形来表述相关理论,其结构化、可视化的特点让我们能够更好地理解和掌握理论,为理解和分析复杂的问题、预测市场趋势或消费者行为等提供了高效的思考路径,更让同业交流时能够基于模型使用相同的语言和框架来描述和解决问题,从而提高协作效率和减少理解偏差,这些都有助于提升营销工作的效率和帮助营销人实现持续成长。

因此,掌握营销理论模型对于营销专业人员来说非常重要。

市场营销学科发展至今已经总结提炼了大量的理论模型,并在营销实践中被持续精进完善,像是STP、波特五力、SWOT、4Ps、AIDA、AISAS、AARRR等理论模型早已为资深从业者耳熟能详和熟练运用

但这些模型的具体含义是什么和如何使用,对于从业新人或过往忽视理论的朋友来说还是相当陌生,在公众号后台和知乎上有不少朋友在向我提问。

此前,我已经在文章中介绍过STP、品牌生命周期、商业模式画布、消费者旅程等相关理论模型,打算在之后的文章中继续分享一些其他常用的营销理论模型,也期待与感兴趣的朋友交流。

今天就让我们一起来了解下AARRR模型(海盗模型和增长黑客模型)。

一、什么是AARRR模型?

AARRR模型的实质是一个用户生命周期模型,关注用户获取(Acquisition)、激活(Activation)、留存(Retention)、收入(Revenue)和自传播(Refer)这五个方面,描述了用户从了解一个产品或服务到成为忠实用户的整个过程,对应于产品生命周期中的五个阶段。

AARRR模型是由硅谷著名风险投资人戴夫·麦克卢尔Dave McClure于2007年提出的,也被称为海盗模型或增长黑客理论模型。

AARRR模型之所以被称为海盗模型,是因为将其对用户生命周期的开发过程形象地比喻为像海盗一样的掠夺式增长;

而AARRR模型被冠以增长黑客模型的名称,则是因为其是增长黑客(互联网时代对以数据驱动营销,以市场指导产品,通过技术化手段贯彻增长目标的人)在进行用户增长时的重要工具。

具体来看,AARRR模型包含五个关键阶段:

1、获取用户(Acquisition):通过大数据分析将消费者更感兴趣的产品推荐给用户,从而获得用户。

2、提高活跃度(Activation):通过优化传播内容、拓宽传播渠道以及提供更有情绪价值的服务等方式,提升用户的活跃度。

3、提高留存(Retention):在兴趣电商时代,留存率指的是消费者在购买某个品牌或产品后,能够继续使用并保持忠诚度的比例。对于电商平台而言,如何帮助品牌提高留存率是衡量平台吸引力和用户满意度的重要指标之一。

4、获取收入(Revenue):通过使用户有兴趣并持续保持兴趣,最终实现销售转化。

5、自传播(Refer):在新营销时代,自传播更多地代表着用户多元化的分享行为,也是品牌的营销和产品被用户认可所产生的UGC内容、朋友圈推荐以及愿意将品牌行为/产品变成自己“炫耀”的资本。

AARRR模型可以抽象为一个五级漏斗模型,如下图:

image.png

要注意的是,市场营销还经常会使用AIDA模型(Attention、Interest、Desire、Action)和AISAS模型(Attention、Interest、Search、、Action、Share),我认为它们与AARRR模型都是描述用户行为和购买过程的模型,只不过是从不同视角出发的一体两面:AIDA模型和AISAS模型是站在用户视角强调其行动,而AARRR模型是站在产品视角强调通过合适手段去调动用户的行动。

营销理论没有绝对的对与错,在实践工作中我们可以根据实际情况切换不同视角,把这些模型结合起来灵活应用。

二、为何AARRR模型对于营销工作非常重要?

互联网时代,大量软件产品服务涌现,AARRR模型被增长黑客和运营人员应用来推动产品用户的增长和商业变现,取得了相当不错的成绩,也因此被市场营销人员所注意,应用到更广泛领域的市场营销实践工作中。

随着工业生产能力不断提升、信息技术快速发展,品牌竞争日益激烈、媒介传播环境充斥着无限的诱惑和巨大噪声,为了保持领先地位并实现持续增长,品牌需要紧紧地抓住客户、强化其忠诚度,并追求商业变现、用户忠诚、品牌建设之间的均衡发展,AARRR模型则为我们提供了有益的思考框架和清晰的可执行路径。

AARRR模型提供了一个全面的视角,描述了用户生命周期对应品牌增长的每一个关键环节,通过深入了解用户需求和市场趋势,品牌可以制定不同阶段的有针对性的策略,提高用户留存率、转化率和满意度,以实现在保持快速用户增长的同时,做好商业变现和品牌建设的平衡,更充分地挖掘用户全生命周期的价值。

数据分析在现代营销中扮演着至关重要的角色,AARRR模型强调了数据在每个增长阶段中的核心地位,通过数据分析企业可以深入了解用户行为、制定营销策略、跟踪和评估营销工作效果并进行持续的调整优化,这有利于并提高营销资源的使用效率和增加营销活动的成功率。

此外,AARRR模型站在产品发展的视角去调动用户,强调了用户体验在品牌增长中的关键作用。从初次接触用户开始,企业就需要提供令人印象深刻的第一印象并持续提供良好的用户体验,再以此去驱动研发设计、生产制造等部门不断升级产品服务和提升品质,驱动客服、营销、销售等人员强化互动沟通和优化服务体验,以确保用户满意从而挖掘其潜藏的商业价值。

三、如何运用AARRR模型来优化营销工作?

AARRR模型为我们提供了一个思考的框架和执行路径,但具体如何运用这一模型还需要根据实际情况而定,但一般来说在不同阶段可以从以下方面着手:

1、获取Acquisition——吸引尽可能多的潜在用户接触品牌。

但这并不是意味着盲目地在各种传播渠道进行大声量的传播和高频大体量的活动,而是要基于调研精准定位潜在用户后再集中资源渗透。

首先,品牌要进行市场研究和用户调查,了解目标用户是谁、他们在哪里以及他们的需求和兴趣是什么;

然后,品牌要根据收集到的信息制定用户获取策略,包括选择合适的渠道和推广方式,例如社交媒体广告、搜索引擎优化(SEO)、内容营销、合作伙伴关系等,来吸引潜在用户进入品牌或产品;

此外,品牌要定期评估获取策略的效果,并根据数据进行调整和优化,而效果评估可以关注获取成本(CAC)、用户来源和转化率等指标。

2、激活Activation——引导用户使用产品和全面了解品牌。

为此,品牌需要降低使用门槛、消除接触障碍,并提供优秀的用户体验。

品牌要以合适的方式唤醒客户的注意,并提供易于使用的界面、优秀的客户服务、明确的使用引导、有趣的互动体验等来满足用户需求和期望。

例如,品牌可以在营销活动中手机用户的手机号或引导其注册APP、关注公众号、添加工作人员微信,这可以通过提供免费的试用样品或者优惠券来实现,后续通过短信、公众号消息、微信沟通或电话来引导其深入使用,为了调动其积极性可以提供优惠券、运用会员机会体系或策划互动活动等。

3、保留Retention——使用户继续使用你的产品或服务,保持和提升其忠诚度,

为此,品牌需要定期更新产品、提供新的功能和服务,以满足用户的需求和期望,保持用户的兴趣和参与度,并建立优质的客户服务体系,及时回应用户的问题和反馈,通过专业、友好的客户服务提高用户忠诚度;

其次,品牌可以通过邮件、通知、活动等方式与用户保持长期的联系和互动也可以尝试建立有效的激励制度,例如积分、等级、优惠券等,以激励用户更频繁地使用产品或服务;

此外,品牌也可以建立用户社区,鼓励用户之间的互动和交流和更好地了解用户需求和反馈,强化他们对品牌文化的认可、参与产品服务的开发和升级、增加用户粘性和品牌忠诚度。

4、收益Revenue——制定和优化定价策略,并提供便捷的支付方式,让用户愿意也容易为产品服务付费。

在定价策略上,企业需要综合考虑多种因素,以确保价格与产品或服务的价值相匹配并具有竞争力,例如价值定价(确保价格与用户感知的价值相匹配)、市场比较定价(根据竞争对手的价格来设定自己的价格,以提供更具竞争力的定价)、差别定价(根据不同的用户群体、产品版本或服务等级来设定不同的价格),从而满足不同用户的需求和期望,提升其付费的意愿。

同时,企业需要选择合适的付费模式以吸引和满足用户的需求。例如,存储和在线办公套件等频繁使用的服务可以采取按月或按年付费的订阅模式,既为用户提供灵活的付费选择的同时又保证企业的持续收益;软件和游戏等用户一次性付费即可永久使用的产品可以采用买断模式,通过提供永久的使用权增加付费购买意愿;也可以采用“免费+增值”模式是基础功能免费,高级功能收费的模式,例如如广告免费、无广告收费的区别服务模式,在保证大用户基础的同时促使用户付费享受更高品质的服务。

此外,品牌还要支持信用卡、支付宝、微信支付等多种支付方式,并提供清晰的支付流程说明,确保用户能够轻松完成支付;还可以开展如折扣、买一送一、捆绑销售等促销活动,吸引用户付费,充分挖掘留存用户所潜藏的商业价值。

5、推荐Refer——调懂用户推荐品牌或产品给其他人。

为了激励用户推荐品牌或产品给其他人,企业需要提供优秀的用户体验,让用户对产品或服务满意并产生推荐意愿,并建立有效的推荐机制,如推荐奖励、分享功能等来激励用户积极参与推荐活动。

此外,品牌要善于利用社交媒体和口碑营销来进一步扩大品牌的知名度和影响力,例如策划有奖互动活动来引导老用户参与和吸引更多潜在用户的关注和信任,并通过建立话题标签或品牌专区来沉淀相关的传播内容,以实现更长期的可持续的品牌影响。

四、结语

AARRR模型提供了一个全面且系统的营销框架,旨在指导品牌更好地理解用户并与其建立长期关系。本模型关注用户全生命周期,通过获取、激活、留存、收入和推荐来吸引更多潜在用户、提高用户满意度和忠诚度、增加收益、扩大影响力,并最终实现持续的增长和成功。

因此,理解和运用AARRR模型对于品牌的长期发展至关重要。这需要品牌不仅关注单一的销售或推广活动,而要从更高层次的视角和更长时间周期来看待与用户的关系,并以数据分析驱动精准高效的营销活动,在用户生命周期的不同阶段实现相应的营销目标。

` ); @@ -1116,6 +1161,7 @@ const submitData = () => { }) .then((res) => { proxy.$modal.msgSuccess("提交成功"); + showAnswerFlag.value = true; }) .catch((error) => {}); }; diff --git a/src/views/portraitModel/components/abcAnalysis.vue b/src/views/portraitModel/components/abcAnalysis.vue index c64cd08..cf521ab 100644 --- a/src/views/portraitModel/components/abcAnalysis.vue +++ b/src/views/portraitModel/components/abcAnalysis.vue @@ -64,7 +64,13 @@ @@ -122,17 +128,29 @@ }" > - + - + @@ -176,11 +194,17 @@ @@ -199,30 +223,54 @@
提交
- - - - - - - - - - - - - - - - - - - - - - - - +
+ + + + + + +
+ X + +
+
+
+ + + + + + +
+ X + +
+
+
+ + + + + + +
+ X + +
+
+
+ + + + + + +
+ X + +
+
@@ -280,6 +328,7 @@ import * as portraitModel from "@/api/portraitModel"; import { downBlobFile } from "@/utils/index.js"; const { proxy } = getCurrentInstance(); const baseUrl = import.meta.env.VITE_APP_BASE_API; +const showAnswerFlag = ref(false); const dialogVisible = ref(false); const knowledgeFlag = ref(false); const errorNum = ref(0); @@ -653,15 +702,27 @@ const step1Submit = () => { } if (step1Data.value[0].params && step1Data.value[0].params !== "5900") { step1Error.value++; + step1Data.value[0].isError = true; + } else { + step1Data.value[0].isError = false; } if (step1Data.value[1].params && step1Data.value[1].params !== "600") { step1Error.value++; + step1Data.value[1].isError = true; + } else { + step1Data.value[1].isError = false; } if (step1Data.value[2].params && step1Data.value[2].params !== "1100") { step1Error.value++; + step1Data.value[2].isError = true; + } else { + step1Data.value[2].isError = false; } if (step1Data.value[3].params && step1Data.value[3].params !== "2400") { step1Error.value++; + step1Data.value[3].isError = true; + } else { + step1Data.value[3].isError = false; } console.log(step1Error.value, "错误数"); proxy.$modal.msgSuccess("提交成功"); @@ -698,27 +759,51 @@ const step3Submit = () => { } if (step3Data.value[0].params1 && step3Data.value[0].params1 !== "59") { step3Error.value++; + step3Data.value[0].isError1 = true; + } else { + step3Data.value[0].isError1 = false; } if (step3Data.value[0].params2 && step3Data.value[0].params2 !== "59") { step3Error.value++; + step3Data.value[0].isError2 = true; + } else { + step3Data.value[0].isError2 = false; } if (step3Data.value[1].params1 && step3Data.value[1].params1 !== "24") { step3Error.value++; + step3Data.value[1].isError1 = true; + } else { + step3Data.value[1].isError1 = false; } if (step3Data.value[1].params2 && step3Data.value[1].params2 !== "83") { step3Error.value++; + step3Data.value[1].isError2 = true; + } else { + step3Data.value[1].isError2 = false; } if (step3Data.value[2].params1 && step3Data.value[2].params1 !== "11") { step3Error.value++; + step3Data.value[2].isError1 = true; + } else { + step3Data.value[2].isError1 = false; } if (step3Data.value[2].params2 && step3Data.value[2].params2 !== "94") { step3Error.value++; + step3Data.value[2].isError2 = true; + } else { + step3Data.value[2].isError2 = false; } if (step3Data.value[3].params1 && step3Data.value[3].params1 !== "6") { step3Error.value++; + step3Data.value[3].isError1 = true; + } else { + step3Data.value[3].isError1 = false; } if (step3Data.value[3].params2 && step3Data.value[3].params2 !== "100") { step3Error.value++; + step3Data.value[3].isError2 = true; + } else { + step3Data.value[3].isError2 = false; } console.log("错误数", step3Error.value); proxy.$modal.msgSuccess("提交成功"); @@ -745,15 +830,27 @@ const step4Submit = () => { } if (step4Data.value[0].params && step4Data.value[0].params !== "A类商品") { step4Error.value++; + step4Data.value[0].isError = true; + } else { + step4Data.value[0].isError = false; } if (step4Data.value[1].params && step4Data.value[1].params !== "B类商品") { step4Error.value++; + step4Data.value[1].isError = true; + } else { + step4Data.value[1].isError = false; } if (step4Data.value[2].params && step4Data.value[2].params !== "C类商品") { step4Error.value++; + step4Data.value[2].isError = true; + } else { + step4Data.value[2].isError = false; } if (step4Data.value[3].params && step4Data.value[3].params !== "C类商品") { step4Error.value++; + step4Data.value[3].isError = true; + } else { + step4Data.value[3].isError = false; } console.log("错误数", step4Error.value); proxy.$modal.msgSuccess("提交成功"); @@ -903,6 +1000,7 @@ const submitData = () => { }) .then((res) => { proxy.$modal.msgSuccess("提交成功"); + showAnswerFlag.value = true; }) .catch((error) => {}); }; @@ -1007,7 +1105,7 @@ defineExpose({ width: 945px; height: 26px; // background: #003b75; - background: #FFF8EE; + background: #fff8ee; border-radius: 10px; // border: 1px solid #0052a3; font-size: 12px; @@ -1017,11 +1115,12 @@ defineExpose({ } } .chartXData { + display: flex; position: relative; top: -58px; - left: 60px; + left: 50px; .XdataItem { - margin-right: 15px; + margin-left: 10px; } } } diff --git a/src/views/portraitModel/components/basketAnalysis.vue b/src/views/portraitModel/components/basketAnalysis.vue index 75abc62..6714aaa 100644 --- a/src/views/portraitModel/components/basketAnalysis.vue +++ b/src/views/portraitModel/components/basketAnalysis.vue @@ -85,6 +85,10 @@ - +
+ X + +
@@ -115,6 +119,10 @@
@@ -148,18 +156,30 @@ @@ -198,6 +218,10 @@ +
+ X + +
@@ -243,6 +267,8 @@ import { downBlobFile } from "@/utils/index.js"; import { onBeforeUnmount, onMounted } from "vue"; const { proxy } = getCurrentInstance(); const baseUrl = import.meta.env.VITE_APP_BASE_API; +const showAnswerFlag = ref(false); +const comListError = ref(false); const knowledgeHtml = ref( `

一、理解购物篮分析

购物篮分析是指通过分析消费者在电商平台上的购物数据,了解他们购买商品之间的关联性,从而发现潜在的消费行为和需求,为电商平台提供决策支持。通过购物篮分析,电商平台可以更好地理解用户的购物习惯和偏好,从而为用户提供更加精准的推荐和产品布局。

购物篮分析的关键衡量指标有三个:支持度、置信度、提升度

为了更好地解释这三个指标,这里我先跟大家举个例子,后续就用这个例子说明。

某超市30天订单数一共10000单,其中包含A商品的订单有600单,包含B商品的订单有400单,同时包含A和B两种商品的订单有300单。

购买A商品的概率 P(A)=(600/10000)*100%=6%

购买B商品的概率 P(B)=(400/10000)*100%=4%

同时购买A商品和B商品的概率 P(A∩B)=(300/10000)*100%=3%

1.支持度

支持度是指A和B两个商品同时被购买的概率,代表了这个组合的可靠程度。

AB组合的支持度=同时包含A和B商品的订单数/总订单数*100%

在本例中,AB组合的支持度=P(A∩B)=(300/10000) *100%=3%

2.置信度

置信度是指购买A之后又购买了B的条件概率,是买了A和B的订单占所有买了A的订单里的占比。代表买了A的用户有多大概率会再买B,既买A产品对B产品产生了多大的影响。

A对B的置信度=同时包含A和B商品的订单数/包含A商品的订单数*100%

在本例中,A对B的置信度=P(A∩B)/P(A)=(300/600)*100%=50%

3.提升度

A对B提升度=A对B的置信度/P(B),是指在购买A产品这个条件下购买B产品的可能性与没有这个条件下购买B 产品的可能性之比。

它的计算方法是:A对B的置信度/P(B)。提升度和置信度一样,也是一个条件概率。

    当置信度>P(B)时,A对B的提升度>1,则表示买A再买B的概率大于本身买B的概率,就表示买A对买B带来了提升效果。

    当置信度<P(B)时,A对B的提升度<1,则表示买A再买B的概率小于本身买B的概率,就表示买A对买B带来了负向效果。

    当置信度等于P(B)时,A对B的提升度=1,则代表买A对买B没有影响。

在本例中,A对B的提升度=A对B的置信度/P(B)=50%/4%=12.5,表示商品A对商品B有较大的提升,有较大的搭配价值,建议搭配。

二、利用购物篮分析优化产品推荐

1. 推荐算法优化:根据用户的历史购物数据,结合用户画像和行为数据,制定更加精准的推荐算法。通过分析用户的购买行为,了解他们的购物习惯和偏好,为不同的用户提供个性化的推荐。

2. 动态推荐:根据用户在购物过程中的实时行为,实时调整推荐结果,确保推荐内容与用户需求高度匹配。

3. 推荐内容丰富度:除了商品推荐外,还可以考虑推荐相关服务、优惠券、套餐等,增加用户购物的丰富度和满意度。

三、利用购物篮分析优化产品布局

1. 商品分类优化:根据用户的购物习惯和偏好,对商品进行分类和布局,提高用户在搜索和浏览过程中的便利性。

2. 突出热销商品:通过分析用户的购买数据,了解哪些商品最受用户欢迎,将热销商品放在更加显眼的位置,提高用户的点击率和购买率。

3. 季节性商品布局:根据季节变化,提前布局相关季节性商品,提高用户在特定季节的购买欲望。

四、利用购物篮分析提升客户服务体验

1. 客户反馈处理:通过购物篮分析,了解用户对哪些商品、服务和功能存在不满,及时调整和优化,提高用户满意度。

2. 售后服务优化:针对购买后可能出现的问题和售后需求,提前做好应对措施和解决方案,提高用户的售后服务体验。

3. 个性化客服:针对不同用户的购物习惯和偏好,提供个性化的客服服务,提高用户对电商平台的信任度和忠诚度。

五、利用购物篮分析进行数据驱动的营销策略

1. 优惠券策略:根据用户的购物数据和习惯,制定个性化的优惠券策略,提高用户的购买意愿和转化率。

2. 组合营销:针对用户的购买行为和需求,制定有针对性的组合营销策略,提高用户的购买量和忠诚度。

3. 社交媒体推广:通过社交媒体平台,利用购物篮分析结果进行精准推广,提高品牌知名度和用户参与度。


` ); @@ -510,6 +536,9 @@ const step1Submit = () => { // console.log(isArrayContained(list.value, combinationRight.value)); // 输出:true if (!isArrayContained(list.value, combinationRight.value)) { step1Error.value = 1; + comListError.value = true; + } else { + comListError.value = false; } console.log("错误数", step1Error.value); proxy.$modal.msgSuccess("提交成功"); @@ -530,15 +559,27 @@ const step2Submit = () => { } if (step2Data.value[0].params && step2Data.value[0].params !== "60") { step2Error.value++; + step2Data.value[0].isError = true; + } else { + step2Data.value[0].isError = false; } if (step2Data.value[1].params && step2Data.value[1].params !== "60") { step2Error.value++; + step2Data.value[1].isError = true; + } else { + step2Data.value[1].isError = false; } if (step2Data.value[2].params && step2Data.value[2].params !== "80") { step2Error.value++; + step2Data.value[2].isError = true; + } else { + step2Data.value[2].isError = false; } if (step2Data.value[3].params && step2Data.value[3].params !== "60") { step2Error.value++; + step2Data.value[3].isError = true; + } else { + step2Data.value[3].isError = false; } console.log(step2Error.value, "错误数"); proxy.$modal.msgSuccess("提交成功"); @@ -555,57 +596,111 @@ const step3Submit = () => { } if (step3Data.value[0].params1 && step3Data.value[0].params1 !== "40" && step3Data.value[0].params1 !== "40.00") { step3Error.value++; + step3Data.value[0].isError1 = true; + } else { + step3Data.value[0].isError1 = false; } if (step3Data.value[0].params2 && step3Data.value[0].params2 !== "66.67") { step3Error.value++; + step3Data.value[0].isError2 = true; + } else { + step3Data.value[0].isError2 = false; } if (step3Data.value[0].params3 && step3Data.value[0].params3 !== "111.11") { step3Error.value++; + step3Data.value[0].isError3 = true; + } else { + step3Data.value[0].isError3 = false; } if (step3Data.value[1].params1 && step3Data.value[1].params1 !== "20" && step3Data.value[1].params1 !== "20.00") { step3Error.value++; + step3Data.value[1].isError1 = true; + } else { + step3Data.value[1].isError1 = false; } if (step3Data.value[1].params2 && step3Data.value[1].params2 !== "33.33") { step3Error.value++; + step3Data.value[1].isError2 = true; + } else { + step3Data.value[1].isError2 = false; } if (step3Data.value[1].params3 && step3Data.value[1].params3 !== "41.67") { step3Error.value++; + step3Data.value[1].isError3 = true; + } else { + step3Data.value[1].isError3 = false; } if (step3Data.value[2].params1 && step3Data.value[2].params1 !== "40" && step3Data.value[2].params1 !== "40.00") { step3Error.value++; + step3Data.value[2].isError1 = true; + } else { + step3Data.value[2].isError1 = false; } if (step3Data.value[2].params2 && step3Data.value[2].params2 !== "60.00" && step3Data.value[2].params2 !== "60") { step3Error.value++; + step3Data.value[2].isError2 = true; + } else { + step3Data.value[2].isError2 = false; } if (step3Data.value[2].params3 && step3Data.value[2].params3 !== "100.00" && step3Data.value[2].params3 !== "100") { step3Error.value++; + step3Data.value[2].isError3 = true; + } else { + step3Data.value[2].isError3 = false; } if (step3Data.value[3].params1 && step3Data.value[3].params1 !== "20" && step3Data.value[3].params1 !== "20.00") { step3Error.value++; + step3Data.value[3].isError1 = true; + } else { + step3Data.value[3].isError1 = false; } if (step3Data.value[3].params2 && step3Data.value[3].params2 !== "33.33") { step3Error.value++; + step3Data.value[3].isError2 = true; + } else { + step3Data.value[3].isError2 = false; } if (step3Data.value[3].params3 && step3Data.value[3].params3 !== "41.67") { step3Error.value++; + step3Data.value[3].isError3 = true; + } else { + step3Data.value[3].isError3 = false; } if (step3Data.value[4].params1 && step3Data.value[4].params1 !== "20" && step3Data.value[4].params1 !== "20.00") { step3Error.value++; + step3Data.value[4].isError1 = true; + } else { + step3Data.value[4].isError1 = false; } if (step3Data.value[4].params2 && step3Data.value[4].params2 !== "33.33") { step3Error.value++; + step3Data.value[4].isError2 = true; + } else { + step3Data.value[4].isError2 = false; } if (step3Data.value[4].params3 && step3Data.value[4].params3 !== "55.56") { step3Error.value++; + step3Data.value[4].isError3 = true; + } else { + step3Data.value[4].isError3 = false; } if (step3Data.value[5].params1 && step3Data.value[5].params1 !== "40" && step3Data.value[5].params1 !== "40.00") { step3Error.value++; + step3Data.value[5].isError1 = true; + } else { + step3Data.value[5].isError1 = false; } if (step3Data.value[5].params2 && step3Data.value[5].params2 !== "50.00" && step3Data.value[5].params2 !== "50") { step3Error.value++; + step3Data.value[5].isError2 = true; + } else { + step3Data.value[5].isError2 = false; } if (step3Data.value[5].params3 && step3Data.value[5].params3 !== "83.33") { step3Error.value++; + step3Data.value[5].isError3 = true; + } else { + step3Data.value[5].isError3 = false; } console.log(step3Error.value, "错误数"); proxy.$modal.msgSuccess("提交成功"); @@ -623,21 +718,39 @@ const step4Submit = () => { } if (step4Data.value[0].params && step4Data.value[0].params !== "提升效果") { step4Error.value++; + step4Data.value[0].isError = true; + } else { + step4Data.value[0].isError = false; } if (step4Data.value[1].params && step4Data.value[1].params !== "负向效果") { step4Error.value++; + step4Data.value[1].isError = true; + } else { + step4Data.value[1].isError = false; } if (step4Data.value[2].params && step4Data.value[2].params !== "没有影响") { step4Error.value++; + step4Data.value[2].isError = true; + } else { + step4Data.value[2].isError = false; } if (step4Data.value[3].params && step4Data.value[3].params !== "负向效果") { step4Error.value++; + step4Data.value[3].isError = true; + } else { + step4Data.value[3].isError = false; } if (step4Data.value[4].params && step4Data.value[4].params !== "负向效果") { step4Error.value++; + step4Data.value[4].isError = true; + } else { + step4Data.value[4].isError = false; } if (step4Data.value[5].params && step4Data.value[5].params !== "负向效果") { step4Error.value++; + step4Data.value[5].isError = true; + }else{ + step4Data.value[5].isError = false; } // console.log(666); console.log(step4Error.value, "错误数"); @@ -777,6 +890,7 @@ const submitData = () => { }) .then((res) => { proxy.$modal.msgSuccess("提交成功"); + showAnswerFlag.value = true; }) .catch((error) => {}); }; @@ -912,6 +1026,7 @@ defineExpose({ margin-left: 10px; } .comList { + display: flex; ul { text-align: center; list-style-type: none; diff --git a/src/views/portraitModel/components/bostonAnalysis.vue b/src/views/portraitModel/components/bostonAnalysis.vue index e3e2a27..c40b7a2 100644 --- a/src/views/portraitModel/components/bostonAnalysis.vue +++ b/src/views/portraitModel/components/bostonAnalysis.vue @@ -68,12 +68,24 @@ @@ -102,11 +114,19 @@ @@ -128,18 +148,34 @@
绘制A
(3,800) +
+ X + +
绘制B
(4,1200) +
+ X + +
绘制C
(6,600) +
+ X + +
绘制D
(7,1400) +
+ X + +
@@ -160,6 +196,10 @@
绘制平均消费次数X,平均消费金额Y
(5,1000) +
+ X + +
+
+ X + +
@@ -136,6 +140,10 @@ % +
+ X + +
@@ -169,7 +177,7 @@ 天 +
+ X + +
- +
@@ -269,6 +285,10 @@ --> +
+ X + +
@@ -297,12 +317,20 @@ --> +
+ X + +
@@ -430,6 +458,7 @@ import { downBlobFile } from "@/utils/index.js"; import * as echarts from "echarts"; const { proxy } = getCurrentInstance(); const baseUrl = import.meta.env.VITE_APP_BASE_API; +const showAnswerFlag = ref(false); const knowledgeHtml2 = ref( `

在电商/零售数据分析中,复购数据分析是非常重要的部分。尤其是在当今新用户获取成本越来越高的今天,根据中国电子商务中心提供的公开数据显示,商家获得一个新用户的成本是维护一个老用户的 5 - 10 倍,一个满意的用户会带来至少 8 笔潜在生意,一个不满意的用户可能会影响超过 25 个人的购买意愿。

通过复购行为分析,了解用户偏向和用户习惯,优化相关产品、活动等,提高用户粘性和产品粘性,才能实现产品/业务的稳定增长。

本文我们一起看下,复购分析可以从哪些角度入手,核心指标复购率如何计算。

一、复购率是什么?

复购率通常指重复购买率,在不同业务场景下,也有各自的计算方式。常见的是从用户角度和订单角度两种。

1、用户复购率:

指一定时间段内,购买次数>1次的用户数/有过购买行为的用户总数

2、订单复购率:

指一定时间段内,重复交易订单数/交易订单总数
在实际分析中,还需要根据业务场景和需求,对于公式中的指标取值范围进行确定。

例如:

【购买次数】计算的两种方式:

a.同一天多个订单分别计算次数

b.一个客户一天产生多笔订单交易,只算一次购买

2、复购分析如何做?

影响复购率的因素通常是商品、活动、服务、用户满意度等,根据复购分析,我们也会从这些方面入手调整策略,达到提高复购、提高用户粘性的作用。
所以在进行复购分析时,我们就可以从用户、订单、产品几个角度入手进行分析。

分析工具:海致BDP个人版

数据情况:零售订单示例数据

包含字段:订单ID、用户ID、购买日期、商品ID、购买金额

1、区分首购订单 or 复购订单

要计算复购率,首先我们需要根据用户ID、订单ID和购买日期,区分每行数据订单是首购or 复购第几次
在上传的基础工作表中「添加字段」

计算公式:dense_rank()over ( partition by [用户ID] order by [购买日期],[订单ID] )

公式逻辑:这里我们使用窗口函数,按照用户ID分组,按照购买日期和订单ID进行排序,即可计算出该行订单数据是用户的第几次购买。

(这里我们将同一天,不同订单ID计为多次购买)

计算出的结果示例:

某用户在2月4日分开交易2笔订单,3月27日交易一笔,计算字段结果分别计1,2,3次

根据计算结果,可以区分首购 or 复购订单

计算后,将工作表进行一次追加合并,将窗口函数结果物化,便于后续的计算和做图。

点击右上角-创建合表,选择追加合并,添加工作表,命名后保存为表1.1

2、复购用户数&复购订单数

计算复购率, 需要先计算分子,也就是复购用户数和复购订单数

我们通过对用户ID和订单ID进行去重计数得出。

在刚刚保存的表1.1 右上角,点击新建图表,在图表编辑界面添加计算字段

复购用户数—计算公式:

count(distinct(if([区分首购订单or复购订单]=2,[用户ID],null)))

计算逻辑:复购标记字段=2的即为有过复购行为的用户,按此条件对用户ID进行去重计数,即可得出有过复购行为的用户数量。

将计算字段拖至数值栏,即可展示复购用户数

复购订单数逻辑类似,区别在于条件是:只要复购标记字段不等于1,都属于复购订单。

计算公式:count(distinct(if([区分首购订单or复购订单]<>1,[订单ID],null)))

3、用户复购率&订单复购率
已经求出复购率公式的分子后,依然在图表编辑界面,添加字段,求出复购率

用户复购率:

计算公式:[复购用户数]/count(distinct([用户ID]))

用上一步计算的复购用户数/用户ID去重计数值,即可表示用户复购率

订单复购率:

计算公式:[复购订单数]/count(distinct([订单ID]))

4、复购时间间隔

了解用户的复购周期,也是复购分析中必要的指标,这里需要计算用户复购和首次购买之间的时间间隔

在刚才的合表1.1 右上角,选择创建合表,进行追加合并,设置过滤条件,筛选出所有的复购订单,保存为表1.2

再次选择创建合表—多表关联

将表1.1作为左表,1.2作为右表,选择关联方式inner-join,关联字段为2张表的用户ID。

设置过滤条件:左表复购标记字段=1

进行字段设置,左表相关字段为首购数据字段,右表为复购数据字段

命名保存为表1.3

保存后点击添加字段,使用公式,计算两次购买时间间隔

公式:DAY_DIFF([复购购买日期],[首次购买日期])

计算结果示例:

三、复购分析-可视化

根据刚才的数据计算结果,我们可以进行可视化展示,通过可视化图表的形式,发现数据规律和问题
1、重点指标数据

使用指标卡,展示重点指标数据,还可以配合全局筛选器,筛选展示不同时间段、不同地区等指标数据

2、复购数据—时间趋势

使用表1.1,对用户复购情况,做日期维度的分析展示
图表类型:双轴图

购买用户总数为用户ID去重计数

订单复购分析类似。按照日期维度,可以按季度、按月、按周查看复购率和用户数/订单数之间的变化关系。同时监控数据健康度,理想状态下复购率应该是较为稳定的,根据数据变化,及时发现异常问题。

3、复购时间间隔分析

可以根据复购时间间隔进行分组展示,了解用户在不同时间间隔范围内,进行复购行为的占比情况

添加分组字段,根据业务需求,设置自定义步长和组别

将分组字段放置维度栏,用户ID去重计数作为数值,使用饼图/环形图展示占比情况(这里我们主要分析第二次购买与首购的时间间隔,通过筛选器控制)

也可以使用折线图,展示复购时间间隔的趋势

根据可视化图表显示,示例数据中用户在7天内产生复购行为的占比最大,其次是60天以上,说明在短时间内用户粘性最高,产生复购的可能性最大, 对于占比较小的时间间隔,可以采取相应措施对用户进行引导召回。

复购时间间隔的分析还可以下钻到具体商品,了解商品的复购周期等。

4、商品复购分析

除了用户复购和订单复购分析外,针对于商品的复购情况分析也十分重要,可以通过复购次数较多的商品,分析用户习惯和商品特征。

我们可以在表1.3中添加商品复购标记字段

公式:if([首购商品ID]=[复购商品ID],1,0)

首购商品ID=复购商品ID,即表示该用户有复购该商品行为

按照商品ID,计算商品ID计数,即查看每种商品的复购次数

还可以通过图层下钻,了解每种商品,复购的用户情况,每个用户复购的次数等

动图封面

商品的复购分析,还可以结合品类、销量、价格区间、评价等等多种维度,进行细化分析

针对用户的复购分析,还可以从新老用户的复购率、不同渠道来源用户的复购率等角度,进行拆解分析。
结合用户的RFM分析,更加详细的了解用户的消费习惯,了解商品的特征,通过复购率的变化优化我们的业务策略

` ); @@ -1403,63 +1432,123 @@ const step1Submit = () => { } if (step1Data.value[0].params && step1Data.value[0].params != "1") { step1Error.value++; + step1Data.value[0].isError = true; + } else { + step1Data.value[0].isError = false; } if (step1Data.value[1].params && step1Data.value[1].params != "2") { step1Error.value++; + step1Data.value[1].isError = true; + } else { + step1Data.value[1].isError = false; } if (step1Data.value[2].params && step1Data.value[2].params != "1") { step1Error.value++; + step1Data.value[2].isError = true; + } else { + step1Data.value[2].isError = false; } if (step1Data.value[3].params && step1Data.value[3].params != "2") { step1Error.value++; + step1Data.value[3].isError = true; + } else { + step1Data.value[3].isError = false; } if (step1Data.value[4].params && step1Data.value[4].params != "3") { step1Error.value++; + step1Data.value[4].isError = true; + } else { + step1Data.value[4].isError = false; } if (step1Data.value[5].params && step1Data.value[5].params != "1") { step1Error.value++; + step1Data.value[5].isError = true; + } else { + step1Data.value[5].isError = false; } if (step1Data.value[6].params && step1Data.value[6].params != "2") { step1Error.value++; + step1Data.value[6].isError = true; + } else { + step1Data.value[6].isError = false; } if (step1Data.value[7].params && step1Data.value[7].params != "3") { step1Error.value++; + step1Data.value[7].isError = true; + } else { + step1Data.value[7].isError = false; } if (step1Data.value[8].params && step1Data.value[8].params != "4") { step1Error.value++; + step1Data.value[8].isError = true; + } else { + step1Data.value[8].isError = false; } if (step1Data.value[9].params && step1Data.value[9].params != "1") { step1Error.value++; + step1Data.value[9].isError = true; + } else { + step1Data.value[9].isError = false; } if (step1Data.value[10].params && step1Data.value[10].params != "2") { step1Error.value++; + step1Data.value[10].isError = true; + } else { + step1Data.value[10].isError = false; } if (step1Data.value[11].params && step1Data.value[11].params != "2") { step1Error.value++; + step1Data.value[11].isError = true; + } else { + step1Data.value[11].isError = false; } if (step1Data.value[12].params && step1Data.value[12].params != "3") { step1Error.value++; + step1Data.value[12].isError = true; + } else { + step1Data.value[12].isError = false; } if (step1Data.value[13].params && step1Data.value[13].params != "4") { step1Error.value++; + step1Data.value[13].isError = true; + } else { + step1Data.value[13].isError = false; } if (step1Data.value[14].params && step1Data.value[14].params != "1") { step1Error.value++; + step1Data.value[14].isError = true; + } else { + step1Data.value[14].isError = false; } if (step1Data.value[15].params && step1Data.value[15].params != "1") { step1Error.value++; + step1Data.value[15].isError = true; + } else { + step1Data.value[15].isError = false; } if (step1Data.value[16].params && step1Data.value[16].params != "1") { step1Error.value++; + step1Data.value[16].isError = true; + } else { + step1Data.value[16].isError = false; } if (step1Data.value[17].params && step1Data.value[17].params != "1") { step1Error.value++; + step1Data.value[17].isError = true; + } else { + step1Data.value[17].isError = false; } if (step1Data.value[18].params && step1Data.value[18].params != "1") { step1Error.value++; + step1Data.value[18].isError = true; + } else { + step1Data.value[18].isError = false; } if (step1Data.value[19].params && step1Data.value[19].params != "1") { step1Error.value++; + step1Data.value[19].isError = true; + } else { + step1Data.value[19].isError = false; } console.log(step1Error.value, "错误数"); proxy.$modal.msgSuccess("提交成功"); @@ -1484,12 +1573,21 @@ const step2Submit = () => { } if (step2Data.value[0].params && step2Data.value[0].params != "10") { step2Error.value++; + step2Data.value[0].isError = true; + } else { + step2Data.value[0].isError = false; } if (step2Data.value[1].params && step2Data.value[1].params != "4") { step2Error.value++; + step2Data.value[1].isError = true; + } else { + step2Data.value[1].isError = false; } if (step2Data.value[2].params && step2Data.value[2].params != "40") { step2Error.value++; + step2Data.value[2].isError = true; + } else { + step2Data.value[2].isError = false; } console.log(step2Error.value, "错误数"); proxy.$modal.msgSuccess("提交成功"); @@ -1516,27 +1614,52 @@ const step4Submit = () => { } if (step4Data.value[0].params1 && step4Data.value[0].params1 != "22") { step4Error.value++; + step4Data.value[0].isError1 = true; + } else { + step4Data.value[0].isError1 = false; } if (step4Data.value[0].params2 && step4Data.value[0].params2 != "30天内") { step4Error.value++; + step4Data.value[0].isError2 = true; + } else { + step4Data.value[0].isError2 = false; } if (step4Data.value[2].params1 && step4Data.value[2].params1 != "10") { step4Error.value++; + step4Data.value[2].isError1 = true; + } else { + step4Data.value[2].isError1 = false; } if (step4Data.value[2].params2 && step4Data.value[2].params2 != "15天内") { step4Error.value++; + step4Data.value[2].isError2 = true; + } else { + step4Data.value[2].isError2 = false; } if (step4Data.value[4].params1 && step4Data.value[4].params1 != "4") { step4Error.value++; + step4Data.value[4].isError1 = true; + } else { + step4Data.value[4].isError1 = false; } if (step4Data.value[4].params2 && step4Data.value[4].params2 != "7天内") { step4Error.value++; + step4Data.value[4].isError2 = true; + } else { + step4Data.value[4].isError2 = false; } + if (step4Data.value[6].params1 && step4Data.value[6].params1 != "2") { step4Error.value++; + step4Data.value[6].isError1 = true; + } else { + step4Data.value[6].isError1 = false; } if (step4Data.value[6].params2 && step4Data.value[6].params2 != "7天内") { step4Error.value++; + step4Data.value[6].isError2 = true; + } else { + step4Data.value[6].isError2 = false; } console.log(step4Error.value, "错误数"); proxy.$modal.msgSuccess("提交成功"); @@ -1562,39 +1685,75 @@ const step5Submit = () => { } if (step5DataTable2.value[0].params && step5DataTable2.value[0].params != "裤子" && step5DataTable2.value[0].params != "外套") { step5Error.value++; + step5DataTable2.value[0].isError = true; + } else { + step5DataTable2.value[0].isError = false; } if (step5DataTable2.value[1].params && step5DataTable2.value[1].params != "衬衫" && step5DataTable2.value[1].params != "短袖" && step5DataTable2.value[1].params != "睡衣") { step5Error.value++; + step5DataTable2.value[1].isError = true; + } else { + step5DataTable2.value[1].isError = false; } if (step5DataTable3.value[0].params1 && step5DataTable3.value[0].params1 != "无") { step5Error.value++; + step5DataTable3.value[0].isError1 = true; + } else { + step5DataTable3.value[0].isError1 = false; } if (step5DataTable3.value[0].params2 && step5DataTable3.value[0].params2 != "0") { step5Error.value++; + step5DataTable3.value[0].isError2 = true; + } else { + step5DataTable3.value[0].isError2 = false; } if (step5DataTable3.value[1].params1 && step5DataTable3.value[1].params1 != "无") { step5Error.value++; + step5DataTable3.value[1].isError1 = true; + } else { + step5DataTable3.value[1].isError1 = false; } if (step5DataTable3.value[1].params2 && step5DataTable3.value[1].params2 != "0") { step5Error.value++; + step5DataTable3.value[1].isError2 = true; + } else { + step5DataTable3.value[1].isError2 = false; } if (step5DataTable3.value[2].params1 && step5DataTable3.value[2].params1 != "无") { step5Error.value++; + step5DataTable3.value[2].isError1 = true; + } else { + step5DataTable3.value[2].isError1 = false; } if (step5DataTable3.value[2].params2 && step5DataTable3.value[2].params2 != "0") { step5Error.value++; + step5DataTable3.value[2].isError2 = true; + } else { + step5DataTable3.value[2].isError2 = false; } if (step5DataTable3.value[3].params1 && step5DataTable3.value[3].params1 != "C") { step5Error.value++; + step5DataTable3.value[3].isError1 = true; + } else { + step5DataTable3.value[3].isError1 = false; } if (step5DataTable3.value[3].params2 && step5DataTable3.value[3].params2 != "1") { step5Error.value++; + step5DataTable3.value[3].isError2 = true; + } else { + step5DataTable3.value[3].isError2 = false; } if (step5DataTable3.value[4].params1 && step5DataTable3.value[4].params1 != "D") { step5Error.value++; + step5DataTable3.value[4].isError1 = true; + } else { + step5DataTable3.value[4].isError1 = false; } if (step5DataTable3.value[4].params2 && step5DataTable3.value[4].params2 != "2") { step5Error.value++; + step5DataTable3.value[4].isError2 = true; + } else { + step5DataTable3.value[4].isError2 = false; } console.log(step5Error.value, "错误数"); proxy.$modal.msgSuccess("提交成功"); @@ -1740,6 +1899,7 @@ const submitData = () => { }) .then((res) => { proxy.$modal.msgSuccess("提交成功"); + showAnswerFlag.value = true; }) .catch((error) => {}); // console.log(666); diff --git a/src/views/portraitModel/components/retainAnalysis.vue b/src/views/portraitModel/components/retainAnalysis.vue index c6201e4..e0c334b 100644 --- a/src/views/portraitModel/components/retainAnalysis.vue +++ b/src/views/portraitModel/components/retainAnalysis.vue @@ -87,80 +87,132 @@ @@ -196,24 +248,40 @@ @@ -235,6 +303,10 @@ +
+ X + +
分析结论:
@@ -336,6 +408,7 @@ import { downBlobFile } from "@/utils/index.js"; import * as echarts from "echarts"; const { proxy } = getCurrentInstance(); const baseUrl = import.meta.env.VITE_APP_BASE_API; +const showAnswerFlag = ref(false); const knowledgeHtml = ref( `

前言

Tableau的本质还是辅助分析、辅助工作,分析思维不可少。所以在分享Tableau技能之外,也会分享些有关分析技能的内容,统一更新入“Janie碎谈”模块中。

这篇文章是我花了好几个晚上认认真真写的,自己编造的数据,自己画的图,自己写的代码。一方面写的过程中会促使我进入更深层次的思考,边改进边学习边进步;另一方面独乐乐不如众乐乐,分享出来大家一起进步,顺便也帮我指出不足。

网上有关留存的文章很多,这篇不敢说是最全的,但最起码是较全的。由于上班加带娃,又要坚持原创,又要精细的准备每一篇干货,所以大概一周一更。如有做的不足的地方,请于后台留言,督促我改进,以分享更有价值的干货。

在这个用户为大的互联网世界中,我们一起发现更多有意思的点......

目录

  1. 互联网企业面临的留存问题
  2. 什么是留存分析
  3. 留存分析常用口径
  4. 留存分析的适用场景
  5. 留存分析参考代码
  6. 留存下降的可能性原因
  7. 留存分析方法
  8. 案例实攻

1 互联网企业面临的留存问题

  • 流量红利见顶、拉新成本高

在极易同质化的今天,流量竞争着实激烈,提高用户留存的重要性不言而喻,且存量用户的获客成本远远低于拉新成本。

  • 新用户较易流失

企业大规模投广告、做活动,高额支出锁不住新用户,长期可持续发展有些无力,只顾眼前利益治标不治本。

2 什么是留存分析

留存率:某日用户数在第N日仍启动该App的用户比例,留存分析即分析用户随时间变化的活跃情况。获取用户只是第一步,留住用户才是所有产品最终目标。

可以理解为:由初期的摇摆用户转化为忠诚&稳定用户的过程。留存率越高,说明用户对产品越有强烈的依赖感。

可分为三个阶段:

  • 初期:新用户刚注册,用户留存下降较快,需快速让用户感受到产品核心价值。
  • 中期:新用户沉淀下来,形成活跃用户。此时需分析活跃留存,加强核心功能,培养用户对产品的使用习惯。
  • 后期:思考产品核心价值,做好产品迭代与优化。

从时间维度划分:

常见的的有:次日留存、3日留存、7日留存、30日留存、周留存、月留存

从用户维度划分:

常见的的有:新用户留存、活跃留存

图解如下:

3 留存分析常用口径

以新用户留存为例

次日留存率=(某日新增的用户中,在注册的第2天还进行登录的用户数)/ 该日新增用户数

3日留存率=(某日新增用户中,在注册的第3天还进行登录的用户数)/ 该日新增用户数

7日留存率=(某日新增的用户中,在注册的第7天还进行登录的用户数)/ 该日新增用户数

30日留存率=(某日新增的用户中,在注册的第30天还进行登录的用户数)/ 该日新增用户数

1周后留存率=(某周新增的用户中,在注册的第2周还进行登录的用户数)/ 该周新增用户数

2周后留存率=(某周新增的用户中,在注册的第3周还进行登录的用户数)/ 该周新增用户数

1月后留存率=(某月新增的用户中,在注册的第2月还进行登录的用户数)/ 该月新增用户数

2月后留存率=(某月新增的用户中,在注册的第3月还进行登录的用户数)/ 该月新增用户数

以活跃留存为例

次日留存率=(某日登录的用户中,在第2天还进行登录的用户数)/ 该日登录用户数

3日留存率=(某日登录用户中,在第3天还进行登录的用户数)/ 该日登录用户数

7日留存率=(某日登录的用户中,在第7天还进行登录的用户数)/ 该日登录用户数

30日留存率=(某日登录的用户中,在第30天还进行登录的用户数)/ 该日登录用户数

1周后留存率=(某周登录的用户中,在第2周还进行登录的用户数)/ 该周登录用户数

2周后留存率=(某周登录的用户中,在第3周还进行登录的用户数)/ 该周登录用户数

1月后留存率=(某月登录的用户中,在第2月还进行登录的用户数)/ 该月登录用户数

2月后留存率=(某月登录的用户中,在第3月还进行登录的用户数)/ 该月登录用户数

4 留存分析的适用场景

日留存率

  • 快速判断产品是否迎合市场需求,比如新手对产品的UI设计、功能设置、新手引导等的体验是否满意,是否需做调整。
  • 快速判断用户粘性,比如用户是否更易受促销活动的影响等等。

周留存率

  • 判断用户忠诚度,用户此时对产品基本已有完整的体验。一整套流程体验下来,继续访问的用户可判断为潜在忠诚用户。
  • 分析用户再次访问的原因,找出产品最能巩固用户的点,且参考此点以一贯之,拓展应用到更多的用户身上,促使更多的用户留下来。
    月留存率
  • 评估迭代与优化的效果。砍掉留存率低的产品功能,进行迭代优化。
    5 留存分析参考代码

有些互联网公司面试会出留存SQL题型,该代码仅供参考。

​代码运行结果

语法环境:SparkSql或Impala,其他环境也可以,只是个别函数会略有差别,替换个别函数即可,无需更改代码结构。

参考代码如下:

 --以a表日期作为主体
 select 
@@ -1366,6 +1439,9 @@ const step1Submit = () => {
   for (let i in step1Data.value.slice(0, step1Data.value.length - 1)) {
     if (step1Data.value[i].params != step1RightAnswer.value[i]) {
       step1Error.value++;
+      step1Data.value[i].isError = true;
+    } else {
+      step1Data.value[i].isError = false;
     }
   }
   console.log(step1Error.value, "错误数");
@@ -1380,15 +1456,27 @@ const step2Submit = () => {
   }
   if (step2Data.value[0].params1 && step2Data.value[0].params1 != "85") {
     step2Error.value++;
+    step2Data.value[0].isError1 = true;
+  } else {
+    step2Data.value[0].isError1 = false;
   }
   if (step2Data.value[0].params2 && step2Data.value[0].params2 != "73") {
     step2Error.value++;
+    step2Data.value[0].isError2 = true;
+  } else {
+    step2Data.value[0].isError2 = false;
   }
   if (step2Data.value[0].params3 && step2Data.value[0].params3 != "27") {
     step2Error.value++;
+    step2Data.value[0].isError3 = true;
+  } else {
+    step2Data.value[0].isError3 = false;
   }
   if (step2Data.value[0].params4 && step2Data.value[0].params4 != "4") {
     step2Error.value++;
+    step2Data.value[0].isError4 = true;
+  } else {
+    step2Data.value[0].isError4 = false;
   }
   console.log(step2Error.value, "错误数");
   proxy.$modal.msgSuccess("提交成功");
@@ -1541,6 +1629,7 @@ const submitData = () => {
     })
     .then((res) => {
       proxy.$modal.msgSuccess("提交成功");
+      showAnswerFlag.value = true;
     })
     .catch((error) => {});
 };
@@ -1720,7 +1809,7 @@ defineExpose({
     // background: #005b55;
     background: #f1f6fa;
     border: 1px solid #5b87ee;
-    color:#305FCB;
+    color: #305fcb;
     border-radius: 10px;
     margin-top: 20px;
     font-size: 14px;
@@ -1759,5 +1848,7 @@ defineExpose({
 ::v-deep .el-table td {
   padding-top: 3px;
   padding-bottom: 3px;
+  padding-left: 0px;
+  padding-right: 0px;
 }
 
diff --git a/src/views/portraitModel/components/rfmAnalysis.vue b/src/views/portraitModel/components/rfmAnalysis.vue
index 35c6830..4d90ea7 100644
--- a/src/views/portraitModel/components/rfmAnalysis.vue
+++ b/src/views/portraitModel/components/rfmAnalysis.vue
@@ -60,9 +60,9 @@
                     
                     
                   
-                  
- X - +
+ X +
@@ -93,17 +93,35 @@ @@ -168,17 +186,35 @@ @@ -206,17 +242,35 @@ @@ -256,10 +310,16 @@ v-if="scope.$index != 3" > --> - - - - +
+ + + + +
+ X + +
+
@@ -271,10 +331,16 @@ v-if="scope.$index != 3" > --> - - - - +
+ + + + +
+ X + +
+
@@ -286,10 +352,16 @@ v-if="scope.$index != 3" > --> - - - - +
+ + + + +
+ X + +
+
@@ -339,9 +411,15 @@ @@ -422,6 +500,7 @@ const step4AnswerFlag = ref(false); const step5AnswerFlag = ref(false); const step6AnswerFlag = ref(false); const step7AnswerFlag = ref(false); +const showAnswerFlag = ref(false); const knowledgeFlag = ref(false); const knowledge = ref( '

1.什么是RFM分析方法?

RFM是3个指标的缩写,最近一次消费时间间隔(Recency),消费频率(Frequency),消费金额(Monetary)。通过这3个指标对用户分类。

这里举个例子来说明这3个指标是什么意思。

比如我有一家店铺,小明是这家店铺的用户。现在是这个月的30号。

1)最近1次消费时间间隔(R)是指用户最近一次消费距离现在多长时间了。

小明最近1次在这就店铺买东西是这个月25号,上一次消费距离现在过去了5天,所以小明的最近1次消费时间间隔是5天。

2)消费频率(F)是指用户一段时间内消费了多少次。

比如“一段时间”定义是最近30天,发现小明最近30天在店铺消费了3次。

3)消费金额(M)是指用户一段时间内的消费金额。

比如“一段时间”是最近30天,发现小明最近30天总共在店铺消费了1000元。

这3个指标业务不同,定义也不同,要根据业务来灵活定义。

最近一次消费时间间隔(R),上一次消费离得越近,也就是R的值越小,用户价值越高。

消费频率(F),购买频率越高,也就是F的值越大,用户价值越高。

消费金额(M),消费金额越高,也就是M的值越大,用户价值越高。

我们把这3个指标按价值从低到高排序,并把这3个指标作为XYZ坐标轴,就可以把空间分为8部分,这样就可以把用户分为下图的8类。


我们把这个图里对应的RFM这3个值对应的价值是高还是低,对应到下面这张表里就得到了用户分类的规则。


2.RFM分析方法有什么用?

小明的店铺某个月收入大幅下跌。他赶快分析数据,发行原来几个重要的用户被竞争对手挖走了,而这几个用户贡献了店铺80%的收入。

出现这个问题,是因为小明没有对用户分类,对全部用户采取的都是一样的运营决策。怎么对用户分类,识别出有价值的用户呢?

这时候就可以用RFM分析方法把用户分为8类,这样就可以对不同价值用户使用不同的营销决策,把公司有限的资源发挥最大的效果,这就是我们常常听到的精细化运营。比如第1类是重要价值用户,这类用户最近一次消费较近,消费频率也搞,消费金额也搞,要提供vip服务。

我们日常生活中接触到的会员服务就是这方面的经典案例。根据企鹅智库《2017中国会员经济数据报告》数据显示,用户对信用卡、酒店、航空公司的会员体系最满意。


3.如何使用RFM分析方法?

前面我们说RFM分析方法把用户分为8类,具体是如何做到的呢?

第1步)计算R、F、M值

要得到R、F、M这3个指标,我们一般需要数据的3个字段:用户ID或者用户名称、消费时间、消费金额。从这3个字段我们可以计算出R、F、M这3个指标。

以图片中的原始数据为例,现在比如是2020年1月30日,分析最近30天的用户。

小明最近一次消费是(2020.1.26)与现在时间的间隔是4天。在最近30天消费了2次,总共消费金额是5000元。

用这个方法,假如我们这个案例里计算出的是下面表格里的R、F、M值,并在表格里加了3列,用于后面对计算出的R、F、M3个值打分。


第2步)给R、F、M按价值打分

注意这里是按指标的价值打分,不是按指标数值大小打分。最近一次消费时间间隔(R),上一次消费离得越近,也就是R的值越小,用户价值越高。

将R、F、M3个指标分别按价值从小到大分为1-5分。

这个案例里,将最近消费时间间隔(R)距离越近价值越大,大于20天的打1分,10-20天的打2分,5-10天打2分,3-5天打4分,3天以内打5分。


我们把这3个指标分别是如何打分的,整理到下面这个表里。

最近一次消费时间间隔(R),上一次消费离得越近,也就是R的值越小,用户价值越高。

消费频率(F),购买频率越高,也就是F值越大,用户价值越高。

消费金额(M),消费金额越高,也就是M值越大,用户价值越高。

具体实际业务中,如何定义打分的范围,要根据具体的业务来灵活定,没有统一的标准。

根据这个打分规则,我们可以把前面计算出的R、F、M值表格里的R值分类、F值分类、M值分类这3列填上上对应的RFM值的打分值:


第3步)计算价值平均值

分别计算出R值打分、F值打分、M值打分这3列的平均值


第4步)用户分类

在表格里增加3列,分别用于记录R、F、M3个值是高于平均值,还是低于平均值。

如果一行里的R值打分大于平均值,就在R值高低列里记录为“高”,否则记录为“低”。其他F值,M值也这样比较。最终得到了下面表格里的值

然后和用户分类表格里定义的规则进行比较,就可以得出用户属于哪种类


我们总结下前面的内容:如何用RFM对用户分类?

1)使用原始数据计算出R、F、M值

2)给R、F、M按价值打分,比如按价值从低到高分为1-5分

3)计算价值的平均值,如果某个指标的得分比价值的平均值低,标记为低。如果某个指标的得分比价值的平均值高,标记为高

4)用户分类规则表比较,得出用户分类

我们再回过头看前面这个分类图,你就会恍然大悟。在坐标轴的中心,可以理解为某个指标价值的平均值。


用户分类后,如何精细化运营呢?

对用户分类以后要做什么呢?那就是针对每类用户如何制定运营策略,这个具体公司业务不同,方法也不一样。这里举例说明前4类用户。

1)重要价值用户,RFM三个值都很高,要提供vip服务

2)重要发展用户,消费频率低,但是其他两个值很高,就要想办法提高他的消费频率

3) 重要保持用户,最近消费距离现在时间较远,也就是F值低,但是消费频次和消费金额高。这种用户,是一段时间没来的忠实客户。应该主动和他保持联系,提高复购率

4) 重要挽留客户,最近消费时间距离现在较远、消费频率低,但消费金额高。这种用户,即将流失,要主动联系用户,调查清楚哪里出了问题,并想办法挽回。

这样通过RFM分析方法来分析用户,对用户进行精细化运营。不断将用户转化为重要价值用户。


4.使用RFM分析方法需要注意什么?

第1个问题:什么是? 我们学习了,RFM是3个指标的缩写,最近一次消费的时间间隔(R),消费频率(F),消费金额(M)。RFM分析方法可以把用户分为8类。

第2个问题:有什么用?我们学习了,通RFM分析方法,我们可以把用户分为8类,这样就可以对不同用户使用不同的营销策略。比如信用卡的会员服务。

第3个问题:如何用?通过一个案例学会了如何用RFM分析方法对用户分类,了解了RFM背后的原理。现在有很多工具,比如excel,sql,pytho等都可以实现RFM。工作里用到的时候,可以再用搜索引擎去搜对应的实现工具,就可以快速实现了,现在把基本原理掌握了就可以。

现在我们来看第4个问题:有哪些注意事项?

(1)第1个注意事项:R、F、M指标定义,不同业务定义不同。要根据具体业务灵活应用。

这里举个例子。

很多人会有这样的疑问,朋友之间不经常联系,慢慢就淡了。那么,如何管理人脉关系呢?

我们还可以用RFM分析方法来分析你的人脉,针对不同的人,制定不同的联系决策。

最近一次消费时间间隔(R)可以定义为最近一次见面距离现在的时间。

消费频率(F)可以定义为最近1年见面的频率。

消费金额(M)可以定义为最近1年见面深度,比如见面是只打个招呼,还是一起吃个饭,还是畅谈人生。

按照这个定义,我们可以重点关注前3类人脉关系。

按照这个定义,我们可以重点关注前3类人脉关系

1)重要价值关系:对你的生活和工作非常有价值。他几乎是你最亲密的亲戚、朋友、客户。面对这些人,你应该经常联系,彼此帮助,时不时约出来聊聊天。

2)重要发展关系:联系比较多、一起做过点事,但是聊天是有一句没一句的,这种要重点发展关系。比如把你的困惑或者小秘密和他分享,产生情感连接。

3)重要保持的关系:所谓的熟人,也就是打起电话来记得住这个人,而且也大概了解他的背景,可能很长时间都没有见的那种“朋友”。这种要主动联系,利用节假日登门拜访、共同的朋友持续保持沟通。


冯仑讲过一段话:在正常情况下,人一生交往的关系是三个数:10、30和60。这句话是什么意思呢?其实正好对应我们刚才讲的三种人脉关系。

你遇到危难的时候,能借钱的对象不超过10个人。就算是把亲戚、朋友、父母全算上,你到时候能张口借钱的对象不会超过10个人。

再一层就是属于朋友,经常打交道的、做过点事的,大概不超过30个人。这30人还包括前面说的那10个人。

最外一圈是所谓的熟人,也就是打起电话来记得住这个人,而且也大概了解他的背景,可能很长时间都没有见的那种“朋友”,最多也就是60个。这60个人还包括了前面说的30人。

所以,人这一生,其实不需要太多的关系就能应付得了。需要花精力去了解的人,其实很少,不会很多,不会超过60个。只要把这60个人的名单每天都盘好,能够用一生了。

我有个朋友是这方面高手,他把经常要联系的人记下来,每个月翻出来看看,“这个朋友有3个月没联系了,要约出来聊聊天”。

你看,在关系中,如果两个都被动,那只能慢慢断了联系。所以,保持关系的秘密就是需要其中的一方主动。

人脉比你想象的重要,为了保持有效关系,你必须把自己变成一个在这方面主动的人。


(2)第2个注意事项:R、F、M按价值如何确定打分的规则?

一般分为1-5分,也可以根据具体业务灵活来调整。

每个分数的范围是多少?这要根据具体业务来定范围的阈值,这就好比你在开车,车速控制在哪个范围内,可以根据路况灵活把握。

同样的,FRM打分的规则可以与业务部门沟通,进行头脑风暴。或者使用聚类的方法对R、F、M的值进行分类,然后给每个类别打分。


5.总结

我把前面的知识点总结到下面这张图里

' @@ -708,7 +787,7 @@ const step1Submit = () => { if (fileTable1.value[0].params && fileTable1.value[0].params == "纳入") { stepError1.value++; fileTable1.value[0].isError = true; - }else{ + } else { fileTable1.value[0].isError = false; } // console.log(fileTable1.value[0].params); @@ -716,7 +795,7 @@ const step1Submit = () => { if (fileTable1.value[i].params && fileTable1.value[i].params == "剔除") { stepError1.value++; fileTable1.value[i].isError = true; - }else{ + } else { fileTable1.value[i].isError = false; } } @@ -739,30 +818,57 @@ const step2Submit = () => { console.log(555); if (step2Data.value[0].params1 && step2Data.value[0].params1 !== "4") { stepError2.value++; + step2Data.value[0].isError1 = true; + } else { + step2Data.value[0].isError1 = false; } if (step2Data.value[0].params2 && step2Data.value[0].params2 !== "2") { stepError2.value++; + step2Data.value[0].isError2 = true; + } else { + step2Data.value[0].isError2 = false; } if (step2Data.value[0].params3 && step2Data.value[0].params3 !== "5000") { stepError2.value++; + step2Data.value[0].isError3 = true; + } else { + step2Data.value[0].isError3 = false; } if (step2Data.value[1].params1 && step2Data.value[1].params1 !== "2") { stepError2.value++; + step2Data.value[1].isError1 = true; + } else { + step2Data.value[1].isError1 = false; } if (step2Data.value[1].params2 && step2Data.value[1].params2 !== "3") { stepError2.value++; + step2Data.value[1].isError2 = true; + } else { + step2Data.value[1].isError2 = false; } if (step2Data.value[1].params3 && step2Data.value[1].params3 !== "1000") { stepError2.value++; + step2Data.value[1].isError3 = true; + } else { + step2Data.value[1].isError3 = false; } if (step2Data.value[2].params1 && step2Data.value[2].params1 !== "1") { stepError2.value++; + step2Data.value[2].isError1 = true; + } else { + step2Data.value[2].isError1 = false; } if (step2Data.value[2].params2 && step2Data.value[2].params2 !== "1") { stepError2.value++; + step2Data.value[2].isError2 = true; + } else { + step2Data.value[2].isError2 = false; } if (step2Data.value[2].params3 && step2Data.value[2].params3 !== "500") { stepError2.value++; + step2Data.value[2].isError3 = true; + } else { + step2Data.value[2].isError3 = false; } console.log(stepError2.value, "错误数"); proxy.$modal.msgSuccess("提交成功"); @@ -790,30 +896,57 @@ const step4Submit = () => { // let step4Error = 0; if (step4Data.value[0].params1 && step4Data.value[0].params1 !== "4") { step4Error.value++; + step4Data.value[0].isError1 = true; + } else { + step4Data.value[0].isError1 = false; } if (step4Data.value[0].params2 && step4Data.value[0].params2 !== "2") { step4Error.value++; + step4Data.value[0].isError2 = true; + } else { + step4Data.value[0].isError2 = false; } if (step4Data.value[0].params3 && step4Data.value[0].params3 !== "4") { step4Error.value++; + step4Data.value[0].isError3 = true; + } else { + step4Data.value[0].isError3 = false; } if (step4Data.value[1].params1 && step4Data.value[1].params1 !== "5") { step4Error.value++; + step4Data.value[1].isError1 = true; + } else { + step4Data.value[1].isError1 = false; } if (step4Data.value[1].params2 && step4Data.value[1].params2 !== "2") { step4Error.value++; + step4Data.value[1].isError2 = true; + } else { + step4Data.value[1].isError2 = false; } if (step4Data.value[1].params3 && step4Data.value[1].params3 !== "2") { step4Error.value++; + step4Data.value[1].isError3 = true; + } else { + step4Data.value[1].isError3 = false; } if (step4Data.value[2].params1 && step4Data.value[2].params1 !== "5") { step4Error.value++; + step4Data.value[2].isError1 = true; + } else { + step4Data.value[2].isError1 = false; } if (step4Data.value[2].params2 && step4Data.value[2].params2 !== "1") { step4Error.value++; + step4Data.value[2].isError2 = true; + } else { + step4Data.value[2].isError2 = false; } if (step4Data.value[2].params3 && step4Data.value[2].params3 !== "1") { step4Error.value++; + step4Data.value[2].isError3 = true; + } else { + step4Data.value[2].isError3 = false; } console.log(step4Error.value, "错误数"); proxy.$modal.msgSuccess("提交成功"); @@ -841,12 +974,21 @@ const step5Submit = () => { // let step5Error = 0; if (step5Data.value[0].params1 && step5Data.value[0].params1 !== "4.67") { step5Error.value++; + step5Data.value[0].isError1 = true; + } else { + step5Data.value[0].isError1 = false; } if (step5Data.value[0].params2 && step5Data.value[0].params2 !== "1.67") { step5Error.value++; + step5Data.value[0].isError2 = true; + } else { + step5Data.value[0].isError2 = false; } if (step5Data.value[0].params3 && step5Data.value[0].params3 !== "2.33") { step5Error.value++; + step5Data.value[0].isError3 = true; + } else { + step5Data.value[0].isError3 = false; } console.log(step5Error.value, "错误数"); proxy.$modal.msgSuccess("提交成功"); @@ -868,30 +1010,57 @@ const step6Submit = () => { // let step6Error = 0; if (step6Data.value[0].params1 && step6Data.value[0].params1 !== "低") { step6Error.value++; + step6Data.value[0].isError1 = true; + } else { + step6Data.value[0].isError1 = false; } if (step6Data.value[0].params2 && step6Data.value[0].params2 !== "高") { step6Error.value++; + step6Data.value[0].isError2 = true; + } else { + step6Data.value[0].isError2 = false; } if (step6Data.value[0].params3 && step6Data.value[0].params3 !== "高") { step6Error.value++; + step6Data.value[0].isError3 = true; + } else { + step6Data.value[0].isError3 = false; } if (step6Data.value[1].params1 && step6Data.value[1].params1 !== "高") { step6Error.value++; + step6Data.value[1].isError1 = true; + } else { + step6Data.value[1].isError1 = false; } if (step6Data.value[1].params2 && step6Data.value[1].params2 !== "高") { step6Error.value++; + step6Data.value[1].isError2 = true; + } else { + step6Data.value[1].isError2 = false; } if (step6Data.value[1].params3 && step6Data.value[1].params3 !== "高") { step6Error.value++; + step6Data.value[1].isError3 = true; + } else { + step6Data.value[1].isError3 = false; } if (step6Data.value[2].params1 && step6Data.value[2].params1 !== "高") { step6Error.value++; + step6Data.value[2].isError1 = true; + } else { + step6Data.value[2].isError1 = false; } if (step6Data.value[2].params2 && step6Data.value[2].params2 !== "低") { step6Error.value++; + step6Data.value[2].isError2 = true; + } else { + step6Data.value[2].isError2 = false; } if (step6Data.value[2].params3 && step6Data.value[2].params3 !== "低") { step6Error.value++; + step6Data.value[2].isError3 = true; + } else { + step6Data.value[2].isError3 = false; } console.log(step6Error.value, "错误数"); proxy.$modal.msgSuccess("提交成功"); @@ -919,12 +1088,21 @@ const step7Submit = () => { // let step7Error = 0; if (step7Data.value[0].params && step7Data.value[0].params !== "重要保持用户") { step7Error.value++; + step7Data.value[0].isError1 = true; + } else { + step7Data.value[0].isError1 = false; } if (step7Data.value[1].params && step7Data.value[1].params !== "重要价值用户") { step7Error.value++; + step7Data.value[1].isError1 = true; + } else { + step7Data.value[1].isError1 = false; } if (step7Data.value[2].params && step7Data.value[2].params !== "一般发展用户") { step7Error.value++; + step7Data.value[2].isError1 = true; + } else { + step7Data.value[2].isError1 = false; } console.log(step7Error.value, "错误数"); proxy.$modal.msgSuccess("提交成功"); @@ -942,10 +1120,11 @@ const submitData = () => { userId: JSON.parse(getUserInfo()).userId, taskName: "RFM分析", numberOfErrors: errorNum.value, - subState:1, + subState: 1, }) .then((res) => { proxy.$modal.msgSuccess("提交成功"); + showAnswerFlag.value = true; }) .catch((error) => {}); }; diff --git a/src/views/portraitModel/components/viscosityAnalysis.vue b/src/views/portraitModel/components/viscosityAnalysis.vue index d060347..334a302 100644 --- a/src/views/portraitModel/components/viscosityAnalysis.vue +++ b/src/views/portraitModel/components/viscosityAnalysis.vue @@ -80,7 +80,7 @@ https://blog.csdn.net/kevin1993best/article/details/106329573"
- + @@ -143,12 +155,20 @@ https://blog.csdn.net/kevin1993best/article/details/106329573" @@ -181,12 +201,20 @@ https://blog.csdn.net/kevin1993best/article/details/106329573" @@ -233,6 +261,10 @@ https://blog.csdn.net/kevin1993best/article/details/106329573" @@ -250,6 +282,10 @@ https://blog.csdn.net/kevin1993best/article/details/106329573" @@ -275,7 +311,7 @@ https://blog.csdn.net/kevin1993best/article/details/106329573" 在日常的项目和产品运营工作中, 单日的DAU/MAU的数值往往受到周期(工作日/周末)、版本更新和活动的影响,用户粘性在短期内的波动较大。所以通常要采用长期的均值作参考,例如一个月、两个大版本之间。eg:以某客户App为例,DAU/MAU的数值在工作日约50%,而在周末和假期的数值则在20%左右。那么谈到用户粘性的时候,通常采用每天DAU/MAU的平均值39.37%。
-
+