电商分析之广告业务

文章内容输出来源:拉勾教育大数据高薪训练营

互联网平台通行的商业模式是利用免费的基础服务吸引凝聚大量用户,并利用这些用户资源开展广告或其他增值业务实现盈利从而反哺支撑免费服务的生存和发展。广告收入不仅成为互联网平台的重要收入之一,更决定了互联网平台的发展程度。

电商平台本身就汇聚了海量的商品、店铺的信息,天然适合进行商品的推广。对于电商和广告主来说,广告投放的目的无非就是吸引更多的用户,最终实现营销转化。因此非常关注不同位置广告的曝光量、点击量、购买量、点击率、购买率。

第1节 需求分析

事件日志数据样例:

{
    "lagou_event": [{
        "name": "loading",
        "json": {
            "loading_time": "10",
            "action": "2",
            "loading_type": "1",
            "type": "2"
        },
        "time": 1595297586761
    }, {
        "name": "notification",
        "json": {
            "action": "2",
            "type": "1"
        },
        "time": 1595327851731
    }, {
        "name": "praise",
        "json": {
            "id": 6,
            "type": 3,
            "add_time": "1597832569942",
            "userid": 5,
            "target": 9
        },
        "time": 1595286066942
    }],
    "attr": {
        "area": "赤峰",
        "uid": "2F10092A2321",
        "app_v": "1.1.5",
        "event_type": "common",
        "device_id": "1FB872-9A1002321",
        "os_type": "0.35",
        "channel": "BB",
        "language": "chinese",
        "brand": "Huawei-5"
    }
}

采集的信息包括:

  • 商品详情页加载:goods_detail_loading
  • 商品列表:loading
  • 消息通知:notification
  • 商品评论:comment
  • 收藏:favorites
  • 点赞:praise
  • 广告:ad
    • action。用户行为;0 曝光;1 曝光后点击;2 购买
    • duration。停留时长
    • shop_id。商家id
    • event_type。"ad"
    • ad_type。格式类型;1 JPG;2 PNG;3 GIF;4 SWF
    • show_style。显示风格,0 静态图;1 动态图
    • product_id。产品id
    • place。广告位置;首页=1,左侧=2,右侧=3,列表页=4
    • sort。排序位置

需求指标:

1、点击次数统计(分时统计)

曝光次数、不同用户id数、不同用户数

点击次数、不同用户id数、不同用户数

购买次数、不同用户id数、不同用户数

2、转化率-漏斗分析

点击率 = 点击次数 / 曝光次数

购买率 = 购买次数 / 点击次数

3、活动曝光效果评估:

行为(曝光、点击、购买)、时间段、广告位、产品,统计对应的次数

时间段、广告位、商品,曝光次数最多的前N个

第2节 事件日志采集

1、启动Flume Agent(适当的修改参数,128M滚动一次)

# 启动flume
flume-ng agent --conf /opt/apps/flume-1.9/conf --conf-file /data/lagoudw/conf/flume-log2hdfs3.conf -name a1 -Dflume.root.logger=INFO,console

2、生成数据(文件大小约640M,100W条事件日志)

cd /data/lagoudw/jars

java -cp data-generator-1.1-SNAPSHOT-jar-with-dependencies.jar com.lagou.ecommerce.AppEvent 1000000 2020-08-02 > /data/lagoudw/logs/event/events0802.log

3、数据采集完成后,检查HDFS结果

hdfs dfs -ls /user/data/logs/event

第3节 ODS层建表和数据加载

drop table if exists ods.ods_log_event;
CREATE EXTERNAL TABLE ods.ods_log_event(`str` string)
PARTITIONED BY (`dt` string)
STORED AS TEXTFILE
LOCATION '/user/data/logs/event';

/data/lagoudw/script/advertisement/ods_load_event_log.sh

#!/bin/bash
source /etc/profile
if [ -n "$1" ]
then
    do_date=$1
else
    do_date=`date -d "-1 day" +%F`
fi
sql="
alter table ods.ods_log_event add partition (dt='$do_date');
-- 解决select count(*) from tableName 查询语句统计不到条数问题
ANALYZE TABLE ods.ods_log_event partition(dt='$do_date') COMPUTE STATISTICS;
"
hive -e "$sql"

