【保姆级】【零基础教程用户行为分析教程】浏览器用户行为分析与流失预测-数据加工
一、实验目的
通过本次实验,熟悉本次数据集的整体构成与半结构化日志数据的核心特点,熟练掌握文本日志解析、字段拆分的实操处理方法。
完成数据规整工作,把零散的原始日志转化为标准的结构化数据表。
实现多维度的数据聚合、字段衍生与跨表关联操作,搭建适配本次分析场景的指标体系。
完成机器学习的特征工程处理,最终产出可以直接投入使用的预测建模数据集。
二、实验环境
实验平台:助睿在线实验平台,地址https://lab.guilian.cn,助睿数智(Uniplore)。从数据接入、ETL 处理、机器学习建模到可视化展示的全链路零代码功能,既适用于数据分析教学场景,也可以满足企业的数据加工需求。助睿数智https://www.uniplore.com。。
本次实验的数据规模为覆盖 1000 名用户,包含 800 万 + 条行为记录,数据总大小约 825MB。
三、实验数据
本次实验基于首届中国互联网数据挖掘竞赛的公开数据集开展,该数据集是非常典型的计算机用户行为半结构化日志数据,专门用于用户行为分析、习惯挖掘、活跃度预测与用户画像研究。
3.1 数据集整体构成
使用的数据集包含三大核心部分:
第一部分是用户基本信息表,文件名为 demographic.csv,文件中存储了用户 ID、性别、年龄、职业、教育程度、收入等用户的人口属性信息。
第二部分是浏览器上网记录,日志中包含了用户访问的 URL、域名、访问时间等信息。
第三部分是软件使用记录,日志中包含了进程名、程序名、使用时长、窗口切换等信息。
整个数据集解压后总大小约 825MB,包含原始行为记录 800 多万条,覆盖了 1000 名用户连续 4 周的电脑使用行为,数据横跨 4 个月,每个月抽取 1 周的数据,具体的时间范围如下:
第 1 周:2012 年 5 月 7 日至 2012 年 5 月 13 日
第 2 周:2012 年 6 月 4 日至 2012 年 6 月 10 日
第 3 周:2012 年 7 月 2 日至 2012 年 7 月 8 日
第 4 周:2012 年 8 月 6 日至 2012 年 8 月 12 日
3.2 数据文件结构
拿到的所有数据分为两个部分:
第一个是 behavior / 文件夹,文件夹内按照日期归档,存放了数万条 TXT 格式的行为日志。
第二个是 demographic.csv 文件,也就是用户属性表。
两份数据通过用户 ID(user_id)实现唯一关联。
3.3 日志文件命名规则
每一个 TXT 文件,都对应一个用户一次开机产生的行为日志,文件名的格式为:用户 ID_日期_开机时间.txt,举个例子,文件名 0AB6BBBEDFF24EC8BAAC905F45AE314C_2012-05-07_21-22-38.txt,可以从文件名中直接解析出三个核心信息:
user_id:用户的唯一标识
file_date:日志对应的日期
file_start_time:用户的开机时间
3.4 日志文件内部格式
每一个日志文件的内容都固定分为三个部分:
第 1 行:格式为 Last<=> 数字,这个数字表示日志最后一条记录距离用户开机的秒数。
第 2 行:格式为 L_Start<=> 时间,表示本次开机的绝对时间。
第 3 行及以后的内容是行为记录,也是本次实验的核心数据,格式示例为:T<=>177 [=] P<=>360se.exe [=] I<=>5572 [=] W<=>30378 [=] V<=>4,1,6,6 [=] N<=>360 安全浏览器 [=] C<=> 360.cn
日志中采用了固定的分隔符:
<=> :用于分隔字段名与对应的值
[=] :用于分隔不同的字段
3.5 字段含义
需要熟练掌握日志中每个字段的具体含义,对应关系如下:
T:距离开机的秒数,也就是行为发生的时间
P:进程名,比如 360se.exe、QQ.exe 等
I:进程 ID
U:浏览器访问的 URL
W:非浏览器窗口句柄
V:程序版本号
N:程序名称,仅在程序第一次出现时记录
C:开发公司名称,仅在程序第一次出现时记录
A/B:浏览器窗口句柄
3.6 数据特点
本次实验的日志数据属于半结构化数据,没有固定的行列结构,无法直接用于分析。同时该数据具备数据量大、文件分散、格式统一、规则明确的特点。
四、实验步骤
4.1 创建实验项目
首先点击平台页面的 “新建项目” 按钮。

接着输入项目名称为 “互联网用户行为日志数据加工”,点击 “确定” 按钮完成项目创建。

项目创建成功后,就可以在数据集成页面看到刚刚新创建的项目。

