机顶盒用户流向分析

电视台的项目今天有重大的突破,做了个demo。这个demo做完,我觉得自己在数据的理解上走的弯路太多,数据的探索是一个很重要的步骤,不可跳过,尤其是在接手一个新的领域的数据的时候,太想当然了,浪费太多时间。

今天下午所做的应该是大连-1新闻锋线节目,开播5分钟后流出到各个电视台的情况,在做的时候没有增加限制,后期可以增加例如看了多长时间以及地区编号的限制等等。

话不多说,记录下思路。

刚开始想找到一个用户的上一个和下一个电视台用START_TIME_C字段,因为是在mysql里面,没有窗口函数。这一段时间因为肝那本书肝的拥各种函数和子查询也熟练了些。然后发现做不下去之后把数据导入到了postresql中。

先针对一个用户分析。找到某一个用户这个时段的全部数据,然后通过排序找到前一个或者后一个

这里被cue到,觉得可以做协同过滤



想到了最近在看的推荐系统,可以按照书上和视频走完一遍之后用这个做,虽然没有电影评分,但是我有收看的节目时长,把收看一个节目的时间和节目时长占比当做评分。嘻嘻,就可以通过这些用户在其他电视节目上的行为找出用户可能喜欢的节目。

这里想到了用窗口函数中的ROW_NUMBER(),并且通过新增一列ranks,用来标记数据。然后对准一条有新闻锋线收看记录的用户找。这里注意是联合主键,所以要where两个字段。


得到ranks=3。

因为在那本书上学到了CET(公用表表达式),而且这次要多次引用同一个表。



接下来就想如何扩展到所有有收看大连-1王牌节目新闻锋线(6:00-6:25)的用户,以及统计6:00-6:05这5分钟内的用户是从何处而来。

统计6:25-6:30节目结束后的5分钟用户流向了哪里。

============================================================================


因为考虑到要是6:00开始播新闻锋线,如果只用18-1930这个表,会遗漏之前的从哪些台跳转来,ranks出现大量的1,这个还找个锤子哦。所以再导入一张表,然后合并成一个大表。


注意18:00:01 因为00点的时候会跳变,所以规避了系统自动换台来的人。有1996个流入记录。

接下来想找到前后的数据,搜了发现hive和oracle里面有一个lag() lead()函数

https://www.cnblogs.com/dqz19892013/archive/2013/04/11/3014239.html


但是试验没有成功,暂时放一边。


哦,还有用with的时候一定要连着select语句,不然报错。

思路:通过with构建一张a表为了接下来的引用。with中最内查询的是节目开始后5分钟内流入用户的newkey,外层先将18-19:30和12-17两个表拼在一起,并且根据机顶盒的记录特性(每隔一段时间就会刷新全部用户),减少数据数量,规定大于下午5点。用IN将cust_id和patch_code联合形成的主键规定为特定收看的用户。select部分选取主要的字段,并且通过窗口函数排序,以newkey分区,以Sstart_time排序,这样是为了让各个节目的首位连续,ranks正确。这样就形成了a表:


通过观察这张表可以发现了一些之前没有注意到的问题。当收看一个节目换台时START_TIME,END_TIME和START_TIME_C,END_TIME_C是一样的,当连续收看一个电视台时,没有换台,就是继续看下去,这种情况两条记录的C会相同,有点乱,看例子。为了辅助理解,特意加上了节目的开始和结束时间P。


19:20分“法制新天地”结束,这个观众没有换台,顺延到了“非常帮”,C记录的其实是一个用户看这个频道不换台的时间段!!!


以新闻锋线这个节目名来做筛选条件,规避了HD高清频道的影响。ranks-1出现了0,说明是一开机就看新闻锋线的,所以这部分的用户没有流入的电视台,可以筛选掉。


当一个人来来回回进出大连-1时,这里因为要按照newkey分组,所以只取最小的ranks。因为我的目的是找出看新闻锋线之前这个人在看什么,从哪里跳转。


------------------------------------------------------------

-----------最关键的部分--------

------------------------------------------------------------

这里用到INNER JOIN



接下来就是匹配lagranknum=ranks


再按照频道名称聚合:



同理6:25-6:30加广告这个时段,可以统计观众流向哪里。

But,以下是流出的部分,时间段为6:25-6:30
这里还要用表12-17,是因为有一直收看大连-1不换台的人,在表12-17中开始看,start_time落在这段时间里面,恰好end_time
落在节目结束这5min。而且比START_TIME要多注意,在找CONCAT("CUST_ID",'-',"PATCH_CODE")时,也要联合12-17表。


流出要规定END_TIME,这里划定时间的时候要注意18:30:00,会产生跳变,新闻锋线的人去往大连-1下一个节目,是否应该一起统计进去?分开统计!

再想,如果一个人顺延到了新闻锋线的下一个节目,那么这时他的END_TIME_C必将 > '2018/3/5 18:30:00',无论你手速有多快。这些人有多少。统计发现有10207条。

其中又发现了问题,也就是START_TIME_C为2018/3/5,之前有过验证,这代表0点,而系统会在0点全部刷新这些数据。这些用户可以确定是关了电视,没关机顶盒。
这些用户有817个用户。

知晓了这一部分的情况后,还是带着全部数据去计算最后这5min的用户去向。





在做的过程中遇到的问题:

1. [Err] ERROR:  CASE types integer and text cannot be matched

上网搜索了下,找到了stackflow上面的一个相同的报错。发现是格式的问题,用 :: 转格式后解决。

2. [Err] ERROR:  subquery has too many columns

发现是用IN 选择CONCAT("CUST_ID",'-',"PATCH_CODE"),* 时没有注意到验证期间多加的*。


猜你喜欢

转载自blog.csdn.net/dufemt/article/details/80599598