用户新增预测——baseline学习笔记

news2025/1/20 19:07:32

一、赛题理解

1. 赛题名称

        用户新增预测挑战赛

2. 赛题数据集

        赛题数据由约62万条训练集、20万条测试集数据组成,共包含13个字段。其中uuid为样本唯一标识,eid为访问行为ID,udmap为行为属性,其中的key1到key9表示不同的行为属性,如项目名、项目id等相关字段,common_ts为应用访问记录发生时间(毫秒时间戳),其余字段x1至x8为用户相关的属性,为匿名处理字段。target字段为预测目标,即是否为新增用户。

3. 赛题链接 

2023 iFLYTEK A.I.开发者大赛-讯飞开放平台 (xfyun.cn)


4. 评估指标

        F1 score,具体公式如下: 

Precision_i = \frac{TP_i}{TP_i + FP_i} Recall_i = \frac{TP_i}{TP_i + FN_i}

F1_i = \frac{2 \cdot Precision_i \cdot Recall_i}{Precision_i + Recall_i}

二、数据竞赛开发步骤

1. 问题分析

        问题分析是竞赛的第一步,它涉及对问题进行定义、目标明确化和数据需求的识别。

2.  数据清洗

        在采集数据完后,对数据进行数据清洗,即把采集到的、不适合用来做机器学习训练的数据进行预处理,从而转化为适合机器学习的数据。

3. 数据探索

        对清洗后的数据进行可视化和统计分析的过程。通过数据探索,可以深入了解数据的特征、分布、相关性等情况,发现数据之间的模式和趋势,为特征工程和特征筛选提供指导。常见的数据探索方法包括绘制直方图、散点图、箱线图等图形,计算统计指标如均值、方差、相关系数等。

4. 特征工程

        根据数据的领域知识和探索结果,对原始数据进行变换、组合、衍生等操作,以创建更有意义、更能表达问题特征的新特征。好的特征工程可以提高模型的性能和泛化能力。常见的特征工程包括特征缩放、编码分类变量、处理时间序列数据、创建多项式特征等。

5. 特征筛选 

        通过一定的评估方法选择对模型训练最有用的特征,去除冗余或不相关的特征。这样可以降低模型复杂度,加快训练速度,减少过拟合的可能性,并提高模型的解释性。常见的特征筛选方法包括基于统计的方法、基于模型的方法和基于特征重要性的方法。

6. 模型训练

        使用清洗、探索和筛选后的数据来训练机器学习模型的过程。根据问题的类型和数据的特点,可以选择合适的机器学习算法和模型架构进行训练。训练过程涉及优化模型参数,使其能够最好地拟合训练数据,并能在未见过的数据上泛化。

7. 模型保存 

        模型训练完成后,需要将训练得到的模型保存起来,以便在后续部署和使用中使用。模型保存可以包括保存模型权重、参数和架构,以及相关的辅助信息。在实际应用中,保存的模型可以用于预测新数据的结果或作为其他任务的基础。

        当然,对于上面的特征工程不是一步到位的,而是不断的通过模型训练的结果进行不断的优化调整,直到最优的特征组合。

三、 baseline详细解读

1. 数据读取

# 1. 导入需要用到的相关库
# 导入 pandas 库,用于数据处理和分析
import pandas as pd
# 导入 numpy 库,用于科学计算和多维数组操作
import numpy as np
# 从 sklearn.tree 模块中导入 DecisionTreeClassifier 类
# DecisionTreeClassifier 用于构建决策树分类模型
from sklearn.tree import DecisionTreeClassifier


# 2. 读取训练集和测试集
# 使用 read_csv() 函数从文件中读取训练集数据,文件名为 'train.csv'
train_data = pd.read_csv('用户新增预测挑战赛公开数据/train.csv')
# 使用 read_csv() 函数从文件中读取测试集数据,文件名为 'test.csv'
test_data = pd.read_csv('用户新增预测挑战赛公开数据/test.csv')

2. 特征构造

(1)对'udmap' 列进行 One-Hot 编码 