4.2 日志数据结构化转换
4.2.1 数据资源获取
需要注意的是,由于本次实验的整体数据量过大,只使用其中 20 个 TXT 数据,来学习如何将半结构化数据转换为结构化数据。
本次实验的部分原始数据,也就是 20 个 TXT 数据,已经上传到平台的公共空间,为了方便后续的数据使用,需要将原始数据导入到自己的文件目录下。
项目创建成功后,点击该项目右上角的 “…” 按钮,接着点击 “打开项目”。

进入项目页面后,可以看到左侧有 3 个菜单,分别是资源库、文件、元数据。
其中资源库用于对工作流进行管理,包括工作流的新建、删除、修改、查看信息,以及工作空间的导出导入、调度管理等操作;文件库用于保存工作流中需要用到的文件,以及工作流产生的文件;元数据管理是助睿 ETL 的重要基石,可以为工作流定义 “运行配置”、“数据库”、“flink 集群” 等配置。

接下来开始获取本次的实验数据集:点击 “文件库”,右键点击根目录,点击 “新建目录”。

输入目录名称为 “互联网用户行为日志数据集”,点击 “确定”。

接下来需要将公共空间的数据资源导入到这个新建的目录下。
点击公共空间选项。
接着点击 “数据资源”。

点击属于 “互联网用户行为日志数据集” 下的数据卡片右上角的 “更多” 按钮,接着点击 “导出”。

在弹出的窗口中,选择导出到刚刚新创建的目录下,接着点击“确定”。

此时可以看到,在互联网用户行为日志数据集的目录下,已经新增了数据文件。
接下来重复以上的导出操作,将本次实验用到的 20 个数据都导出到 “互联网用户行为日志数据集” 目录下。

4.2.2 建立数据源连接
在之前的《学生用户画像 - 考勤主题标签构建》实验中,已经创建了团队私有数据库的连接,所以本次实验无需再建立数据源连接。

如果还未创建数据库连接,可以参考《学生用户画像 - 考勤主题标签构建》的 4.2.2 建立数据源连接小节的内容,完成连接的创建。
4.2.3 创建原始用户行为日志表
新建一个转换工作流,并将其命名为 “创建原始行为日志数据表”,在该工作流中拖拽 “执行一个 SQL 脚本” 组件,通过执行 SQL 脚本来创建一个标签表。整个转换流的结构如下所示。

组件的配置说明:在组件中填写 SQL 脚本,选择目标数据库连接为 “团队私有数据库”,确保脚本的执行权限。
使用的 SQL 脚本如下:
CREATE TABLE behavior_events (
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '自增主键',
session_id VARCHAR(255) COMMENT '会话唯一ID',
user_id VARCHAR(100) COMMENT '用户ID',
session_start_time VARCHAR(50) COMMENT '会话开始时间',
event_seconds INT COMMENT '事件发生秒数',
process_name VARCHAR(255) COMMENT '进程名称',
process_id VARCHAR(100) COMMENT '进程ID',
url TEXT COMMENT '访问网址',
addr_handle VARCHAR(255) COMMENT '地址栏句柄',
tab_handle VARCHAR(255) COMMENT '标签页句柄',
browser_version VARCHAR(100) COMMENT '浏览器版本',
window_handle VARCHAR(255) COMMENT '窗口句柄',
app_name VARCHAR(255) COMMENT '程序名称',
company_name VARCHAR(255) COMMENT '开发公司',
source_file VARCHAR(255) COMMENT '原始日志文件名',
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '入库时间',
INDEX idx_session_id (session_id),
INDEX idx_user_id (user_id)
) COMMENT '用户行为事件明细表';
其他参数都使用默认选项,完成后组件的配置如下。

完成配置后运行转换流,运行过程中平台会定时刷新组件状态,并在画布下方显示执行日志。

由于原始的数据是半结构化的数据,无法直接通过文件输入组件获取数据,所以需要换一种处理思路:
通过 “获取文件名” 组件批量读取并定位日志文件,再交由 “Java 代码” 组件完成半结构化日志的解析,包括字段拆分工作,接着通过 “字段选择” 组件筛选并规整有效字段,最终输出为标准结构化数据表,实现原始文本日志到可分析数据的标准化转换。
4.2.4 获取文件名:日志文件批量采集
新建转换工作流,并将其命名为 “行为日志数据转为结构化数据”,在该工作流中拖拽 “获取文件名” 组件。

双击 “获取文件名” 组件,在配置窗口中,点击文件或目录后的 “浏览文件” 按钮,在弹出的窗口中选择上面创建的目录 “互联网用户行为日志数据集”,再点击 “确定”。

选择目录后,点击 “增加” 按钮。

选择的目录出现在下方的路径中后,点击 “确认”。

4.2.5 Java 代码:日志解析与结构化转换
根据实验数据的说明,可以通过 java 代码来读取日志文件、解析文件名、提取用户与开机信息、跳过文件头部、按分隔符拆分半结构化行为记录,将原始 TXT 日志中的 T、P、I、U、V、W、N、C 等关键字段逐一解析提取,最终输出包含会话 ID、用户信息、行为详情的标准结构化数据,完成从半结构化数据到结构化数据的转换。
拖拽一个 “Java 代码” 组件到画布中,并创建 “获取文件名” 组件到 “Java 代码” 组件的连线,连接线类型选择 “主输出步骤”。

双击 “Java 代码” 组件,输入以下代码:
// 全局变量定义
String pathField;
String shortFilenameField;
public boolean processRow() throws HopException {
if (first) {
pathField = "filename";
shortFilenameField = "short_filename";
first = false;
}
Object[] r = getRow();
if (r == null) {
setOutputDone();
return false;
}
String path = get(Fields.In, pathField).getString(r);
String short_filename = get(Fields.In, shortFilenameField).getString(r);
String user_id = "";
String l_start = "";
if (short_filename != null) {
String name = short_filename.replace(".txt", "");
String[] parts = name.split("_");
if (parts.length >= 3) {
user_id = parts[0];
l_start = parts[1] + " " + parts[2].replace("-", ":");
}
}
String session_id = user_id + "_" + l_start;
java.io.BufferedReader br = null;
try {
br = new java.io.BufferedReader(new java.io.FileReader(path));
String line = "";
// 跳过前两行(Last和L_Start)
br.readLine();
br.readLine();
while ((line = br.readLine()) != null) {
if (line.trim().isEmpty()) {
continue;
}
// 解析键值对
String[] kvPairs = line.split("\\[=\\]");
String t = "";
String p = "";
String i = "";
String u = "";
String a = "";
String b = "";
String v = "";
String w = "";
String n = "";
String c = "";
for (String kv : kvPairs) {
int sepIdx = kv.indexOf("<=>");
if (sepIdx == -1) {
continue;
}
String key = kv.substring(0, sepIdx).trim();
String val = kv.substring(sepIdx + 3);
if ("T".equals(key)) {
t = val;
} else if ("P".equals(key)) {
p = val;
} else if ("I".equals(key)) {
i = val;
} else if ("U".equals(key)) {
u = val;
} else if ("A".equals(key)) {
a = val;
} else if ("B".equals(key)) {
b = val;
} else if ("V".equals(key)) {
v = val;
} else if ("W".equals(key)) {
w = val;
} else if ("N".equals(key)) {
n = val;
} else if ("C".equals(key)) {
c = val;
}
}
// 创建输出行
Object[] outRow = createOutputRow(r, data.outputRowMeta.size());
get(Fields.Out, "session_id").setValue(outRow, session_id);
get(Fields.Out, "user_id").setValue(outRow, user_id);
get(Fields.Out, "l_start").setValue(outRow, l_start);
get(Fields.Out, "t").setValue(outRow, t);
get(Fields.Out, "p").setValue(outRow, p);
get(Fields.Out, "i").setValue(outRow, i);
get(Fields.Out, "u").setValue(outRow, u);
get(Fields.Out, "a").setValue(outRow, a);
get(Fields.Out, "b").setValue(outRow, b);
get(Fields.Out, "v").setValue(outRow, v);
get(Fields.Out, "w").setValue(outRow, w);
get(Fields.Out, "n").setValue(outRow, n);
get(Fields.Out, "c").setValue(outRow, c);
get(Fields.Out, "source_file").setValue(outRow, short_filename);
putRow(data.outputRowMeta, outRow);
}
} catch (Exception e) {
logError(e.getMessage(), e);
} finally {
try {
if (br != null) {
br.close();
}
} catch (Exception e) {
// ignore
}
}
return true;
}
在字段空白表格处右键点击 “插入”。

双击插入的行,字段名输入 “session_id”,类型选择 “String”。

继续插入行,依次将 java 代码中输出的字段进行配置,具体配置如下:
|
字段名 |
类型 |
|
session_id |
String |
|
user_id |
String |
|
l_start |
String |
|
t |
String |
|
p |
String |
|
i |
String |
|
u |
String |
|
a |
String |
|
b |
String |
|
v |
String |
|
w |
String |
|
n |
String |
|
c |
String |
|
source_file |
String |
配置完成后点击 “确认”。

4.2.6 字段选择:有效字段筛选与规整
右键 “java 代码” 组件,点击 “预览输出字段”,可以看到有很多字段是不需要,也不属于原始数据字段的,需要将这些字段移除。

