飞桨常规赛:点击反欺诈预测-10月第2名方案


本文围绕广告欺诈预测这一二分类任务展开,流程涵盖数据分析、特征工程等。对类别特征用Embedding处理,连续特征标准化;模型维持baseline结构,含embedding、concat等层,采用RMSProp优化器与交叉熵损失。还指出可从特征工程、模型结构等方面改进。

☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

1 赛题背景

广告欺诈是数字营销需要面临的重要挑战之一,点击会欺诈浪费广告主大量金钱,同时对点击数据会产生误导作用。本次比赛提供了约50万次点击数据。特别注意:我们对数据进行了模拟生成,对某些特征含义进行了隐藏,并进行了脱敏处理。

请预测用户的点击行为是否为正常点击,还是作弊行为。点击欺诈预测适用于各种信息流广告投放,banner广告投放,以及百度网盟平台,帮助商家鉴别点击欺诈,锁定精准真实用户。

2 任务分析

根据赛题设置,本任务为二分类任务; 根据数据挖掘与机器学习的一般任务流程,将按照下述流程完成该任务:

  1. 数据分析
  2. 特征工程
  3. 模型构建
  4. 模型训练
  5. 模型调优
  6. 模型推理

其中,模型调优部分同时涉及数据的再处理(比如选用新的特征工程方案)以及模型结构、优化方法、损失函数等方面的优化

3 解决方案

基于比赛提供的baseline实现,按照以下思路进行:

  1. 对于结构化数据中的各字段,进行稠密向量嵌入式表示;并将嵌入维度作为超参数进行调优;
  2. 维持baseline模型的基本结构不变,调整优化器及其学习率等训练超参数;

4 数据分析

在本赛题中,由于数据形式为结构化数据,为了对数据进行更好的表示以便神经网络模型能够充分挖掘数据背后的模式与规律,参照自然语言处理(NLP)中的字词方法,对数据的各字段进行稠密向量的嵌入式表示,即embedding方法。

简单而言,Embedding方法就是用一个低维的向量表示一个物体,可以是一个词,一个商品,或是一部电影等。这个向量能使距离相近的向量对应的物体有相近的含义,比如“复仇者联盟”对应的向量和“钢铁侠”对应的向量之间的距离(欧几里得距离,汉明距离等)就会很小,但 “复仇者联盟”对应的向量和“乱世佳人”对应的向量之间的距离就会大一些。 此外,Embedding形式的表示使得其背后所代表的“物体”具有数学运算关系,比如:Embedding(马德里)-Embedding(西班牙)+Embedding(法国)≈Embedding(巴黎)。

Embedding能够用低维向量对物体进行编码还能保留其含义的特点非常适合深度学习。在传统机器学习模型构建过程中,经常使用onehot编码对离散特征、特别是id类特征进行编码,但由于onehot编码的维度等于物体的类别总数,这样的编码方式对于类别型变量来说是极端稀疏的,而深度学习的特点使其不利于对稀疏特征向量的处理。

因此,在本任务中,先对数据集中的类别型变量进行嵌入式表示(连续性变量进行标准化),将处理之后的字段输入到神经网络模型中用以分类。

5 模型分析

本任务中,模型结构维持baseline提供的模型结构基本不变,其主要由embedding层、concat层以及dense层组成,embedding层用于获取每个输入字段值的嵌入式表示向量,concat层用于拼接所有字段的表示向量成为一个总的样本特征向量,dense层用于转换数据大小,其中模型最后一层的输出维度为2(类别数目),激活函数使用softmax函数。

关于模型的优化器与损失函数,优化器使用RMSProp,损失函数使用分类任务常设的交叉熵损失函数。

6 总结改进

根据赛题重点,合理有效地处理数据集的各类特征是完成分类任务的关键之处。 本项目只是使用较为初级的多层感知机网络执行分类任务,项目可改进的地方包含但不限于:

进一步细化特征处理办法,深化特征工程有关工作,Embedding处理只是其中一个方法; 改进或换用预测模型结构,可以尝试使用现代深度学习框架内更为先进的神经网络模型; 更换任务思路,采用传统机器学习项目中的相关思路与模型解决该问题,如适用于结构化数据的TabNet网络。

7 飞桨使用

在使用paddlepaddle进行深度学习时,注重理论课程与实践应用的合理结合; 一方面,强调通过资料与视频课程领会框架的基本使用; 另一方面,需要结合具体应用(如参加飞桨的各类竞赛)熟练掌握数据预处理、模型构建、模型训练、模型调优与应用等深度学习各阶段操作

8 参考资料

  1. 本次竞赛的baseline代码
  2. 深入浅出Word2Vec原理解析
  3. Embedding从入门到专家必读的十篇论文

feature_process

In [ ]
import osimport pandas as pdimport numpy as npfrom paddle.io import Datasetfrom baseline_tools import *

DATA_RATIO = 0.9  # 训练集和验证集比例TAGS = {'android_id': None,        'apptype': "emb",        'carrier': "emb",        'dev_height': "emb",        'dev_ppi': "emb",        'dev_width': "emb",        'lan': "emb",        'media_id': "emb",        'ntt': "emb",        'os': "emb",        'osv': None,        'package': "emb",        'sid': None,        'timestamp': "norm",        'version': "emb",        'fea_hash': None,        'location': "emb",        'fea1_hash': None,        'cus_type': None}# 归一化权重设置NORM_WEIGHT = {'timestamp': 6.40986e-12}
In [ ]
TRAIN_PATH = "train.csv"SAVE_PATH = "emb_dicts"df = pd.read_csv(TRAIN_PATH, index_col=0)

pack = dict()for tag, tag_method in TAGS.items():    if tag_method != "emb":        continue
    data = df.loc[:, tag]
    dict_size = make_dict_file(data, SAVE_PATH, dict_name=tag)
    pack[tag] = dict_size + 1  # +1是为了增加字典中不存在的情况,提供一个默认值with open(os.path.join(SAVE_PATH, "size.dict"), "w", encoding="utf-8") as f:
    f.write(str(pack))print("全部生成完毕")

data_loading

In [ ]
def get_size_dict(dict_path="./emb_dicts/size.dict"):
    """
    获取Embedding推荐大小
    :param dict_path: 由run_make_emb_dict.py生成的size.dict
    :return: 推荐大小字典{key: num}
    """
    with open(dict_path, "r", encoding="utf-8") as f:        try:
            size_dict = eval(f.read())        except Exception as e:            print("size_dict打开失败,请检查", dict_path, "文件是否正常,报错信息如下:\n", e)        return size_dictclass Reader(Dataset):
    def __init__(self,
                 is_infer: bool = False,
                 is_val: bool = False,
                 use_mini_train: bool = False,
                 emb_dict_path="./emb_dicts"):

        """
        数据读取类
        :param is_infer: 是否为预测Reader
        :param is_val: 是否为验证Reader
        :param use_mini_train:使用Mini数据集
        :param emb_dict_path: emb字典路径
        """
        super().__init__()        # 选择文件名
        train_name = "mini_train" if use_mini_train else "train"
        file_name = "test" if is_infer else train_name        # 根据文件名读取对应csv文件
        df = pd.read_csv(file_name + ".csv")        # 划分数据集
        if is_infer:
            self.df = df.reset_index()        else:
            start_index = 0 if not is_val else int(len(df) * DATA_RATIO)
            end_index = int(len(df) * DATA_RATIO) if not is_val else len(df)
            self.df = df.loc[start_index:end_index].reset_index()        # 数据预处理
        self.cols = [tag for tag, tag_method in TAGS.items() if tag_method is not None]
        self.methods = dict()        for col in self.cols:            # ===== 预处理方法注册 =====
            if TAGS[col] == "emb":
                self.methods[col] = Data2IdEmb(dict_path=emb_dict_path, dict_name=col).get_method()            elif TAGS[col] == "norm":
                self.methods[col] = Data2IdNorm(norm_weight=NORM_WEIGHT[col]).get_method()            else:                raise Exception(str(TAGS) + "是未知的预处理方案,请选手在此位置使用elif注册")        # 设置FLAG负责控制__getitem__的pack是否包含label
        self.add_label = not is_infer        # 设置FLAG负责控制数据集划分情况
        self.is_val = is_val    def __getitem__(self, index):
        """
        获取sample
        :param index: sample_id
        :return: sample
        """
        # 因为本次数据集的字段非常多,这里就使用一个列表来"收纳"这些数据
        pack = []        # 遍历指定数量的字段
        for col in self.cols:
            sample = self.df.loc[index, col]
            sample = self.methods[col](sample)
            pack.append(sample)        # 如果不是预测,则添加标签数据
        if self.add_label:
            tag_data = self.df.loc[index, "label"]
            tag_data = np.array(tag_data).astype("int64")
            pack.append(tag_data)            return pack        else:            return pack    def __len__(self):
        return len(self.df)# 获取训练集和测试集数据读取器USE_MINI_DATA = Falsetrain_reader = Reader(use_mini_train=USE_MINI_DATA)
val_reader = Reader(use_mini_train=USE_MINI_DATA, is_val=True)

model_define

