Java 漏斗分析计算,如何计算漏斗?

Java 漏斗分析计算,如何计算漏斗?,java,math,hadoop,mapreduce,bigdata,Java,Math,Hadoop,Mapreduce,Bigdata,假设我跟踪用户在网站上的“事件”,事件可以是: 浏览网页 已将项目添加到购物车 结帐 已付款订单 现在,这些事件都存储在数据库中,如: 会话\u id事件\u名称已创建\u日期 现在我想构建一个报告来显示一个特定的漏斗,我将定义如下: Step#1 event_n Step#2 event_n2 Step#3 event_n3 所以这个漏斗有3个步骤,每个步骤都与任何事件相关 鉴于我拥有的上述数据,我现在如何为此构建报告 注意:我只想说清楚,我希望能够创建我定义的任何漏斗,并能够为

假设我跟踪用户在网站上的“事件”,事件可以是:

  • 浏览网页
  • 已将项目添加到购物车
  • 结帐
  • 已付款订单
  • 现在,这些事件都存储在数据库中,如:

    会话\u id事件\u名称已创建\u日期

    现在我想构建一个报告来显示一个特定的漏斗,我将定义如下:

    Step#1   event_n
    Step#2   event_n2
    Step#3   event_n3
    
    所以这个漏斗有3个步骤,每个步骤都与任何事件相关

    鉴于我拥有的上述数据,我现在如何为此构建报告

    注意:我只想说清楚,我希望能够创建我定义的任何漏斗,并能够为其创建报告。

    我能想到的最基本的方法是:

  • 获取数据库中每个步骤的所有事件
  • 步骤1将是,x%的人执行了事件
  • 现在,我必须查询步骤2的数据,该步骤2也执行了步骤1,并显示%
  • 与#3相同,但步骤#3的条件为步骤#2

  • 我很好奇这些在线服务如何在托管Saas环境中显示这些类型的报告。map reduce在某种程度上使这变得容易了吗?

    考虑这一点的核心问题是,您是在SQL/表类型模型中思考的。每个事件都是一个记录。NoSQL技术的一个优点(您对此有所了解)是可以自然地将记录存储为每个记录一个会话。一旦以基于会话的方式存储了数据,就可以编写一个例程来检查该会话是否符合模式。无需执行连接或其他操作,只需在会话中的事务列表上循环即可。这就是半结构化数据的威力

    如果将会话存储在一起呢?然后,您所要做的就是迭代每个会话,看看它是否匹配

    在我看来,这是一个极好的HBase用例

    使用HBase,您将会话ID存储为行键,然后将每个事件存储为值,时间戳作为列限定符。这给您留下的是按会话ID分组的数据,然后按时间排序

    好的,现在你想知道有多少%的会话执行了行为1,然后是2,然后是3。对该数据运行MapReduce作业。MapReduce作业将为每行键/值对提供一个会话。在数据上写一个循环,检查它是否与模式匹配。如果是+1,如果不是,就不要


    不用全力以赴使用HBase,您可以使用MapReduce在静止状态下对无组织的数据进行会话。按会话ID分组,然后在reducer中,将与该会话关联的所有事件分组在一起。现在,您基本上已经达到了使用HBase时的状态,您可以在reducer中编写一个方法来检查模式



    如果你没有大量的数据,HBase可能会被过度使用。在这种情况下,任何能够分层存储数据的数据库都是不错的选择。MongoDB、Cassandra和Redis都会浮现在脑海中,它们都有各自的优势和劣势。

    首先,根据您的假设,使用标准SQL给出答案: 有一个简单布局的事件表:

    EVENTS
    -----------------------------
    SESION_ID , EVENT_NAME , TMST
    
    要在某个时间获取执行步骤#1的会话,请执行以下操作:

    -- QUERY 1
    SELECT SESSION_ID,MIN(TMST) FROM EVENTS WHERE EVENT_NAME='event1' GROUP BY SESSION_ID;
    
    在这里,我假设事件1可以在每个会话中发生一次以上。结果是在某个时间演示event1的唯一会话列表

    为了得到步骤2和步骤3,我可以做同样的事情:

    -- QUERY 2
    SELECT SESSION_ID,MIN(TMST) FROM EVENTS WHERE EVENT_NAME='event2' GROUP BY SESSION_ID;
    -- QUERY 3
    SELECT SESSION_ID,MIN(TMST) FROM EVENTS WHERE EVENT_NAME='event3' GROUP BY SESSION_ID;
    
    现在,您要选择执行步骤1、步骤2和步骤3的会话-按顺序。 更准确地说,您需要计算执行步骤1的会话数,然后计算执行步骤2的会话数,然后计算执行步骤3的会话数。 基本上,我们只需将上述3个查询与left join结合起来,列出进入漏斗的会话以及它们执行的步骤:

    -- FUNNEL FOR S1/S2/S3
    SELECT 
      SESSION_ID, 
      Q1.TMST IS NOT NULL AS PERFORMED_STEP1,
      Q2.TMST IS NOT NULL AS PERFORMED_STEP2,
      Q3.TMST IS NOT NULL AS PERFORMED_STEP3
    FROM
      -- QUERY 1
      (SELECT SESSION_ID,MIN(TMST) FROM EVENTS WHERE EVENT_NAME='event1' GROUP BY SESSION_ID) AS Q1,
    LEFT JOIN
      -- QUERY 2
      (SELECT SESSION_ID,MIN(TMST) FROM EVENTS WHERE EVENT_NAME='event2' GROUP BY SESSION_ID) AS Q2,
    LEFT JOIN
      -- QUERY 3
      (SELECT SESSION_ID,MIN(TMST) FROM EVENTS WHERE EVENT_NAME='event2' GROUP BY SESSION_ID) AS Q3
    -- Q2 & Q3
    ON Q2.SESSION_ID=Q3.SESSION_ID AND Q2.TMST<Q3.TMST
    -- Q1 & Q2
    ON Q1.SESSION_ID=Q2.SESSION_ID AND Q1.TMST<Q2.TMST
    
    现在我们只需要计算一些统计数据,例如:

    SELECT
      STEP1_COUNT,
      STEP1_COUNT-STEP2_COUNT AS EXIT_AFTER_STEP1,
      STEP2_COUNT*100.0/STEP1_COUNT AS PERCENTAGE_TO_STEP2,
      STEP2_COUNT-STEP3_COUNT AS EXIT_AFTER_STEP2,
      STEP3_COUNT*100.0/STEP2_COUNT AS PERCENTAGE_TO_STEP3,
      STEP3_COUNT*100.0/STEP1_COUNT AS COMPLETION_RATE
    FROM
    (-- QUERY TO COUNT session at each step
      SELECT
        SUM(CASE WHEN PERFORMED_STEP1 THEN 1 ELSE 0 END) AS STEP1_COUNT,
        SUM(CASE WHEN PERFORMED_STEP2 THEN 1 ELSE 0 END) AS STEP2_COUNT,
        SUM(CASE WHEN PERFORMED_STEP3 THEN 1 ELSE 0 END) AS STEP3_COUNT
      FROM
        [... insert the funnel query here ...]
    ) AS COMPUTE_STEPS
    

    现在开始讨论。 第一点,如果您采用“集合”(或功能性)思维方式,而不是“程序性”方法,那么结果非常简单。不要将数据库可视化为包含列和行的固定表的集合。。。这是它的实现方式,但不是您与它交互的方式。都是布景,你可以按照你需要的方式来安排布景

    第二点是,如果使用MPP数据库,查询将自动优化为并行运行。您甚至不需要对查询进行不同的编程,使用map reduce或其他什么。。。我在测试数据集上运行了超过1亿个事件的相同查询,并在几秒钟内得到结果


    最后但并非最不重要的一点是,这个问题带来了无限的可能性。只需将结果按引用者、关键字、登录页、用户信息进行分组,并分析哪一个提供了最佳转化率(例如!)

    我最近发布了一个开源的Hive UDF来实现这一点:

    用于这种漏斗分析任务非常简单,您只需编写配置单元,无需编写自定义Java MapReduce代码


    这只有在您使用Hive/Hadoop存储和查询数据时才起作用。

    如果您认为这样做更容易,那么您可以在reducer中获取每个会话ID的所有事件。不确定我是否清楚,但我希望用户能够定义一个漏斗(每个步骤的步骤和匹配的事件),并且能够查看历史数据的报告。我想这意味着我必须运行批处理作业才能将旧数据拉入给定的数据存储/结构,对吗?没有什么神奇的方法可以解决这个问题,对吗?我只是在读hbase,我喜欢如何以这种分组方式存储相关数据等。不过,我该如何做与mongodb类似的事情呢?(hbase在这一点上对我来说可能太多了)是的,您必须编写某种流程来将它们组合在一起,或者如果您使用的是一个数据存储,那么
    SELECT
      STEP1_COUNT,
      STEP1_COUNT-STEP2_COUNT AS EXIT_AFTER_STEP1,
      STEP2_COUNT*100.0/STEP1_COUNT AS PERCENTAGE_TO_STEP2,
      STEP2_COUNT-STEP3_COUNT AS EXIT_AFTER_STEP2,
      STEP3_COUNT*100.0/STEP2_COUNT AS PERCENTAGE_TO_STEP3,
      STEP3_COUNT*100.0/STEP1_COUNT AS COMPLETION_RATE
    FROM
    (-- QUERY TO COUNT session at each step
      SELECT
        SUM(CASE WHEN PERFORMED_STEP1 THEN 1 ELSE 0 END) AS STEP1_COUNT,
        SUM(CASE WHEN PERFORMED_STEP2 THEN 1 ELSE 0 END) AS STEP2_COUNT,
        SUM(CASE WHEN PERFORMED_STEP3 THEN 1 ELSE 0 END) AS STEP3_COUNT
      FROM
        [... insert the funnel query here ...]
    ) AS COMPUTE_STEPS