# 数据样例:
#                    udmap  key1  key2  key3  key4  key5  key6  key7  key8  key9
# 0           {'key1': 2}     2     0     0     0     0     0     0     0     0
# 1           {'key2': 1}     0     1     0     0     0     0     0     0     0
# 2  {'key1': 3, 'key2': 2}   3     2     0     0     0     0     0     0     0
# 具体实现代码:
# 定义函数 udmap_onethot,用于将 'udmap' 列进行 One-Hot 编码
def udmap_onethot(d):
    v = np.zeros(9)  # 创建一个长度为 9 的零数组
    if d == 'unknown':  # 如果 'udmap' 的值是 'unknown'
        return v  # 返回零数组
    d = eval(d)  # 将 'udmap' 的值解析为一个字典
    for i in range(1, 10):  # 遍历 'key1' 到 'key9'
        if 'key' + str(i) in d:  # 如果当前键存在于字典中
            v[i-1] = d['key' + str(i)]  # 将字典中的值存储在对应的索引位置上
            
    return v  # 返回 One-Hot 编码后的数组
    
# 使用 apply() 方法将 udmap_onethot 函数应用于每个样本的 'udmap' 列
# np.vstack() 用于将结果堆叠成一个数组
train_udmap_df = pd.DataFrame(np.vstack(train_data['udmap'].apply(udmap_onethot)))
test_udmap_df = pd.DataFrame(np.vstack(test_data['udmap'].apply(udmap_onethot)))
# 为新的特征 DataFrame 命名列名
train_udmap_df.columns = ['key' + str(i) for i in range(1, 10)]
test_udmap_df.columns = ['key' + str(i) for i in range(1, 10)]
# 将编码后的 udmap 特征与原始数据进行拼接,沿着列方向拼接
train_data = pd.concat([train_data, train_udmap_df], axis=1)
test_data = pd.concat([test_data, test_udmap_df], axis=1)

(2) 编码 udmap 是否为空

# 使用比较运算符将每个样本的 'udmap' 列与字符串 'unknown' 进行比较,返回一个布尔值的 Series
# 使用 astype(int) 将布尔值转换为整数(0 或 1),以便进行后续的数值计算和分析
train_data['udmap_isunknown'] = (train_data['udmap'] == 'unknown').astype(int)
test_data['udmap_isunknown'] = (test_data['udmap'] == 'unknown').astype(int)

 (3)提取 eid 的频次特征和标签特征

# 使用 map() 方法将每个样本的 eid 映射到训练数据中 eid 的频次计数
# train_data['eid'].value_counts() 返回每个 eid 出现的频次计数
train_data['eid_freq'] = train_data['eid'].map(train_data['eid'].value_counts())
test_data['eid_freq'] = test_data['eid'].map(train_data['eid'].value_counts())

# 使用 groupby() 方法按照 eid 进行分组,然后计算每个 eid 分组的目标值均值
# train_data.groupby('eid')['target'].mean() 返回每个 eid 分组的目标值均值
train_data['eid_mean'] = train_data['eid'].map(train_data.groupby('eid')['target'].mean())
test_data['eid_mean'] = test_data['eid'].map(train_data.groupby('eid')['target'].mean())

 (4)提取时间戳

# 使用 pd.to_datetime() 函数将时间戳列转换为 datetime 类型
# 样例:1678932546000->2023-03-15 15:14:16
# 具体实现代码:
train_data['common_ts'] = pd.to_datetime(train_data['common_ts'], unit='ms')
test_data['common_ts'] = pd.to_datetime(test_data['common_ts'], unit='ms')

# 使用 dt.hour 属性从 datetime 列中提取小时信息,并将提取的小时信息存储在新的列 'common_ts_hour'
train_data['common_ts_hour'] = train_data['common_ts'].dt.hour
test_data['common_ts_hour'] = test_data['common_ts'].dt.hour


3. 模型训练

        加载决策树模型进行训练(直接使用sklearn中导入的包进行模型建立);

        对测试集进行预测,并保存结果到result_df中;

        保存结果文件到本地

clf = DecisionTreeClassifier()
# 使用 fit 方法训练模型
# train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1) 从训练数据集中移除列 'udmap', 'common_ts', 'uuid', 'target'
# 这些列可能是特征或标签,取决于数据集的设置
# train_data['target'] 是训练数据集中的标签列,它包含了每个样本的目标值
clf.fit(
    train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1),  # 特征数据:移除指定的列作为特征
    train_data['target']  # 目标数据:将 'target' 列作为模型的目标进行训练
)


# 9. 对测试集进行预测,并保存结果到result_df中
# 创建一个DataFrame来存储预测结果,其中包括两列:'uuid' 和 'target'
# 'uuid' 列来自测试数据集中的 'uuid' 列,'target' 列将用来存储模型的预测结果
result_df = pd.DataFrame({
    'uuid': test_data['uuid'],  # 使用测试数据集中的 'uuid' 列作为 'uuid' 列的值
    'target': clf.predict(test_data.drop(['udmap', 'common_ts', 'uuid'], axis=1))  # 使用模型 clf 对测试数据集进行预测,并将预测结果存储在 'target' 列中
})