In [ ]
import osimport numpy as npimport pandas as pdimport paddleimport paddle.nn as nnimport paddle.tensor as tensorfrom paddle.static import InputSpecfrom paddle.metric import Accuracy# 模型保存与加载文件夹SAVE_DIR = "./output/"# 部分训练超参数EMB_SIZE = 256  # Embedding特征大小EMB_LINEAR_SIZE = 32  # Embedding后接Linear层神经元数量LINEAR_LAYERS_NUM = 2  # 归一化方案的Linear层数量# 组网class SampleNet(paddle.nn.Layer):
    def __init__(self, tag_dict: dict, size_dict: dict):
        super().__init__()        # 新建一个隐藏层列表,用于存储各字段隐藏层对象
        self.hidden_layers_list = []        # 定义一个用于记录输出层的输入大小变量,经过一个emb的网络结构就增加该结构的output_dim,以此类推
        out_layer_input_size = 0

        # 遍历每个字段以及其处理方式
        for tag, tag_method in tag_dict.items():            # Embedding方法注册
            if tag_method == "emb":
                hidden_layer = nn.LayerList([nn.Embedding(num_embeddings=size_dict[tag],
                                                          embedding_dim=EMB_SIZE),
                                             nn.Linear(in_features=EMB_SIZE, out_features=EMB_LINEAR_SIZE)])
                out_layer_input_size += EMB_LINEAR_SIZE            # 归一化方法注册
            elif tag_method == "norm":
                hidden_layer = nn.LayerList(
                    [nn.Linear(in_features=1, out_features=1) for _ in range(LINEAR_LAYERS_NUM)])
                out_layer_input_size += 1
            # 如果对应方法为None,那么跳过该字段
            elif tag_method is None:                continue
            # 若出现没有注册的方法,提示报错
            else:                raise Exception(str(tag_method) + "为未知的处理方案,请在SampleNet类中用elif注册处理流程")
            self.hidden_layers_list.append(hidden_layer)
        
        self.out_layers = nn.Linear(in_features=out_layer_input_size,out_features=2)    # 前向推理部分 `*input_data`的`*`表示传入任一数量的变量
    def forward(self, *input_data):
        layer_list = []  # 用于存储各字段特征结果
        for sample_data, hidden_layers in zip(input_data, self.hidden_layers_list):
            tmp = sample_data            for hidden_layer in hidden_layers:
                tmp = hidden_layer(tmp)
            layer_list.append(tensor.flatten(tmp, start_axis=1))  # flatten是因为原始shape为[batch size, 1 , *n], 需要变换为[bs, n]
        # 对所有字段的特征合并
        layers = tensor.concat(layer_list, axis=1)        # 把特征放入用于输出层的网络
        result = self.out_layers(layers)
        result = paddle.nn.functional.softmax(result)        
        # 返回分类结果
        return result
In [ ]
# 定义网络输入inputs = []for tag_name, tag_m in TAGS.items():
    d_type = "float32"
    if tag_m == "emb":
        d_type = "int64"
    if tag_m is None:        continue
    inputs.append(InputSpec(shape=[-1, 1], dtype=d_type, name=tag_name))# 定义Labellabels = [InputSpec([-1, 1], 'int64', name='label')]# 实例化SampleNetmodel = paddle.Model(SampleNet(TAGS, get_size_dict()), inputs=inputs, labels=labels)

model_config

In [ ]
from paddle.optimizer import RMSProp# 定义优化器optimizer = RMSProp(learning_rate=0.01, parameters=model.parameters())# 模型训练配置model.prepare(optimizer, paddle.nn.loss.CrossEntropyLoss(), Accuracy())

model_training

In [7]
# 开始训练model.fit(train_data=train_reader,  # 训练集数据
            eval_data=val_reader,  # 验证集数据
            batch_size=128,  # Batch size大小
            epochs=10,  # 训练轮数
            log_freq=1000,  # 日志打印间隔
            save_dir=SAVE_DIR)  # checkpoint保存路径

model_reasoning

In [ ]
# 推理部分CHECK_POINT_ID = "final"  TEST_BATCH_SIZE = 128  # 实例化SampleNetmodel = paddle.Model(SampleNet(TAGS, get_size_dict()), inputs=inputs)# 获取推理Reader并读取参数进行推理infer_reader = Reader(is_infer=True)
model.load(os.path.join(SAVE_DIR, CHECK_POINT_ID))
In [ ]
# 开始推理model.prepare()
infer_output = model.predict(infer_reader, TEST_BATCH_SIZE)# 获取原始表中的字段并添加推理结果result_df = infer_reader.df.loc[:, "sid"]
pack = []for batch_out in infer_output[0]:    for sample in batch_out:
        pack.append(np.argmax(sample))# 保存csv文件RESULT_FILE = "./result1.csv"  result_df = pd.DataFrame({"sid": np.array(result_df, dtype="int64"), "label": pack})
