stone

基于Spark的用户行为漏斗分析
之前一段时间参加了一个OLAP比赛,现在来进行一波小总结吧。比赛方案采用了spark和hdfs的简单方案,其实就是...
扫描右侧二维码阅读全文
05
2017/11

基于Spark的用户行为漏斗分析

之前一段时间参加了一个OLAP比赛,现在来进行一波小总结吧。

比赛方案采用了spark和hdfs的简单方案,其实就是自己不会hive和hbase,这个之后要找时间专门去恶补一下。
比赛花了三天的时间,其中大部分的时间都在配环境,现在反过来看看,其实真的没必要话那么多的时间在这一块,
就是坑在太急躁了,这应该也是我的一个毛病。劈哩叭啦的乱敲键盘一遍,然后各种报错,各种重来,一点都静不下来。╮( ̄▽ ̄)╭

用户行为指用户在网站中的一系列的操作,通过分析用户行为的转换率,可以找出产品中的一些不合理的地方,针对性地
进行分析。例如用户A在一购物网站中的行为是: 浏览网页,点击商品,加入购物车,点击支付,完成支付。通过分析这个过程中,
那一步流失的用户最多,进而分析每一步流式的原因,对产品进行优化。

比赛的要求比较简单,给定用户的操作记录数据,从中查询指定时间范围内,指定时间窗口的每一步的用户转化率。
其实这波比赛还是比较水的,数据直接储存在hdfs上面,用spark进行读取。

计算用户的漏斗转化率说白了就是计算每一个用户的最长转化路径,算法上参考了最长递增子序列,遍历一遍每个用户的操作序列即可。
对于每一步骤只需找到前前一个符合要求的操作。最后计算出最长的操作序列长度即可。直接上代码:

  def getLongestPath2(data: ArrayBuffer[Log]): Int = {
    //    val g = data.sortBy(_.timestamp)
    val g = data
    val timestamp = new Array[Int](16)
    val preOp = new Array[Int](16)
    for (i <- 1 until searchParams.opArr.length) {
      preOp(searchParams.opArr(i)) = searchParams.opArr(i - 1)
    }

    g.foreach((x) => {
      if (x.opId == searchParams.opArr(0)) {
        timestamp(x.opId) = x.timestamp
      } else if (timestamp(preOp(x.opId)) > 0 && x.timestamp - timestamp(preOp(x.opId)) <= searchParams.timeWin) {
        timestamp(x.opId) = timestamp(preOp(x.opId))
        //完成所有转化
        if (x.opId == searchParams.opArr(searchParams.opArr.length - 1)) {
          return searchParams.opArr.length
        }
      }
    })

    for (i <- searchParams.opArr.length - 1 to 0 by -1) {
      if (timestamp(searchParams.opArr(i)) > 0) {
        return i + 1
      }
    }

    return 0
  }

在算法的基础上进行了一些小的优化,将时间戳进行截断,另外利用了spark的缓存机制来提高计算的效率。

这样的做法肯定不是最优的,希望这次开了一个好头,以后再接再厉。

Last modification:September 7th, 2018 at 08:20 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment