Sparkcore案例实操:需求三---页面单跳转化率统计

一、需求说明
1)页面单跳转化率计算页面单跳转化率,什么是页面单跳转换率,比如一个用户在一次Session 过程中访问的页面路径3,5,7,9,10,21,那么页面3 跳到页面5 叫一次单跳,7-9 也叫一次单跳,那么单跳转化率就是要统计页面点击的概率。比如:计算3-5 的单跳转化率,先获取符合条件的Session 对于页面3 的访问次数(PV)为A,然后获取符合条件的Session 中访问了页面3 又紧接着访问了页面5 的次数为B,那么B/A 就是3-5 的页面单跳转化率。
在这里插入图片描述
2)统计页面单跳转化率意义产品经理和运营总监,可以根据这个指标,去尝试分析,整个网站,产品,各个页面的表现怎么样,是不是需要去优化产品的布局;吸引用户最终可以进入最后的支付页面。数据分析师,可以此数据做更深一步的计算和分析。企业管理层,可以看到整个公司的网站,各个页面的之间的跳转的表现如何,可以适当调整公司的经营战略或策略。

二、需求分析
在这里插入图片描述
三、代码

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

object Spark06_Req3_PageflowAnalysis {

  def main(args: Array[String]): Unit = {

    //TODO:Top热门品类
    val sparkConf =new SparkConf().setMaster("local[*]").setAppName("HotCategoryTop10Analysis")
    val sc = new SparkContext(sparkConf)

    //1.读取原始日志数据
    val actionRDD =sc.textFile("datas/user_visit_action.txt")

    val actionDataRDD = actionRDD.map(
      action =>{
        val datas = action.split("_")
        UserVisitAction(
          datas(0),
          datas(1).toLong,
          datas(2),
          datas(3).toLong,
          datas(4),
          datas(5),
          datas(6).toLong,
          datas(7).toLong,
          datas(8),
          datas(9),
          datas(10),
          datas(11),
          datas(12).toLong
        )
      }
    )
    actionDataRDD.cache()
    //TODO 计算分母
    val pageidToCountMap:Map[Long,Long] = actionDataRDD.map(
      actionR => {
        (actionR.page_id, 1L)
      }
    ).reduceByKey(_ + _).collect().toMap

    //TODO 计算分子
    val sessionRDD = actionDataRDD.groupBy(_.session_id)

    //分组后,根据访问时间进行排序(升序)
    val mvRDD:RDD[(String,List[((Long,Long),Int)])] = sessionRDD.mapValues(
      iter => {
        val sortList = iter.toList.sortBy(_.action_time)

        //[1,2,3,4]=>[1,2],[2,3],[3,4]=>[1-2,2-3,3-4]
        //Sliding:滑窗
        //或者zip:拉链

        val flowIds:List[Long] = sortList.map(_.page_id)
        val pageflowIds:List[(Long,Long)] = flowIds.zip(flowIds.tail)
        pageflowIds.map(
          t => {
            (t,1)
          }
        )
      }
    )
    //((1,2),1)
    val flatRDD = mvRDD.map(_._2).flatMap(List=>List)

    //((1,2),1) =>((1,2),sum)
    val dataRDD = flatRDD.reduceByKey(_+_)

    //TODO 计算单跳转化率
    //分子除以分母
    dataRDD.foreach{
      case ((pageid1,pageid2),sum) =>{
        val lon = pageidToCountMap.getOrElse(pageid1,0L)

        println(s"页面${pageid1}跳转到页面${pageid2}单跳转化率为:"+(sum.toDouble/lon))
      }
    }
    sc.stop()
  }

  case class UserVisitAction(
                              date: String,//用户点击行为的日期
                              user_id: Long,//用户的ID
                              session_id: String,//Session的ID
                              page_id: Long,//某个页面的ID
                              action_time: String,//动作的时间点
                              search_keyword: String,//用户搜索的关键词
                              click_category_id: Long,//某一个商品品类的ID
                              click_product_id: Long,//某一个商品的ID
                              order_category_ids: String,//一次订单中所有品类的ID集合
                              order_product_ids: String,//一次订单中所有商品的ID集合
                              pay_category_ids: String,//一次支付中所有品类的ID集合
                              pay_product_ids: String,//一次支付中所有商品的ID集合
                              city_id: Long)//城市id
}