第4节 DWD层建表和数据加载

ODS:分区;事件的主要信息在json串中(json数组),公共信息在另外一个json串中;

ODS => 解析json,从json串中,提取jsonArray数据;将公共信息从json串中解析出来 => 所有事件的明细

所有事件的明细,包括:

  • 分区
  • 事件(json串)
  • 公共信息字段

所有事件的明细 => 广告json串解析 => 广告事件的明细

广告事件的明细:

  • 分区
  • 广告信息字段
  • 公共信息字段

4.1、DWD层建表

-- 所有事件明细
drop table if exists dwd.dwd_event_log;
CREATE EXTERNAL TABLE dwd.dwd_event_log(
`device_id` string,
`uid` string,
`app_v` string,
`os_type` string,
`event_type` string,
`language` string,
`channel` string,
`area` string,
`brand` string,
`name` string,
`event_json` string,
`report_time` string)
PARTITIONED BY (`dt` string)
stored as parquet;

-- 与广告点击明细
drop table if exists dwd.dwd_ad;
CREATE TABLE dwd.dwd_ad(
  `device_id` string,
  `uid` string,
  `app_v` string,
  `os_type` string,
  `event_type` string,
  `language` string,
  `channel` string,
  `area` string,
  `brand` string,
  `report_time` string,
  `duration` int,
  `ad_action` int,
  `shop_id` int,
  `ad_type` int,
  `show_style` smallint,
  `product_id` int,
  `place` string,
  `sort` int,
  `hour` string
)
PARTITIONED BY (`dt` string)
stored as parquet;

4.2、事件json串解析

内建函数、UDF、SerDe(json是所有的信息)

详细内容参见 第三部分 电商分析之--会员活跃度 => 第4节 json数据处理 => 使用 UDF(处理jsonArray)

package cn.lagou.dw.hive.udf;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.google.common.base.Strings;
import org.apache.hadoop.hive.ql.exec.UDF;

import java.util.ArrayList;

public class ParseJsonArray extends UDF {
    public ArrayList<String> evaluate(String jsonStr) {
        // 传入空字符串,返回null
        if (Strings.isNullOrEmpty(jsonStr)) {
            return null;
        }
        try {
            // 获取jsonArray
            JSONArray jsonArray = JSON.parseArray(jsonStr);
            ArrayList<String> lst = new ArrayList<>();
            for (Object o : jsonArray) {
                lst.add(o.toString());
            }
            return lst;
        } catch (Exception e) {
            return null;
        }
    }
}

4.3、DWD层数据加载

主要功能:解析json串;得到全部的事件日志

/data/lagoudw/script/advertisement/dwd_load_event_log.sh

#!/bin/bash
source /etc/profile
if [ -n "$1" ] ;then
    do_date=$1
else
    do_date=`date -d "-1 day" +%F`
fi

sql="
use dwd;
add jar /data/lagoudw/jars/cn.lagou.dw-1.0-SNAPSHOT-jar-with-dependencies.jar;
create temporary function json_array as 'cn.lagou.dw.hive.udf.ParseJsonArray';
with tmp_start as
(
  select split(str, ' ')[7] as line from ods.ods_log_event where dt='$do_date'
)
insert overwrite table dwd.dwd_event_log
PARTITION (dt='$do_date')
select
device_id,
uid,
app_v,
os_type,
event_type,
language,
channel,
area,
brand,
get_json_object(k,'$.name') as name, 
get_json_object(k,'$.json') as json,
get_json_object(k,'$.time') as time
from
(
select
    get_json_object(line,'$.attr.device_id') as device_id,
    get_json_object(line,'$.attr.uid') as uid,
    get_json_object(line,'$.attr.app_v')  as app_v,
    get_json_object(line,'$.attr.os_type') as os_type,
    get_json_object(line,'$.attr.event_type') as event_type,
    get_json_object(line,'$.attr.language') as language,
    get_json_object(line,'$.attr.channel') as channel,
    get_json_object(line,'$.attr.area') as area,
    get_json_object(line,'$.attr.brand') as brand,
    get_json_object(line,'$.lagou_event') as lagou_event
from tmp_start
) A lateral view explode(json_array(lagou_event)) B as k
"
hive -e "$sql"