拖拽 “字段选择” 组件到画布中,并创建 “Java 代码” 组件到 “字段选择” 组件的连线,连接线类型选择 “主输出步骤”。

双击 “字段选择” 组件,点击 tab 选项 “移除”,并在字段名称下方空白处右键点击 “获取字段”。

选中上一步骤中的 Java 代码输出的字段后,右键点击 “删除选中的行”。

最后剩下多余的字段后,就可以点击 “确认”。

4.2.7 表输出:结构化数据表落地
接下来,将已经转换为结构化的数据输出到数据库中,以便后续使用。
拖拽 “表输出” 组件到画布中,并创建 “字段选择” 组件到 “表输出” 组件的连线,连接线类型选择 “主输出步骤”。

双击 “表输出” 组件,选择 “团队私有数据库” 连接。
勾选 “裁剪表”,这样表输出组件在插入数据前会清空原始表数据,避免重复插入。
勾选 “指定数据库字段”,建立工作流字段与数据库表字段的映射关系。勾选后会激活 “数据库字段” tab 页,在数据库字段 tab 页,右键选择 “获取字段”。

重新打开“表输出”组件,在 4.2.3 小节中创建的表字段与流字段是不一样的,所以双击表字段,在下拉框中选择正确的表字段。
设置完成后点击 “确认”。

4.2.8 执行转换流
执行转换流,点击工具栏中的 “执行” 按钮。
在弹出的执行配置窗口中,选择默认配置,然后点击 “启动” 按钮,启动工作流。

查看日志,工作流执行后会打开日志页面,定期刷新工作流日志数据。

接下来查看数据库结果。
打开 “元数据” tab 页,在 “团队私有数据库” 连接上右键选择 “加载元数据”。

然后进入数据探查页面,展开 “团队私有数据库”。
双击目标表 “behavior_events”,在右侧页面选择 “查询” tab 标签。
查看数据库表数据,确认数据符合预期。

4.3 数据分析方向确定
得到 behavior_events 表后,需要确定具体的分析方向。对 behavior_events 表按进程名 process_name 统计使用人数,可以快速看出哪些程序覆盖的用户最广。这个统计的价值在于,它能帮从九百多万条杂乱记录中,迅速锁定最值得分析的候选对象。
4.3.1 创建进程统计表
新建转换工作流,并命名为 “创建进程统计表”,在该工作流中拖拽 “执行一个 SQL 脚本” 组件,通过执行 SQL 脚本来创建一个标签表。整个转换流如下所示。

配置说明:在组件中填写 SQL 脚本,选择目标数据库连接 “团队私有数据库”,确保脚本执行权限。
使用的 SQL 脚本如下:
-- 创建程序/软件统计表
CREATE TABLE program_stats (
program_name VARCHAR(255) NOT NULL, -- 程序/软件名称
user_count INT NOT NULL -- 使用用户数
);
其他参数使用默认选项,完成后组件配置如下。

由于数据量较大,为了顺利运行转换流,点开 “元数据”,双击 “团队私有数据库”,勾选 “使用结果流”。

完成后运行转换流,运行过程会定时刷新组件状态,并在画布下面显示执行日志。

4.3.2 统计进程用户规模
每个进程的用户规模即用户数量,等于每个进程名称对应的用户 ID 计数。
新建转换流 “统计进程用户规模”,拖拽 “表输入” 组件到画布中,数据库连接选择 “团队私有数据库”,并获取 behavior_events 的所有 SQL 查询语句。

拖拽 “字段选择” 组件到画布中,并创建 “表输入” 组件到 “字段选择” 组件的连线,双击 “字段选择” 组件,点击 tab 选项 “移除”,然后在字段名称下方空白处右键点击 “获取字段”。
统计每个进程的用户数量只需用到 user_id、process_name 两个字段,所以需要移除其他字段。
选中 user_id、process_name 两个字段,右键点击 “删除选中的行”。

删除后点击 “确认”。

字段 process_name 可能存在空值,为避免后续操作错误,需要将空值替换为 “未知”。拖拽 “替换 NULL 值” 组件到画布中,并创建 “字段选择” 组件到 “替换 NULL 值” 组件的连线,连接线类型选中 “主输出步骤”。

双击 “替换 NULL 值” 组件,勾选 “选择字段”,在下方字段表格中插入一行,并输入:
字段:process_name
值替换为:未知
是否为空:否

分组聚合之前需要对数据进行排序,否则分组计算结果可能出错。拖拽 “排序字段” 组件到画布中,创建 “替换 NULL 值” 组件到 “排序记录” 组件的连线,连接线类型选中 “主输出步骤”。

双击 “排序记录” 组件,将数据按照 “process_name” 字段升序排序。

接下来就可以对排序后的数据进行分组聚合统计了,拖拽 “分组” 组件到画布中,创建 “排序记录” 组件到 “分组” 组件的连线。