# 10. 保存结果文件到本地
# 将结果DataFrame保存为一个CSV文件,文件名为 'submit.csv'
# 参数 index=None 表示不将DataFrame的索引写入文件中
result_df.to_csv('submit.csv', index=None)

 四、后续提升方案

1. 构建交叉训练框架

def cv_model(clf, train_x, train_y, test_x, clf_name, seed = 23):
    folds = 5
    kf = KFold(n_splits=folds, shuffle=True, random_state=seed)
    oof = np.zeros(train_x.shape[0])
    test_predict = np.zeros(test_x.shape[0])
    cv_scores = []
    
    for i, (train_index, valid_index) in enumerate(kf.split(train_x, train_y)):
        print('************************************ {} ************************************'.format(str(i+1)))
        trn_x, trn_y, val_x, val_y = train_x.iloc[train_index], train_y[train_index], train_x.iloc[valid_index], train_y[valid_index]
            
        if clf_name == "cat":
            params = {'learning_rate': 0.03, 'depth': 6, 'bootstrap_type':'Bernoulli','random_seed':2023,
                      'od_type': 'Iter', 'od_wait': 100, 'random_seed': 23, 'allow_writing_files': False, 'task_type' : 'GPU'}
            
            model = clf(iterations=20000, **params, eval_metric='F1')
            model.fit(trn_x, trn_y, eval_set=(val_x, val_y),
                      metric_period=100,
                      use_best_model=True, 
                      cat_features=[],
                      verbose=1)
            
            val_pred  = model.predict_proba(val_x)[:,1]
            test_pred = model.predict_proba(test_x)[:,1]
        
        oof[valid_index] = val_pred
        test_predict += test_pred / kf.n_splits
        
        F1_score = f1_score(val_y, [1 if prob >= 0.5 else 0 for prob in val_pred])
        cv_scores.append(F1_score)
        print(cv_scores)
        
    return oof, test_predict

2. 特征筛选

(1)相关性

        通过统计单个特征与目标变量之间的相关性,选取相关性较高的特征。

(2)递归特征消除

        通过递归地拟合模型并去除对模型性能贡献较小的特征,直到达到所需的特征数量

(3)特征重要性

        通过查看模型内部的特征重要性指标

(4)具有空重要性的特征选择

        使用目标排列的特征选择过程测试与噪声(混洗目标)拟合时特征重要性分布的实际重要性显着性。

Feature Selection with Null Importances | Kaggle

强烈推荐此方案 

3. 特征交叉

        选取特征重要性排名靠前进行特征交叉,可以选择排名靠前的特征组合来构建新的特征,从而增强模型的表现。

4. 模型调参

        机器学习和深度学习中,通过调整模型的超参数来优化模型性能。超参数是在模型训练之前设置的参数,它们不会在训练过程中自动学习,而需要手动选择。

        一般常用的调参方法:

        a. 网格搜索(Grid Search):遍历所有超参数的组合,逐一尝试。虽然它是全面搜索,但在超参数空间较大时计算代价较高。

         b. 随机搜索(Random Search):随机从超参数空间中抽取组合进行尝试。相比网格搜索,它的计算代价较低,但可能需要更多的尝试次数。

         c. 贝叶斯优化(Bayesian Optimization):通过构建超参数组合的概率模型,根据模型对性能的估计来选择最有可能改善性能的组合。

         d. 遗传算法(Genetic Algorithms):借鉴自然进化的原理,通过基因交叉和变异等方式逐渐优化超参数组合。

        网格搜索一般在数据量很大时不建议使用,会导致迭代的次数很多,而无法跑出最优的参数组合。强烈建议使用贝叶斯优化进行模型调参

5. 特征构造

        (1)eid存在多个数据样本,可以进行mean,max,min,std,skew等数据的统计。

        (2)补充完整频次特征和标签特征;

        (3)提取更多的时间信息;

        (4)对label进行阈值调整

 6. stacking集成

        stacking是一种分层模型集成框架。以两层为例,第一层由多个基学习器组成,其输入为原始训练集,第二层的模型则是以第一层基学习器的输出作为特征加入训练集进行再训练,从而得到完整的stacking模型。

五、降低内存方法

        比赛按照上面的baseline会读取较大的数据内存,因此在此处放入一个降低内存的方法:

        通过减少数字列的数据类型并将对象列转换为分类类型来优化 DataFrame 'train_df' 的内存使用量,从而减少内存使用量。