从全部的事件日志中获取广告点击事件:

/data/lagoudw/script/advertisement/dwd_load_ad_log.sh

#!/bin/bash
source /etc/profile
if [ -n "$1" ] ;then
    do_date=$1
else
    do_date=`date -d "-1 day" +%F`
fi
sql="
insert overwrite table dwd.dwd_ad
PARTITION (dt='$do_date')
select
    device_id,
    uid,
    app_v,
    os_type,
    event_type,
    language,
    channel,
    area,
    brand,
    report_time,
    get_json_object(event_json,'$.duration') ,
    get_json_object(event_json,'$.ad_action') ,
    get_json_object(event_json,'$.shop_id') ,
    get_json_object(event_json,'$.ad_type'),
    get_json_object(event_json,'$.show_style'),
    get_json_object(event_json,'$.product_id'),
    get_json_object(event_json,'$.place'),
    get_json_object(event_json,'$.sort'),
    from_unixtime(ceil(report_time/1000), 'HH')
from dwd.dwd_event_log
where dt='$do_date' and name='ad';
"
hive -e "$sql"

日志 => Flume => ODS => 清洗、转换 => 广告事件详细信息

第5节 广告点击次数分析

5.1 需求分析

广告:ad

  • action。用户行为;0 曝光;1 曝光后点击;2 购买
  • duration。停留时长
  • shop_id。商家id
  • event_type。"ad"
  • ad_type。格式类型;1 JPG;2 PNG;3 GIF;4 SWF
  • show_style。显示风格,0 静态图;1 动态图
  • product_id。产品id
  • place。广告位置;首页=1,左侧=2,右侧=3,列表页=4
  • sort。排序位置

公共字段

分时统计:

曝光次数、不同用户id数(公共信息中的uid)、不同用户数(公共信息中的 device_id)

点击次数、不同用户id数、不同用户数(device_id)

购买次数、不同用户id数、不同用户数(device_id)

DWD => DWS(不需要) => ADS;在某个分析中不是所有的层都会用到

5.2、创建ADS层表

drop table if exists ads.ads_ad_show;
create table ads.ads_ad_show(
    cnt bigint,
    u_cnt bigint,
    device_cnt bigint,
    ad_action tinyint,
    hour string
) PARTITIONED BY (`dt` string)
row format delimited fields terminated by ',';

5.3、加载ADS层数据

/data/lagoudw/script/advertisement/ads_load_ad_show.sh

#!/bin/bash
source /etc/profile
if [ -n "$1" ] ;then
    do_date=$1
else
    do_date=`date -d "-1 day" +%F`
fi
sql="
insert overwrite table ads.ads_ad_show
partition (dt='$do_date')
select count(1),
       count(distinct uid),
       count(distinct device_id),
       ad_action,
       hour
  from dwd.dwd_ad
 where dt='$do_date'
group by ad_action, houra
"
hive -e "$sql"

第6节 漏斗分析(点击率购买率)

6.1、需求分析

分时统计:

点击率 = 点击次数 / 曝光次数

购买率 = 购买次数 / 点击次数

6.2、创建ADS层表

drop table if exists ads.ads_ad_show_rate;
create table ads.ads_ad_show_rate(
    hour string,
    click_rate double,
    buy_rate double
) PARTITIONED BY (`dt` string)
row format delimited fields terminated by ',';

行转列

-- 方法一
select sum(case when ad_action='0' then cnt end) show_cnt,
       sum(case when ad_action='1' then cnt end) click_cnt,
       sum(case when ad_action='2' then cnt end) buy_cnt,
       hour
  from ads.ads_ad_show
 where dt='2020-07-20' and hour='01'
group by hour ;

-- 方法二
select max(case when ad_action='0' then cnt end) show_cnt,
       max(case when ad_action='1' then cnt end) click_cnt,
       max(case when ad_action='2' then cnt end) buy_cnt,
       hour
  from ads.ads_ad_show
 where dt='2020-07-20' and hour='01'