在聚合表格空白处右键点击 “插入”。
双击插入的空白行,名称输入 “user_count”,subject 选择 “user_id”,类型选择 “个数”,最后点击 “确认”。

分组聚合后的数据需要输出到 4.3.1 小节创建的统计表中,拖拽 “表输出” 组件,创建 “分组” 组件到 “表输出” 组件的连线。
双击 “表输出” 组件,选择 “团队私有数据库” 连接,勾选 “裁剪表”,这样表输出组件在插入数据前会清空原始表数据,避免重复插入。

勾选 “指定数据库字段”,建立工作流字段与数据库表字段的映射关系。勾选后会激活 “数据库字段” tab 页,在数据库字段 tab 页,右键选择 “获取字段”,按如图修改。

最后执行转换流即可。

4.3.3 观察数据确定分析方向
为了确定覆盖用户最广的进程 / 软件,使用助睿 BI 来观察数据。
点击实验平台左边菜单 “助睿 BI”,进入助睿 BI 首页。

由于之前的实验已经创建了团队私有数据库的数据源连接,本次实验无需再创建数据源连接,可直接创建数据集。
点击 “数据集” 菜单。

在数据集页面点击 “+” - “新建数据集”。

数据集名称和备注信息都输入 “进程用户数据统计”,点击 “确认”。

右上角数据源选择进程统计表 program_stats 所在的 “商业数据分析” - “cs_group_8”。

将 program_stats 拖拽至画布中。

可以看到 program_stats 的数据结果,为了方便观察,将字段备注修改为中文。

修改完成后点击 “保存”,保存并发布数据集。

点击 “工作表”。

进入工作表页面后,点击 “+” - “新建工作表”。

输入工作表名称和备注信息后点击 “确认”。

数据集选择刚刚创建的数据集 “进程用户数据统计”,图表类型选择 “水平条图”。

将字段 “program_name” 拖拽至 Y 轴,“user_count” 拖拽至 X 轴,并将 “user_count” 按照降序排序。


通过可视化结果可以看到,浏览器类进程(chrome.exe、360chrome.exe、sogouexplorer.exe、QQBrowser.exe)的用户数明显高于其他软件(如 QQ.exe、EXCEL.EXE、WINWORD.EXE)。这表明浏览器是覆盖面最广的应用,样本充足;同时浏览器记录包含 url,可进一步分析网站偏好。因此,确定将浏览器作为本次的分析对象。
4.4 分析方案设计与数据确定
根据 4.3 节的统计结果,发现浏览器类进程的用户覆盖率远高于其他软件,且浏览器记录包含 url 字段,可以挖掘用户网站偏好。因此,将分析对象锁定为浏览器,并围绕以下业务问题展开分析:
浏览器市场格局:哪些浏览器用户最多、使用时长最长?
用户画像:不同浏览器的用户在年龄、职业上有何差异?
使用习惯:用户集中在什么时段使用浏览器?
竞争迁移:用户是否会从一款浏览器切换到另一款?
流失预测:哪些用户可能停止使用 iexplore.exe 浏览器?
个性化推荐:根据用户的网站访问历史,可以推荐哪些网站?
为了回答这些问题,可以预先设计一套可视化方案,将在下一实验完成。下表列出了每张图表对应的业务问题、所需数据字段以及最终输出的数据表名,后续数据加工将围绕它们展开。
|
输出表名 |
内容 |
粒度 |
|
browser_coverage.csv |
每个浏览器的用户数、总使用时长 |
每个浏览器一行 |
|
browser_hourly.csv |
每个浏览器按小时统计活跃用户数 |
浏览器 × 小时 |
|
browser_demographic.csv |
每个浏览器按年龄分段、职业的用户分布 |
浏览器 × 年龄组 × 职业 |
|
browser_retention.csv |
每个浏览器从第3周到第4周的留存率 |
每个浏览器一行 |
|
browser_migration.csv |
用户从第3周主用浏览器切换到第4周主用浏览器的迁移对及人数 |
源浏览器 → 目标浏览器 |
|
churn_features.csv |
每个用户前三周的 Chrome 行为特征及标签 |
每个用户一行 |
|
churn_probability.csv |
每个用户的流失概率(AI Studio 输出) |
每个用户一行 |
|
feature_importance.csv |
流失预测模型的特征重要性 |
每个特征一行 |
|
high_risk_users.csv |
流失概率最高的 20% 用户及其关键特征 |
每用户一行(约200行) |
high_risk_users.csv 流失概率最高的 20% 用户及其关键特征 每用户一行(约 200 行)
本次实验先完成前 2 个数据的加工,首先需要在团队私有数据库中先创建这 2 个数据表。
创建两个转换流,分别命名为 “创建浏览器的用户数总使用时长统计表”、“创建每个浏览器按小时统计活跃用户数统计表”。
两个转换流都拖拽 “执行一个 SQL 脚本” 组件到画布中,分别输入以下 SQL:
创建浏览器的用户数总使用时长统计表的 “执行一个 SQL 脚本” 组件配置如下:

对应的 SQL 语句:
CREATE TABLE `browser_coverage` (
`browser_name` VARCHAR(50) NOT NULL COMMENT '浏览器进程名',
`user_count` INT NOT NULL COMMENT '使用用户数(去重)',
`total_duration_sec` BIGINT NOT NULL COMMENT '总使用时长(秒)'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='浏览器用户覆盖率与总时长';
创建每个浏览器按小时统计活跃用户数统计表的 “执行一个 SQL 脚本” 组件配置如下:

对应的 SQL 语句:
CREATE TABLE `browser_hourly` (
`browser_name` VARCHAR(50) NOT NULL COMMENT '浏览器进程名',
`hour` TINYINT NOT NULL COMMENT '小时(0-23)',
`active_user_count` INT NOT NULL COMMENT '活跃用户数',
PRIMARY KEY (`browser_name`, `hour`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='浏览器按小时活跃用户数';
最后分别执行两个转换流即可。
4.5 数据清洗、聚合与关联加工
在 4.1 章节转换后得到的明细结构化数据,单条记录仅反映单次电脑操作行为,无法直观体现用户整体使用习惯,因此开展清洗、聚合与关联加工,提炼核心统计指标,并结合用户基础属性信息,形成具备分析价值的整合数据集。
使用解析完成的 behavior_events 行为明细表,同时引入 demographic.csv 用户人口属性数据表,依靠用户唯一编号完成两份数据的联动处理。
注:包含全部数据的 behavior_events 行为明细表已经存放在线上公共数据库中,可以直接使用。
新建转换流,命名为 “互联网用户行为日志数据清洗抽取”。

4.5.1 表输入:读取行为日志数据
拖入 “表输入” 组件到画布中。

连接线上公共数据源,因为团队私有数据库中的数据只有 20 个数据,仅作教学使用,全部数据已存放在线上公共数据源中的 behavior_events 表中,获取 behavior_events 的所有 SQL 查询语句。


4.5.2 字段选择:删除冗余字段
拖拽 “字段选择” 组件到画布中,创建 “表输入” 组件到 “字段选择” 组件的连线。

双击 “字段选择” 组件,点击 “移除” tab 选项,在字段名称下方空白处右键点击 “获取字段”。

选中 session_id, user_id, session_start_time, process_name, url, event_seconds 后删除选中的行,保留下来的字段就是要移除的字段,点击 “确认”。

4.5.3 过滤记录:筛选进程为主要浏览器的数据
拖拽 “过滤记录” 组件到画布中,创建 “字段选择” 组件到 “过滤记录” 组件的连线,连接线类型选择 “主输出步骤”。

双击 “过滤记录” 组件,可以看到需要配置匹配和不匹配的结果的输出步骤。

因此,先将后续的步骤的组件拖进来,拖拽 “排序记录” 组件到画布中,创建 “过滤记录” 组件到 “排序记录” 组件的连线,连接线类型选择 “True 输出”。

再拖一个 “空操作 (什么也不做)” 组件到画布中,创建 “过滤记录” 组件到 “空操作 (什么也不做)” 组件的连线,连接线类型选择 “False 输出”。

再次双击 “过滤记录” 组件,设置发送匹配的结果给 “排序记录”,发送不匹配的结果给 “空操作 (什么也不做)”。

接下来配置过滤条件,点击第一个 “field”,选择 “process_name”,表示过滤条件为 process_name 的值。

点击函数符号,选择 “IN LIST”。

接着点击 “value”。
在弹出的窗口中,类型选择 “String”,值为主要浏览器的进程名:“iexplore.exe;360chrome.exe;360se.exe;chrome.exe;sogouexplorer.exe;QQBrowser.exe”,表示 process_name 的值在其中的记录则为 True,否则为 False。

最后点击 “确认”。

4.5.4 计算停留时长
原始日志只记录了焦点切换的时刻,没有直接给出停留时长。但通过前后两条记录的 event_seconds 相减,就能算出用户在每个窗口上停留了多久。这个时长是后续聚合总使用时长的基础数据。
这一步骤需要用到 3 个组件:
排序记录:按 session_id 和 event_seconds 升序排列,确保同一个会话内的行为按时间顺序处理
分析查询:获取同一会话内下一行的 event_seconds 值,存入新字段 next_event_seconds
计算器:计算 next_event_seconds - event_seconds 得到停留时长 duration_sec
首先,“排序记录” 组件在上一步骤已经拖入了,双击 “排序记录” 组件,按 session_id 和 event_seconds 升序排列。

拖拽 “分析查询” 组件到画布中,创建 “排序记录” 组件到 “分析查询” 组件的连线。分析查询

双击 “分析查询” 组件,分组字段为 “session_id”,新增加的字段为 “next_event_seconds”,要取值的字段为 “event_seconds”,类型 “前第 N 行”,N 为 “1”,获取同一会话内下一行的 event_seconds 值,存入新字段 next_event_seconds。

拖拽 “计算器” 组件到画布中,创建 “分析查询” 组件到 “计算器” 组件的连线。

双击 “计算器” 组件,插入新字段行,新字段输入 “duration_sec”,计算公式选择 “A - B”,字段 A 选择 “next_event_seconds”,字段 B 选择 “event_seconds”,值类型为 “Integer”。

4.5.5 字段选择:保留必要字段
使用 “字段选择” 组件,只保留 user_id, process_name, session_start_time, url, duration_sec 字段。


4.5.6 过滤记录:筛选停留时长 > 0 的数据
使用 “过滤记录” 组件,过滤掉 duration_sec <= 0 的记录,因为最后一条记录没有下一条,时长无效,需要忽略。

4.5.7 剪切字符串:提取日期
后续很多分析需要按天、按时段聚合,比如每日使用时长、时段热力图。提前提取好日期和小时,后续分组时直接使用,避免重复解析。
session_start_time 的格式为:yyyy-MM-dd HH:mm:ss,通过剪切字符串组件可以直接获取 yyyy-MM-dd。
拖拽剪切字符串组件到画布中,创建过滤记录 1 组件到拖拽剪切字符串组件的连线,连接线类型选择 “True 输出”,剪切字符串组件的配置如下。

4.5.8 字段选择:设置日期格式
目前获取的数据中,session_start_time 的类型为 String,为方便提前提取好小时,需要将 session_start_time 的类型设置为 Date。
拖拽字段选择组件到画布中,创建剪切字符串组件到字符选择组件的连线,连接线类型选择 “主输出步骤”,字段选择 2 组件的配置如下。

4.5.9 计算器:提取小时
通过计算器组件,可以提取 yyyy-MM-dd HH:mm:ss 中的 HH,拖拽计算器组件到画布中,创建字符选择组件到计算器组件的连线,连接线类型选择 “主输出步骤”,计算器 1 组件的配置如下。

4.5.10 生成用户 - 日 - 浏览器 - 小时明细
原始数据是每条窗口切换记录,粒度太细。真正关心的是 “每个用户每天每浏览器每小时用了多久、启动了几次”。这一步将数据压缩到合适的粒度,同时为后续所有统计表提供统一的基础数据。
接下来就可以使用分组聚合组件来统计用户每天使用浏览器的时段数据了,但在分组聚合前,先使用排序记录组件进行排序,避免分组聚合结果出错。
拖拽排序记录组件到画布中,创建 “计算器 1” 组件到 “排序记录 1” 组件的连线,排序记录 1 组件的配置如下。

接下来,拖拽分组组件,创建 “排序记录 1” 组件到分组组件的连线,分组组件的配置如下。

以上步骤获取的数据已经是比较合适颗粒度的数据了,可以以此为基础,抽取不同维度的数据,以便用来实现后续的可视化分析。
4.5.11 分支 A:生成市场格局表
该分支的目标是统计每个浏览器的总用户数和总使用时长。
这两个指标直接回答 “哪种浏览器覆盖最广、用得最久”。去重计数能避免同一用户被重复计算,总时长反映真实使用强度。
拖拽分组组件到画布中,创建 “分组” 组件到 “分组 1” 组件的连线。

“分组 1” 组件只按 process_name 分组。
聚合规则:
user_count = COUNT (user_id) ,统计有多少不同用户使用过该浏览器
total_duration = SUM (total_duration_sec) ,统计所有用户的累计使用时长

分组聚合的结果需要落地数据库,拖拽 “表输出” 组件到画布中,创建 “分组 1” 组件到 “表输出组件的连线”。表输出组的配置如下。


4.5.12 分支 B:生成时段统计表
该分支的目标是统计每个浏览器在每个小时的使用情况,用于分析用户的时间段偏好。
通过这张表可以绘制柱状图或折线图,展示不同浏览器的使用高峰时段。例如,白天工作时间 Chrome 使用量高,晚上娱乐时段 360 浏览器更活跃。按小时聚合已经足够,不需要更细的粒度。
此分支的分组字段包含浏览器、小时,即 process_name、hour,而前一个排序记录只对 process_name 排序,所以在这里需要按照 process_name、hour 升序排序。
拖拽 “排序记录” 组件到画布中,创建 “分组” 组件到 “排序记录 2” 组件的连线,数据传输模式选择复制发送。

“排序记录 2” 组件的配置如下。

拖拽分组组件到画布中,创建 “排序记录 2” 组件到 “分组 2” 组件的连线。

“分组 2” 组件按 process_name、hour 分组。
聚合规则:active_user_count =user_id 个数

分组聚合的结果需要落地数据库,拖拽 “表输出” 组件到画布中,创建分组 2组件到表输出 1 组件的连线。表输出组的配置如下。


4.5.13 执行转换流
点击运行按钮。

4.5.14 查看结果
点击 “元数据” tab 选项,右键团队私有数据,并点击 “加载元数据”。

接着点击 “数据探查”,可以看到团队私有数据库目录。
点击 browser_coverage、browser_hourly 两个数据表,查询数据情况,确认数据符合预期。


五、实验结果
5.1 结构化数据转换结果
完成 20 份原始 TXT 半结构化日志的全量解析,成功提取文件名中的用户 ID、会话启动时间等信息,拆分日志内行为时间、进程名、访问 URL 等核心字段,最终生成标准结构化行为记录,全部入库 behavior_events 明细表。
完成字段规整与冗余数据清理,解决了原始日志无固定行列结构、无法直接用于统计分析的问题,实现半结构化数据到结构化数据的标准化转换。
5.2 进程统计结果
完成全量行为数据的进程维度聚合,生成 program_stats 统计表,完成数百个进程的用户覆盖规模统计。
通过可视化分析确认,浏览器类进程的用户覆盖率显著高于其他软件,其中 chrome.exe、360se.exe远高于 QQ、Office 等其他软件,最终确定浏览器为本次实验的核心分析对象。
5.3 浏览器维度加工结果
完成全量浏览器行为数据的清洗与指标计算,通过同一会话前后行行为时间差,计算出单条行为的用户停留时长,过滤无效记录后,生成用户 - 日 - 浏览器 - 小时粒度的统一明细数据。
生成 browser_coverage 市场格局表,统计 6 款主流浏览器的用户覆盖与总使用时长,其中 360se.exe 总使用时长最高达 1.12 亿秒,iexplore.exe 用户覆盖量最高。
生成 browser_hourly 时段统计表,完成浏览器 × 小时维度的活跃用户统计,覆盖 0-23 全时段,可直接支撑用户使用时段偏好、浏览器使用高峰等分析场景。
六、问题与解决
问题1:
Java 代码组件解析日志时,输出字段无法被后续组件识别,字段选择组件找不到目标字段。
解决:检查 Java 代码中定义的输出字段,在组件的输出字段配置页,逐一添加所有输出字段,保证字段名称、数据类型与代码完全一致,重新运行后字段正常输出。
问题2:
分组聚合组件统计结果异常,出现重复分组、用户计数错误的情况。
解决:分组前未对数据按分组字段排序,导致分组逻辑出错。添加排序记录组件,按分组字段升序排列后再执行分组,统计结果恢复正常。
问题3:
表输出组件插入数据失败,提示字段不匹配,数据无法入库。
解决:手动核对数据库表字段与流字段的名称、类型差异,在表输出的数据库字段配置页,修正字段映射关系,保证流字段与数据库表字段一一对应,重新执行后数据成功入库。
问题4:
计算用户停留时长时,出现大量负数与空值,导致总使用时长统计异常。
解决:每个会话的最后一条行为记录无下一行数据,计算出的时长为无效值。添加过滤记录组件,筛选停留时长大于 0 的记录,过滤无效数据后,时长统计结果恢复正常。
七、实验总结
本次实验完整掌握了半结构化用户行为日志的处理流程,学会了从文件名解析、文本内容拆分、字段提取到格式规整的全流程操作,能独立将零散的原始日志转化为可直接分析的结构化数据表。
熟练掌握了 ETL 工具的核心组件操作,包括批量文件读取、自定义代码解析、字段筛选、数据过滤、排序聚合、数据入库等,能独立完成从原始数据到分析指标的全链路加工。
理解了用户行为数据加工的核心逻辑,原始的单条行为记录没有业务价值,需要经过清洗、去重、指标衍生、多维度聚合,才能转化为能支撑业务分析的有效指标。
体会到数据加工的严谨性,每一步的字段类型、排序规则、过滤条件都会影响最终结果,操作中需要反复校验中间结果,避免后续的分析出现偏差。
明确了数据加工的目标导向,先确定业务分析方向,再设计数据加工流程,能让数据处理更有针对性,避免无效计算和冗余字段,提升数据加工的效率。
更多推荐


所有评论(0)