00:00
接下来我们开始下一个拈啊,下一个拈是市场营销商业指标的统计分析啊,这里边呢,又包含两部分内容,一部分是做这个市场推广相关的统计,另外一部分呢,是页面广告相关的一些分析,呃,今天我们主要还是先来把这个市场推广这一部分做一个实现,呃,这个本身的本身的这个背景呢,因为大家知道就是像现在啊,我们大部分的用户,特别是电商,一般情况去买东西啊,上网站买东西的时候,用电脑的浏览器去登录的这种习惯其实已经是越来越少了,对吧?啊,就慢慢的大家都已经习惯直接是这个移动端直接用手机直接往上刷了,所以在这种情况下,我们去统计一些业务指标的时候,往往我们就会去关心这个自己的APP。怎么样能够去在哪些渠道能够得到更广泛的推广,对吧?啊,所以现在就是一个很重要的指标,就是APP的市场推广相关的一些数据,那一般情况大家会想到怎么样就代表我们这个推广的市场推广做的好呢?
01:13
那肯定是我们在一些比方说APP的这个下载链接里边,对吧,APP本身内部会有很多买点数据,那这些数据就代表了,比方说这个呃,下载链接的点击量,还有我们这个本身的下载量,还有这个安装量,或者说呃,里边还有一些行为可能是卸载,对吧,所有的这些行为我们都可以获取到,把它写入买点日志,拿到这些数据的话。其实就可以分析出来,当前根据不同的渠道推广出来的效果,诶到底这个这个到底做的市场推广这个渠道到底给不给力,对吧?啊,这是这样的一个状态,所以接下来我们给大家按照两种模式分析一下这个市场推广的统计数据,那其实主要来讲就是一种是分渠道统计的,另外一种是啊,部分渠道所有的混在一起,看看这段时间市场推广到底做的怎么样,对吧?啊,这其实是就是一般情况公司里边对市场部,或者说调整这个公司市场运营战略的一些比较重要的数据。
02:20
呃,说起来这个还比较重要,但是其实实现起来比较简单,大家一想就能想到了,那其实就是开一个时间窗口,直接把关心的那部分指标筛出来,Count一下就可以了啊,那接下来我们就在代码里边实现一下,大家可能会看到我们在数据里边呢,本身没有这样的买点数据,U behavior里边并没有,比方说这个下载啊,或者说这个安装,对吧,卸载没有这样的一些行为数据,所以这里边我们准备自定义一个一个数据源,我们实现一个自定义的测试数据源啊,所以也相当于通过这一部分把这个测试这一块也给大家讲一讲,首先新建一个新的模块,我们叫,呃,我们叫做市场。
03:11
分析啊,那就叫market analysis。然后在po文件里边想一想需要引入什么哦,好像暂时也想不到对吧?哎,我们就先不管了。直接把原文件要放在SW下边,先改个名。当然,我们没有现成数据文件的话,Resources下边不需要有别的东西,你有一个object。带上包名at硅谷,呃,这个我们叫market。呃。Neassis。这个叫APP marketing吧。
04:02
呃,当然现在是分渠道的啊,这个代码是分渠道,所以我们by channel。先把这个文件先建立好,呃,然后接下来大家会想到我们在这个处理的过程当中,首先要要生成那个输入自定义这个测试数据源嘛,那我先得定义出来测试的这个输入数据长什么样,对不对?定义一个class,我们这个数据就叫做marketing user behavior。大家想想,这个用户的行为数据应该包括哪些字段啊?那应该对user ID是不是应该有啊,这是比较正常的一个啊,User ID string类型,呃,然后是不是应该有一个行为啊,Behavior应该得有一个啊,这到底是干了什么事,你到底是点击了还是下载了,还是安装了,还是给卸载了,对吧,这也是一个string。
05:06
然后之后还应该是不是有一个渠道类型啊,对吧,比方说你是从个微博上分享去点击的,还是从这个微信上分享去去点击下载的,呃,另外就是可能还会有一些比方说你是App Store对吧,或者是这个华为的store还是小米的store,这些都是不同的渠道,下载安装渠道啊,推广渠道,所以这也是一个string。最后。我们感兴趣的东西一定少不了一个,因为我们一般情况都是事件时间对吧?对,是不是少不了一个时间戳啊,Time stamp,这个就用一个long类型表示就可以了,所以这是输入数据。样例类。呃,然后在这个main函数里边,大家会想到肯定还是对,先去把这个该有的东西都弄出来,创建环境。
06:14
然后设置呃,并行度可以设一,然后我们设置时间语义time characteristic对吧。接下来data stream,呃,我们这里就需要去怎么样去读取数据源了,可能需要去自定义了,对不对,要自定义的话,那是不是得at source啊,对,没有现成的这种方法让我们掉了啊,这里边我们可以你用一个比方说叫这个模拟的源啊,Simulated的模拟数据。Event。S,好,用这种方法把它创建出来。所以接下来我们先实现一个这样的自定义数据源。
07:05
自定义数据源。Simulated event source,它需要去实现一个source function接口对不对?呃,这里边这里面大家要注意,如果我们想要做的事情更多一些,还要用到这个,呃,其他的一些,比方说生命周期相关的一些东西的话,那是不是对,还需要用负函数对不对?呃,当然这个看大家具体的需要啊,如果不需要的话,直接s function就可以了,那可以用source rich s function,也可以reach parallel s function,对吧?啊,并行的。这里我们就直接算function就可以啊,一一个圆嘛。它的数据类型是什么样的呢?这是不是就是我们产生出来的那个out对吧,它就没有输入了源码,所以就只有产生出来的那个数据类型,就是我们的样例类类型,那就是。
08:07
A marketing user behavior。好啊,这就是我们的这一部分,然后大家会想到在这个里边,我们首先会定义什么来着,在S里边自定义S。要有一个标志位去判断当前是否在正常运行对不对,呃,然后如果在就是我们那个running嘛,如果是running状态的话,下面就是while循环,你就跑着就行了,如果要是cancel的时候,是不是就把那个running制成制成false对吧?啊,然后接下来它自己就停了,所以这里我们先定义是否运行的标志位,呃,当然这应该是一个变量啊,袜类型。呃,我们先默认它是处对吧,另外还需要什么呢?啊,这可能也是得需要,就是提前先定义好,就比方说我们现在既然是要随机产生这些东西嘛,那呃,大家会想到我们自定义这个测试员肯定是随机产生的,那随机产生你这里边这个user ID,那可能大家可能知道,就是我们可以随机产生UUID对吧,UID有那个random的方法,那这个,那这个行为和这个channel,这个是不是我们得先定义好一个集合,然后你从这个集合里边去取啊,对吧,随机生成,因为你这个不能乱生成啊,得有一定含义才行,所以这里边我们可以定义。
09:37
这个用户行为的集合啊,那当然这个就叫behavior types对吧,他应该是一个string的。集合对不对。啊,那当然这里边我们就直接直接写死在这里就好了,呃,比方说会有什么样,会有什么样的行为呢?比方说我们用大写来来表示啊,可能会有click对不对,点击了一下还会有什么呢。
10:12
呃,哦,当然有可能有收藏对吧,更呃更常见的可能是这个,呃,Download下载对吧,Download。然后另外还有安装in install,对呃,对,当然有in install就有on in install卸载对吧?啊,我们就先定义这些吧,呃,大家先知道就大概要有这些东西,然后接下来还需要定义什么集合呢?渠道的集合是不是也应该定义好啊啊,这个没办法直接生成啊,渠道的集合哇,我们定义一个这个叫。Channel赛吧,当然它也是一个string类型的。
11:03
呃,那这里边我们可能能想到的一些渠道啊,比方说我从这个微信分享来的,对不对,呃,然后比方说呃,这个呃微博对吧,微博分享来的,那也有可能我直接从appstore下载了,对不对,Appstore。呃,当然另外就是安卓手机有可能是这个什么华为对吧,华为store啊,这个就大家可以自己去定义啊,随便写一些可以下载的渠道,就是我们测试的时候肯定是要按比较真实的这种情况去去进行测试啊,生成这样的一些数据。另外我们还需要一个什么呢?还需要一个随机数发生器,对吧?啊,这是我们常见的东西。发声器,呃,那定义一个,它应该是一个random类型。
12:04
好,然后这里边啊,当然我们去new一个random就可以了啊,我们先是定义好了,就是在这个整个处理的过程当中,随机生成数据的过程当中,有可能要用到的一些东西啊,那这里边大家看这还报错呢,该复写的方法还没复写呢,对不对?诶这里边。大家会看到必须要去重写的有cancel方法和wrong方法,那cancel其实我们已经知道了啊,对,就是直接running等于false就完事对不对?关键是这个wrong方法到底怎么去运行,怎么去生成我们想要的这些数据啊。呃,这里边当然我们可以直接一个while就开始生成了,这里边如果更规范一些的话,我可能还要去跟踪一下现在到底生成了多少数据,所以这里边,呃,定义就是不要超过一定的限度,对吧?定义一个生成数据的上限啊,那比方说这个上限就叫max element。
13:14
啊,这个大家随便定义,比方说我直接就是long类型的最大值max,这个可以对吧。呃,那当然了,可能这就还得有跟踪,当前到底生成了多少个对不对啊,得有一个count,有一个计数器,一开始是零,后面就是生成一条加一,生成一条加一就完事了。接下来最关键的其实就是。就是一个while循环对不对,对吧,随机生成。所有数据,呃,那这里边well,它的条件就是running对吧?呃,另外因为我们这里边有这个最大值限制嘛,所以对count应该要小于max elements,然后接下来就各种随机生成了,我们要的那个是,呃,Marketing user behavior是user ID behavior channel time STEM time,除了time STEM,这个是我们直接用系统时间,前面三个是不是都可以随机生成啊,那user ID这个随机生成我们就直接定义一个ID,对,用这个UUID下边的。
14:29
诶,这个还得引入一下,它下边是不是直接有一个random u ID啊呃,当然本身我们的这个类型应该要的是一个string类型,而这里边生成的是一个UUID的类型,对不对,所以。还是做一个to string,第二个,第二个字段是behavior behavior的话从哪里去取呢?是不是要从behavior types里边去取啊,那么这里边。
15:04
取第几个呢?取哪个值呢?那这个是不是随机生成一个整数,然后就可以随便随便的取出一个类型了,对吧?啊这个行为的类型,所以这里边我们用随机数生成器的next int是不是就可以搞定。对吧,当然这个单词in你得给一个范围啊,你不能乱生成,要超出它那个那个数组的那个边界怎么办呢?所以这里边我们要是不是把它那个size type的。S要传进去,按照这个生成是不是就可以了,就相当于是呃,就是零到S减一的这样的一个数,对吧。这是behavior,然后还有channel,这个从哪里去学channel set,这个过程是不是跟上面完全一样啊?Ne in对吧?呃,Channel set.set好,这都生成了,最后还有一个time stamp,是不是直接用system?
16:07
system.current对吧,这就是一个。毫秒数直接拿到当前的系统时间,最后直接输出输出,大家还记得s function怎么输出吗?CT对,是不是直接可以用ctx去输出啊,啊,所以这里边我们可以ctx点,诶不是out是。直接collect对吧,直接用上下文的collect方法,然后这里边包装成样例类marketing user behavior ID behavior channel ts。这样是不是就完事了啊,这就是我们的这个数据啊生成的过程啊,当然了,这里边大家不要忘记这个count,我们是只是当天生成多少条数据的,所以完事的时候count应该要加一对吧?呃,另外我们为了方便,这个就是一条一条看到这个数据生成的过程,是不是每一条数据生生成之后稍微的sleep一下呀,对吧,休息一会儿,那这里边我们有另外一种这个。
17:19
Time unit。是不是他直接比方说我们用这个毫秒来来定义这个sleep,是不是可以直接用一个time unit直接点sleep呀,对吧,这样也是调用我们系统thread的那个sleep方法啊,这里边我们给一个比方说生成一个数据,给十毫秒的一个休息时间啊,稍微的缓一缓啊。所以这就是我们这个自定义的圆生成数据的一个过程。呃,所以这个过程其实也也并不难,对吧,其实还整体来讲还是比较简单的,然后我们其实想做的是啊,大家看这个代码有点好像行数还挺多,但其实都是就是跟业务流程相关啊,也都是比较简单的代码,然后接下来我们就就会想到了,那最后要输出的统计输出的东西是不是也应该有一个样例类啊。
18:15
对吧,我们最后可能要有一个。输出结果样例类,呃,那这个就。我们就叫做marketing view count吧,反正都是一个数量的一个一个统计输出嘛,所以这个count的话,大家可能比较关心,关心什么呢。关心哪个时间窗口,然后哪个渠道对吧,然后的一个值啊,我们这里边呢,因为这个它的行为不一样,我们干脆就把渠道和行为都作为我们的K,就是一个渠道对应的一个行为都收集起来,让看一看,对吧,这个渠道的点击量是多少,这个渠道的那个下载量是多少,我们都收集起来,这里边就是。
19:06
呃,那就是得window window,呃,大家把那个start写出来也可以啊,Window start window and,这里面我定义一个可读性更强的string吧。拿到那个时间戳之后,我们再做一个转换,转换成一个string输出是不是更合理一些?Window and。也是一个string,另外还有channel string behavior string,全是string啊,最后count终于来了,一个不是string的,我们给一个long类型。这是我们想要的最后的结果。好,然后接下来我们就可以在读入数据之后继续做操作了,那读入数据之后既然是事件时间。而且读进来之后是不是已经包装成样力类了啊,这里边大家不要忘记还应该得有一个是不是a sign time stamp呀啊,当然这里边如果我们这里边就是按照系统时间生成的话,这其实没什么问题,对吧,直接用升序时间就可以了。
20:13
时间桌指定time STEM要不要乘1000哦,因为下面已经是毫秒了,对吧,这里面已经是毫秒了。然后继续。继续做什么呢?诶,大家会想到接下来我们是不是就应该开窗去聚合统计了呀,比方说我们要关心的是这个,呃,在在这个一个小时之内的所有的,呃当当前所有的这个渠道的一个一个值,另外如果说你要还要滑动的话,对吧,隔两秒钟,隔五秒钟输出一次的话,我们还可以定义划窗啊,这个当然都是可以的,那关键是我们前面按照哪个字段去分组,然后我们要哪些不要哪些呢?
21:01
大家想一想,在这里边。我们我们应该是按照什么去做分组啊,渠道是不是要按照渠道和按照前面说的是不是渠道和行为一起去做分组啊,哎,那另外行为里边我们更感兴趣的说推广的这个,呃,指标应该是是不是应该是正面指标啊,那所以我们可能这个卸载这个就就不应该算在这个推广的正面效应里边了,那所以就应该把。卸载要过滤掉,所以我们先做一个filter,呃,这个也很简单,Behavior不等于。On store。哦,不等于啊。呃,然后接下来,那是不是我既然是要统计。
22:02
按照这个user user behavior和channel这两个去做统计的话,那其实大家会想到我应该是按照那两个去做KY对不对啊,那有可能这里面我就不关心其他的数据了,那是不是把其他的数据都滤掉也可以啊,而且为了方便后边做这个呃处理,做聚合,我甚至直接可以把它map成一个什么呢?我直接把它map成一个这样的元组啊,就是data。这这个就看我们自己的一些定义了,这个就是处理很灵活,比方说我可以前边是我的key data,呃,data.channel data.behavior对吧,后边呃,对,再给一个一对吧,这是我的那个count值,如果大家愿意的话,后面直接sum也可以,当然这里边我们可能呃不能萨,还要包成一个量力类对吧?呃,所以可能这个大家不这么做也也可以啊,就是用不同的方式都可以去实现。
23:09
接下来就可以K了,K是不是当前应该是第一个这个二元组啊,Channel和behavior,然后接下来K外之后可以开窗了,比方说这里我们想要的是前面我给一个注释啊,以渠道和。行为类型。作为分组。那这个time window的话,我们统计的是一个小时之内的。Time or1啊,当然大家可以让它滑动起来,滑动的话呢,time.second可能是十秒钟滑一次对吧?啊,这个也是很正常的。
24:00
接下来就可以做聚合了,呃,那当然这个聚合操作如果。大,大家觉得在这个过程当中,想要去增量聚合的话,这个其实是不是跟我们之前讲的那个增量聚合一样啊,或者大家想用不同的方法的话,是不是也可以写一个process function,直接放大招把它搞定啊。呃,当然这里边我们举一个例子,就直接process function啊,自定义一个,你有一个marketing count by China。那接下来我们是不是把这个实现就可以了,这里是data stream print输出,最后执行execute。当然,这里是APP marketing。By channel。Jos。
我来说两句