group by hour ;

6.2、加载ADS层数据

/data/lagoudw/script/advertisement/ads_load_ad_show_rate.sh

#!/bin/bash
source /etc/profile
if [ -n "$1" ] ;then
    do_date=$1
else
    do_date=`date -d "-1 day" +%F`
fi

sql="
with tmp as(
select max(case when ad_action='0' then cnt end) show_cnt,
       max(case when ad_action='1' then cnt end) click_cnt,
       max(case when ad_action='2' then cnt end) buy_cnt,
       hour
  from ads.ads_ad_show
 where dt='$do_date'
group by hour
)
insert overwrite table ads.ads_ad_show_rate
partition (dt='$do_date')
select hour,
       click_cnt / show_cnt as click_rate,
       buy_cnt / click_cnt as buy_rate
  from tmp;
"
hive -e "$sql"

第7节 广告效果分析

7.1、需求分析

活动曝光效果评估: 行为(曝光、点击、购买)、时间段、广告位、商品,统计对应的次数

时间段、广告位、商品,曝光次数最多的前100个

7.2、创建ADS层表

drop table if exists ads.ads_ad_show_place;
create table ads.ads_ad_show_place(
    ad_action tinyint,
    hour string,
    place string,
    product_id int,
    cnt bigint
)PARTITIONED BY (`dt` string)
row format delimited fields terminated by ',';
drop table if exists ads.ads_ad_show_place_window;
create table ads.ads_ad_show_place_window(
    hour string,
    place string,
    product_id int,
    cnt bigint,
    rank int
)PARTITIONED BY (`dt` string)
row format delimited fields terminated by ',';

7.3、加载ADS层数据

/data/lagoudw/script/advertisement/ads_load_ad_show_page.sh

#!/bin/bash
source /etc/profile
if [ -n "$1" ] ;then
    do_date=$1
else
    do_date=`date -d "-1 day" +%F`
fi
sql="
insert overwrite table ads.ads_ad_show_place
partition (dt='$do_date')
select ad_action,
       hour,
       place,
       product_id,
       count(1)
  from dwd.dwd_ad
 where dt='$do_date'
group by ad_action, hour, place, product_id;
"
hive -e "$sql"

/data/lagoudw/script/advertisement/ads_load_ad_show_page_window.sh

#!/bin/bash
source /etc/profile
if [ -n "$1" ] ;then
    do_date=$1
else
    do_date=`date -d "-1 day" +%F`
fi

sql="
insert overwrite table ads.ads_ad_show_place_window
partition (dt='$do_date')
select *
  from (
        select hour,
               place,
               product_id,
               cnt,
               row_number() over (partition by hour, place, product_id order by cnt desc) rank
          from ads.ads_ad_show_place
         where dt='$do_date' and ad_action='0'
) t
where rank <= 100
"
hive -e "$sql"

小结:分析简单,没有DWS层

Flume、json解析在会员分析讲解

第8节 广告分析小结

image.png

脚本调用次序:

ods_load_event_log.sh
dwd_load_event_log.sh
dwd_load_ad_log.sh
ads_load_ad_show.sh
ads_load_ad_show_rate.sh
ads_load_ad_show_page.sh
ads_load_ad_show_page_window.sh

第9节 ADS层数据导出(DataX)

步骤:

  • 在MySQL创建对应的表
  • 创建配置文件(json)
  • 执行命令,使用json配置文件;测试
  • 编写执行脚本(shell)
  • shell脚本的测试

1、MySQL建表

drop table if exists dwads.ads_ad_show_place;
create table dwads.ads_ad_show_place(
    ad_action tinyint,
    hour varchar(2),
    place varchar(20),
    product_id int,
    cnt int,
    dt varchar(10)
);

2、创建配置文件

/data/lagoudw/script/advertisement/ads_ad_show_place.json