predictor_columns = [col for col in test_df.columns if col not in ['uuid','time','file']]
def reduce_mem_usage(df):
    start_mem = df.memory_usage().sum() / 1024**2
    print('Memory usage of dataframe is {:.2f} MB'.format(start_mem))
    for col in tqdm.tqdm(predictor_columns):
        col_type = df[col].dtype
        if col_type != object:
            c_min = df[col].min()
            c_max = df[col].max()
            if str(col_type)[:3] == 'int':
                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
                    df[col] = df[col].astype(np.int8)
                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
                    df[col] = df[col].astype(np.int16)
                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
                    df[col] = df[col].astype(np.int32)
                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:
                    df[col] = df[col].astype(np.int64)
            else:
                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:
                    df[col] = df[col].astype(np.float16)
                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
                    df[col] = df[col].astype(np.float32)
                else:
                    df[col] = df[col].astype(np.float64)
        else:
            df[col] = df[col].astype('category')
    end_mem = df.memory_usage().sum() / 1024**2
    print('Memory usage after optimization is: {:.2f} MB'.format(end_mem))
    print('Decreased by {:.1f}%'.format(100 * (start_mem - end_mem) / start_mem))
    return df
 
train_df = reduce_mem_usage(train_df)

 https://datawhaler.feishu.cn/docx/HBIHd7ugzoOsMqx0LEncR1lJnCf

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/895633.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

项目管理敏捷管理流程,高效敏捷项目管理解决方案

Leangoo领歌是一款永久免费的专业敏捷研发管理工具&#xff0c;提供敏捷研发解决方案&#xff0c;解决研发痛点&#xff0c;打造成功产品。帮助团队实现需求、迭代、缺陷、任务、测试、发布等全方位研发管理。 敏捷产品路线图管理&#xff1a; 产品路线图是一个高层次的战略计…

服务器数据库中了360后缀勒索病毒怎么办?360后缀勒索病毒的加密形式

随着信息技术的发展&#xff0c;企业的计算机服务器数据库变得越来越重要。然而&#xff0c;在数字时代&#xff0c;网络上的威胁也日益增多。近期&#xff0c;我们收到很多企业的求助&#xff0c;企业的计算机服务器遭到了360后缀勒索病毒的攻击&#xff0c;导致服务器内的所有…

DevExpress VCL Subscription Crack

DevExpress VCL Subscription Crack Developer Express VCL Subscription包括VCL组件&#xff0c;用于&#xff1a;数据输入、图表、数据分析、导航、布局、网格、日程安排、样式、报告、打印和规划。Developer Express VCL Subscription支持Delphi XE7、XE8、10 Seattle、10.1…

Nacos - 安装指南(Windows系统)

一、下载安装包 Nacos现在虽然已经出到二点几的版本&#xff0c;但二点几版本还处在测试阶段&#xff0c;我们选择下载成熟的 1.4.6 版本 下载地址&#xff1a;Nacos 1.4.6 GitHub的Release下载页 拉到页面最底部&#xff0c;可以看到下载按钮&#xff0c;windows版本使用naco…

LeetCode——二叉树篇(四)

刷题顺序及思路来源于代码随想录&#xff0c;网站地址&#xff1a;https://programmercarl.com 二叉树的定义及创建见&#xff1a; LeetCode ACM模式——二叉树篇&#xff08;一&#xff09;_要向着光的博客-CSDN博客 101. 对称二叉树 给你一个二叉树的根节点 root &#xf…

【Flink】Flink窗口触发器

数据进入到窗口的时候,窗口是否触发后续的计算由窗口触发器决定,每种类型的窗口都有对应的窗口触发机制。WindowAssigner 默认的 Trigger通常可解决大多数的情况。我们通常使用方式如下,调用trigger()方法把我们想执行触发器传递进去: SingleOutputStreamOperator<Produ…

Python Opencv实践 - 图像高斯滤波(高斯模糊)

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/pomeranian.png", cv.IMREAD_COLOR) rows,cols,channels img.shape print(rows,cols,channels)#为图像添加高斯噪声 #使用np.random.normal(loc0.0, scale1.0…

NFT Insider #103:The Sandbox 与音乐天才Agoria携手,Intela X宣布与YGG建立合作关系

