层次图神经网络跨设备用户匹配 - 无ID的跨端行为拼接
Skill-HGNN-Cross-Device-Matching · 13-广告分析
1. 解决的问题
将每台设备的 URL 访问序列 $\mathcal{S}_v = \{s_1, s_2, \ldots, s_n\}$ 构建为层次异构图
2. 核心算法逻辑
将每台设备的 URL 访问序列 $\mathcal{S}_v = \{s_1, s_2, \ldots, s_n\}$ 构建为层次异构图:
3. 业务应用场景
业务问题:母婴 DTC 站在 Instagram 投广告,用户在手机看到广告、到电脑搜索品牌词下单。设备级日志显示"手机曝光零转化""电脑无广告来源"——Sankey 归因图中跨设备链路断裂,平台报告 ROAS 严重失真。需要识别"这两台设备属于同一用户",恢复真实跨端转化路径。
| 字段 | 类型 | 示例 | |------|------|------| | `device_id` | str | `"mob_a3f9c2"` / `"pc_b71e44"` | | `url_sequence` | List[str] | `["instagram.com/reel/xxx", "google.com/search?q=品牌", "brand.com/product/abc"]` | | `timestamp_sequence` | List[datetime] | `[2025-03-01 10:15, 2025-03-01 10:16, ...]` | | `d
- 最小要求:每设备至少 20 条匿名 URL 日志(时间跨度 2-4 周) - 数据来源:独立站服务端日志(不依赖第三方 Cookie),通过 IP + User-Agent 初步聚类生成 device_id - 隐私合规:URL 仅保留 domain+path 前两级,不含查询参数中的个人信息
4. 输入数据要求
请查看原始代码模板获取输入规格。
5. 输出结果
请查看原始代码模板获取输出规格。
6. 业务价值 / ROI
⭐⭐⭐⭐☆
7. 代码模板
代码块数量:2 · 路径:未检测到
"""
HGNN Cross-Device Matching — 完整实现
arXiv:2304.03215 (NVIDIA, 2023)
依赖: torch>=2.0, torch_geometric>=2.4, numpy, scikit-learn
"""
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch_geometric.data import HeteroData, Batch
from torch_geometric.nn import MessagePassing, HeteroConv
import numpy as np
from typing import List, Tuple, Dict, Optional
from sklearn.metrics import f1_score, precision_score, recall_score
# ============================================================
# 1. 层次图构建
# ============================================================
def build_hierarchical_graph(
url_sequence: List[int],
K: int = 6,
url_embed_dim: int = 64,
url_vocab_size: int = 10000,
) -> HeteroData:
"""
将 URL 访问序列转换为层次异构图(Fine + Coarse 节点)。
Args:
url_sequence: URL ID 列表(已编码为整数)
K: 每 K 个连续 URL 分配一个 coarse 节点
url_embed_dim: URL embedding 维度
url_vocab_size: URL 词表大小
Returns:
HeteroData,包含 fine 节点、coarse 节点及其连边
"""
data = HeteroData()
# --- Fine 节点 ---
# 去重 URL,保留首次出现顺序
unique_urls = list(dict.fromkeys(url_sequence))
url_to_idx = {url: i for i, url in enumerate(unique_urls)}
n_fine = len(unique_urls)
# Fine 节点特征:URL ID embedding(训练时替换为 Doc2vec/TF-IDF 向量)
fine_node_ids = torch.tensor(unique_urls, dtype=torch.long) # 用于 embedding lookup
data['fine'].x = fine_node_ids
data['fine'].num_nodes = n_fine
# Fine → Fine 有向边(相邻 URL 对,含自环)
src, dst = [], []
for i in range(len(url_sequence) - 1):
s = url_to_idx[url_sequence[i]]
d = url_to_idx[url_sequence[i + 1]]
src.append(s)
dst.append(d)
8. 论文来源
- 2304.03215