{
    "job": {
        "setting": {
            "speed": {
                "channel": 1
            }
        },
        "content": [{
            "reader": {
                "name": "hdfsreader",
                "parameter": {
                    "path": "/lagou/hive/warehouse/ads.db/ads_ad_show_place/dt=$do_date/*",
                    "defaultFS": "hdfs://linux121:9000",
                    "column": [{
                            "index": 0,
                            "type": "string"
                        }, {
                            "index": 1,
                            "type": "string"
                        },
                        {
                            "index": 2,
                            "type": "string"
                        },
                        {
                            "index": 3,
                            "type": "string"
                        },
                        {
                            "index": 4,
                            "type": "string"
                        },
                        {
                            "type": "string",
                            "value": "$do_date"
                        }
                    ],
                    "fileType": "text",
                    "encoding": "UTF-8",
                    "fieldDelimiter": ","
                }
            },
            "writer": {
                "name": "mysqlwriter",
                "parameter": {
                    "writeMode": "insert",
                    "username": "hive",
                    "password": "12345678",
                    "column": [
                        "ad_action",
                        "hour",
                        "place",
                        "product_id",
                        "cnt",
                        "dt"
                    ],
                    "preSql": ["delete from ads_ad_show_place where dt='$do_date'"],
                    "connection": [{
                        "jdbcUrl": "jdbc:mysql://linux123:3306/dwads?useUnicode=true&characterEncoding=utf-8 ",
                        "table": ["ads_ad_show_place"]
                    }]
                }
            }
        }]
    }
}

3、执行命令(测试)

python /data/modules/datax/bin/datax.py -p "-Ddo_date=2020-08-02" /data/lagoudw/script/advertisement/ads_ad_show_place.json

4、编写脚本

/data/lagoudw/script/advertisement/ads_ad_show_place.sh

#!/bin/bash
source /etc/profile
JSON=/data/lagoudw/script
if [ -n "$1" ] ;then
    do_date=$1
else
    do_date=`date -d "-1 day" +%F`
fi
python $DATAX_HOME/bin/datax.py -p "-Ddo_date=$do_date" $JSON/advertisement/ads_ad_show_place.json

5、执行脚本

sh /data/lagoudw/script/advertisement/ads_ad_show_place.sh 2020-08-02

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如今的大数据技术应用场景,对实时性的要求已经越来越高。作为新一代大数据流处理框架,由于非常好的实时性,Flink独树一帜,在近些年引起了业内极大的兴趣和关注。Flink能够提供毫秒级别的延迟,同时保证了数据处理的低延迟、高吞吐和结果的正确性,还提供了丰富的时间类型和窗口计算、Exactly-once 语义支持,另外还可以进行状态管理,并提供了CEP(复杂事件处理)的支持。Flink在实时分析领域的优势,使得越来越多的公司开始将实时项目向Flink迁移,其社区也在快速发展壮大。目前,Flink已经成为各大公司实时领域的发力重点,特别是国内以阿里为代表的一众大厂,都在全力投入,不少公司为Flink社区贡献了大量源码。如今Flink已被很多人认为是大数据实时处理的方向和未来,很多公司也都在招聘和储备了解掌握Flink的人才。本教程将Flink理论与电商数据分析项目实战并重,对Flink基础理论知识做了系统的梳理和阐述,并通过电商用户行为分析的具体项目用多个指标进行了实战演练。为有志于增加大数据项目经验、扩展流式处理框架知识的工程师提供了学习方式。二、教程内容和目标本教程主要分为两部分:第一部分,主要是Flink基础理论的讲解,涉及到各种重要概念、原理和API的用法,并且会有大量的示例代码实现;第二部分,以电商作为业务应用场景,以Flink作为分析框架,介绍一个电商用户行为分析项目的开发实战。通过理论和实际的紧密结合,可以使学员对Flink有充分的认识和理解,在项目实战中对Flink和流式处理应用的场景、以及电商分析业务领域有更深刻的认识;并且通过对流处理原理的学习和与批处理架构的对比,可以对大数据处理架构有更全面的了解,为日后成长为架构师打下基础。三、谁适合学1、有一定的 Java、Scala 基础,希望了解新的大数据方向的编程人员2、有 Java、Scala 开发经验,了解大数据相关知识,希望增加项目经验的开发人员3、有较好的大数据基础,希望掌握Flink及流式处理框架的求职人员

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值