引言&#xff1a;NFT Insider由NFT收藏组织WHALE Members、BeepCrypto联合出品&#xff0c;浓缩每周NFT新闻&#xff0c;为大家带来关于NFT最全面、最新鲜、最有价值的讯息。每期周报将从NFT市场数据&#xff0c;艺术新闻类&#xff0c;游戏新闻类&#xff0c;虚拟世界类&#…

List Label Standard Reporting Edition Crack

List & Label Standard Reporting Edition Crack List&Label是适用于所有主要开发平台的报告解决方案&#xff0c;提供了强大的报告引擎、灵活的API和功能丰富的报告设计器。只需要几行代码就可以在桌面、web或云应用程序中嵌入List&Label。它允许您的应用程序用户…

keepalived集群

keepalived概述 keepalived软件就是通过vrrp协议来实现高可用功能。 VRRP通信原理 VRRP就是虚拟路由冗余协议&#xff0c;它的出现就是为了解决静态路由的单点故障。 VRRP是通过一种竞选一种协议机制来将路由交个某台VRRP路由器。 VRRP 用IP多播的方式&#xff08;多播地…

优先级队列【C++】

文章目录 priority_queuepriority_queue 使用priority_queue的模拟实现向上调整算法向下调整算法pushpoptopsizeempty 仿函数完整代码 priority_queue 优先队列&#xff08;priority_queue&#xff09;也是队列的一种&#xff0c;priority_queue的接口是和queue的接口是相同的…

一篇文章了解Java spring中bean的生命周期!

一.介绍在Java spring中bean的生命周期 1.什么是 Bean&#xff1f; 我们来看下 Spring Framework 的官方文档&#xff1a; In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean …

xcode14.3更新一系列问题

1. Missing file libarclite_iphoneos.a (Xcode 14.3) 解决方法 Xcode升级到14.3后编译失败&#xff0c;完整错误日志&#xff1a; File not found: /Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphoneo…

OpenCV-Python中的图像处理-GrabCut算法交互式前景提取

OpenCV-Python中的图像处理-GrabCut算法交互式前景提取 Python-OpenCV中的图像处理-GrabCut算法交互式前景提取 Python-OpenCV中的图像处理-GrabCut算法交互式前景提取 cv2.grabCut(img: Mat, mask: typing.Optional[Mat], rect, bgdModel, fgdModel, iterCount, mode…) img…

linux训练深度学习模型:文件基本操作

解压.zip unzip XXX.zip 创建目录&#xff1a; mkdir data 在当前目录下创建下一级目录 移动文件&#xff1a; mv /data1/census.csv /data1/data 要写全目录路径&#xff0c;不然会跑到根目录那里去。 复制文件到当前目录下&#xff0c;并重命名 cp main.py ./main…

CSS基础 知识点总结

一.CSS简介 1.1 CSS简介 ① CSS指的是层叠样式表&#xff0c;用来控制网页外观的一门技术 ② CSS发展至今&#xff0c;经历过CSS1.0 CSS2.0 CSS2.1 CSS3.0这几个版本&#xff0c;CSS3.0是CSS最新版本 1.2 CSS引入方式 ① 在一个页面引入CSS&#xff0c;共有三种方式 外部…

《一个操作系统的实现》windows用vm安装CentOS——从bochs环境搭建到第一个demo跑通

vm安装CentOS虚拟机带有桌面的版本。su输入密码123456。更新yum -y update 。一般已经安装好后面这2个工具&#xff1a;yum install -y net-tools wget。看下ip地址ifconfig&#xff0c;然后本地终端连接ssh root192.168.249.132输入密码即可&#xff0c;主要是为了复制网址方便…

基于SOLIDWORKS配置功能建立塑料模具标准件库

在塑料模具的设计过程中&#xff0c;建立其三维模型对于后续进行CAE分析和CAM加工是非常重要的。除了型腔和型芯以外&#xff0c;塑料模具中的标准件很多&#xff0c;如推杆、导柱、导套、推板、限位钉等&#xff0c;这些对于不同的产品是需要反复调用的。目前&#xff0c;我国…

GWAS-eQTL colocalization analysis workflow

1. The purpose of GWAS-eQTL intergration Is the my variant an eQTL?Is the leading variant of the GWAS and eQTL signal the same?Is my GWAS association of interest driven by an eQTL that may indiciate a functinal mechanism? GWAS locus that colocalized w…

IntelliJ IDEA 官方网站 idea官网 http://www.jetbrains.com/idea/

IntelliJ IDEA 官方网站 idea官网 http://www.jetbrains.com/idea/ Idea下载官网一键直达&#xff1a; 官网一键直达