四、运行结果
在这里插入图片描述
五、优化版

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

object Spark06_Req3_PageflowAnalysis_youhua {

  def main(args: Array[String]): Unit = {

    //TODO:Top热门品类
    val sparkConf =new SparkConf().setMaster("local[*]").setAppName("HotCategoryTop10Analysis")
    val sc = new SparkContext(sparkConf)

    //1.读取原始日志数据
    val actionRDD =sc.textFile("datas/user_visit_action.txt")
    val actionDataRDD = actionRDD.map(
      action =>{
        val datas = action.split("_")
        UserVisitAction(
          datas(0),
          datas(1).toLong,
          datas(2),
          datas(3).toLong,
          datas(4),
          datas(5),
          datas(6).toLong,
          datas(7).toLong,
          datas(8),
          datas(9),
          datas(10),
          datas(11),
          datas(12).toLong
        )
      }
    )
    actionDataRDD.cache()
    // TODO 对指定的页面连续跳转进行统计
    //1-2,2-3,3-4,4-5,5-6,6-7
    val ids=List[Long](1,2,3,4,5,6,7)
    val okflowIds:List[(Long,Long)] = ids.zip(ids.tail)

    //TODO 计算分母(过滤掉不需要的数据)
    val pageidToCountMap:Map[Long,Long] = actionDataRDD.filter(
      action => {
        ids.init.contains(action.page_id)
      }
    ).map(
      actionR => {
        (actionR.page_id, 1L)
      }
    ).reduceByKey(_ + _).collect().toMap

    //TODO 计算分子
    val sessionRDD = actionDataRDD.groupBy(_.session_id)
    //分组后,根据访问时间进行排序(升序)
    val mvRDD:RDD[(String,List[((Long,Long),Int)])] = sessionRDD.mapValues(
      iter => {
        val sortList = iter.toList.sortBy(_.action_time)

        //[1,2,3,4]=>[1,2],[2,3],[3,4]=>[1-2,2-3,3-4]
        //Sliding:滑窗
        //或者zip:拉链

        val flowIds:List[Long] = sortList.map(_.page_id)
        val pageflowIds:List[(Long,Long)] = flowIds.zip(flowIds.tail)
        
        //将不合法的页面跳转进行过滤
        pageflowIds.filter(
          t => {
            okflowIds.contains(t)
          }
        ).map(
          t => {
            (t,1)
          }
        )
      }
    )
    //((1,2),1)
    val flatRDD = mvRDD.map(_._2).flatMap(List=>List)

    //((1,2),1) =>((1,2),sum)
    val dataRDD = flatRDD.reduceByKey(_+_)

    //TODO 计算单跳转化率
    //分子除以分母
    dataRDD.foreach{
      case ((pageid1,pageid2),sum) =>{
        val lon = pageidToCountMap.getOrElse(pageid1,0L)

        println(s"页面${pageid1}跳转到页面${pageid2}单跳转化率为:"+(sum.toDouble/lon))
      }
    }
    sc.stop()
  }

  case class UserVisitAction(
                              date: String,//用户点击行为的日期
                              user_id: Long,//用户的ID
                              session_id: String,//Session的ID
                              page_id: Long,//某个页面的ID
                              action_time: String,//动作的时间点
                              search_keyword: String,//用户搜索的关键词
                              click_category_id: Long,//某一个商品品类的ID
                              click_product_id: Long,//某一个商品的ID
                              order_category_ids: String,//一次订单中所有品类的ID集合
                              order_product_ids: String,//一次订单中所有商品的ID集合
                              pay_category_ids: String,//一次支付中所有品类的ID集合
                              pay_product_ids: String,//一次支付中所有商品的ID集合
                              city_id: Long)//城市id
}

运行结果:
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值