result_df.to_csv(RESULT_FILE, index=False)print("结果文件保存至:", RESULT_FILE)
In [ ]


# 就会  # 是一个  # 欧几里得  # 马德里  # 报错  # 等方面  # 适用于  # 遍历  # 结构化  # 进行了  # ai  # embedding  # 数据分析  # nlp  # paddlepaddle  # word2vec  # red  # csv文件  # 百度 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 网络优化91478 】 【 技术知识72672 】 【 云计算0 】 【 GEO优化84317 】 【 优选文章0 】 【 营销推广36048 】 【 网络运营41350 】 【 案例网站102563 】 【 AI智能45237


相关推荐: 文本分类与聚类:网络安全中的自然语言处理应用  ChatGPT如何进行数据可视化构思 ChatGPT图表设计指南  豆包AI怎么评价回答的好坏_点赞与反馈功能使用教程  AI驱动保险代理:最佳保险 lead generation 公司与服务  EdrawMax全面评测:使用AI轻松绘制流程图和思维导图  AI产品经理:AI赋能与AI原生,未来PM的技能演进  Tune AI: 革新音乐创作,AI音乐平台深度测评  AI数字人教程:轻松打造专属YouTube虚拟形象  Google AI Studio 中的提示词微调实验教程  AI症状自检:最佳AI症状检查器,告别网络庸医!  豆包Ai官方网页版入口地址_豆包Ai官网在线使用入口  AI赋能:五款颠覆性工具助你在线赚钱  AI心理测试生成工具有哪些_一键生成趣味测评的AI工具推荐  Android图像翻译器应用:技术、应用与未来展望  Bluecap:加拿大AI会议助手,提升混合办公效率  Jasper AI的Recipes是什么 Jasper AI配方功能使用【详解】  五大AI视频编辑工具:提升视频创作效率和质量  壹伴AI智能排版如何自动生成文章配图_壹伴AI智能排版配图生成与版权说明【教程】  如何用AI帮你设计调查问卷?科学提问,精准收集反馈  Docker MCP Toolkit:简化AI代理与外部工具的连接  AI女友:时尚穿搭与美丽瞬间的完美融合  探索孟加拉音乐魅力:高尔德普林特莎丽,节日欢歌  研究学者如何利用现有资源提升学术影响力  使用ChatGPT快速生成专辑封面:AI艺术创作指南  利用AI在五分钟内高效生成潜在客户:UpLead深度教程  Tenorshare AI Bypass:终极AI内容人性化工具深度评测  2025年冷邮件营销:技巧、工具和成功案例分享  微信AI数字人能否识别语音消息_微信AI数字人语音识别与回复设置【教程】  Google NotebookLM:AI赋能的智能笔记与思维导图工具  批改网ai检测工具如何导出检测报告_批改网ai检测工具报告导出格式【步骤】  Excel Copilot:AI驱动的强大新功能与实用案例解析  FeelinAI聊天网页版 Feelin官方网站地址  千问如何切换回答风格_千问风格选择正式口语等【实操】  Xeon E5-2667 V2性能评测:老平台焕发新生,游戏与工作负载表现分析  一键改变发型:Gemini AI 助你轻松打造时尚造型  改善面部不对称:简单有效的肌肉平衡技巧  去哪旅行ai抢票助手如何设置抢票策略_去哪旅行ai抢票助手策略配置与优先级【攻略】  YouTube SEO优化:AI驱动的标题生成工具详解  亚马逊KDP电子书掘金:月入1万美元的秘密策略  AI员工工具详解:添加与移除指南,提升效率  探索占星术:揭秘 कुंडली 中的 शुक्र,财富与运势的钥匙  AI照片编辑:为你的单人照添加逼真女友,告别孤单  AI vs. 人工书籍教练:哪个更适合你?终极指南  AIPPT:AI驱动的PPT制作工具,高效便捷演示文稿方案  DeepSeek解释机器学习模型 DeepSeek数据科学学习指南  tofai官方网站入口 tofai在线网页版登录  教你用AI帮你写一份完整的用户调研报告,从数据到结论全搞定  Mac百度输入法ai怎么关 Mac版百度ai助手禁用教程  OpenArt:终极AI内容创作平台,图像、视频和角色一致性  AI驱动的Web应用测试:突破QA挑战,提升用户体验 

 2025-07-30

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

南京市珐之弘网络技术有限公司


南京市珐之弘网络技术有限公司

南京市珐之弘网络技术有限公司专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。

 87067657

 13565296790

 87067657@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.