Datawhale机器学习笔记——1

本文详细解读了一种基于Python的用户新增预测挑战赛的Baseline代码,包括数据预处理、特征工程(如udmap的one-hot编码和时间特征提取),以及使用DecisionTreeClassifier进行模型训练。文章展示了如何从原始数据中提取有价值的信息,并提供了初步的预测结果分析。
摘要由CSDN通过智能技术生成

提示:由于本人也是小白,本文可能会非常非常基础。本系列是基于Datewhale 23年暑期夏令营第三期赛题,赛题具体内容见下方链接。

赛题链接

https://challenge.xfyun.cn/topic/info?type=subscriber-addition-prediction&ch=ymfk4uU

目录

前言

一、数据集

二、对Baseline的详解

第一段代码:

第二段代码:

第三段代码:

第四段代码:

第五段代码:

第六段代码:

第七段代码:

第八段代码:

三、总结

ps.


前言

本文对baseline代码进行详细的解释。


一、数据集

赛题数据由约62万条训练集、20万条测试集数据组成,共包含13个字段。

其中uuid为样本唯一标识(用户编号),eid为访问行为ID,udmap为行为属性,其中的key1到key9表示不同的行为属性,如项目名、项目id等相关字段,common_ts为应用访问记录发生时间(毫秒时间戳),其余字段x1至x8为用户相关的属性,为匿名处理字段。target字段为预测目标,即是否为新增用户。

二、对Baseline的详解

#NO_1

#导入相关的库
import pandas as pd
import numpy as np

#使用pd.read_csv()函数读取数据
train_data = pd.read_csv('用户新增预测挑战赛公开数据/train.csv')
test_data = pd.read_csv('用户新增预测挑战赛公开数据/test.csv')

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')

第一段代码:

  1. 导入了pandas和numpy两个常用的Python数据分析库
  2. 使用pandas的read_csv()方法分别读取了训练集train.csv和测试集test.csv
  3. 对训练集和测试集的common_ts这一列使用pd.to_datetime()进行了日期格式的转换,单位指定为ms(毫秒)
  4. 这样将common_ts这一列从原始的时间戳转换成了pandas的DateTime格式,便于后续进行时间序列分析和特征提取。
  5. 整体来说,这段代码完成了训练集和测试集的导入,并对时间戳列进行了预处理,为后续的分析建模做好了准备。

#NO_2

def udmap_onethot(d):
    v = np.zeros(9) #创建长度为9的零数组
    if d == '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

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)))

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)]

第二段代码:

         1.定义了udmap_onethot()函数,目的是将udmap这一字典格式的特征转换为固定长度的向量表示。

        2.对每个样本的udmap字典,如果是'unknown',返回全0向量。否则遍历字典的key1到key9,如果存在该key则将对应位置置1,可以理解为下图的形式(总结来说就是字典——>等长向量):

       具体理解udmap_onethot()函数,d代表每个样本的udmap字典。'key' + str(i)构造了一个变量字典键的字符串,比如'key1','key2'等。然后使用in判断这个键是否在字典d中。如果存在,则将对应的值赋给结果向量v的第i-1个元素(因为key是从1开始,但是v[]数组里从0开始)。这样就实现了有选择地将udmap字典中的键值复制到定长结果向量v中。

        3.train_udmap_df以及test_udmap_df目的是将训练集和测试集中的 udmap 字典特征转换为 DataFrame 格式。

具体来说,apply(udmap_onethot) 对 udmap 列应用自定义函数,将其转化为向量。np.vstack将向量垂直拼接,变成二维数组。pd.DataFrame是将这个二维数组转化为DataFrame

        4.train_udmap_df.columns以及test_udmap_df.columns是设定列名为key1-key9。


train_data = pd.concat([train_data, train_udmap_df], axis=1)
test_data = pd.concat([test_data, test_udmap_df], axis=1)

第三段代码:

是将处理后的udmap特征加入到原始的训练集和测试集中。其中pd.concat()可以实现DataFrame的拼接,直白来说就像用胶带把我们刚刚生成的train_udmap_df和test_udmap_df粘到原始的数据集后面。(函数内参数axis=1就表示将列拼接在一起)


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())

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())

第四段代码:

理解这段代码首先理解value_counts()以及train_data.groupby().mean()

value_counts():这个函数的输入是一个序列,功能为统计序列中各个值出现的频率。

train_data.groupby().mean():这个看起来比较复杂,其实就是根据eid列进行分组,再计算target列的平均值(简单理解为相同eid值所对应的target的均值)

有了上面的基础,再理解map()这个函数:就是将我们刚刚算出来的频率,以及均值。对应到原始数据上,和第三段代码的思路异曲同工。

这种基于某个特征的分组统计,然后映射回每个样本的操作,是构造新的特征的常用技巧。它可以充分挖掘训练集中的信息,并扩展到测试集,为模型提供更多特征以提升效果。这样以eid为桥梁构造的新特征,可以帮助模型学习eid对目标的影响。


train_data['udmap_isunknown'] = (train_data['udmap'] == 'unknown').astype(int)
test_data['udmap_isunknown'] = (test_data['udmap'] == 'unknown').astype(int)

第五段代码:

由于udmap中含有unknown的数据:

可以通过上面的代码判断每一条的udmap是否为unknown,“是”则为“1”,“否”则为“0”(通过astype函数将布尔值转换为数值1或0)。这样针对unknown的数据缺失部分,通过上述方法,构造了一个新的二值特征,可以为模型提供额外的信息,充分挖掘并扩展了数据中的信息。


train_data['common_ts_hour'] = train_data['common_ts'].dt.hour
test_data['common_ts_hour'] = test_data['common_ts'].dt.hour

第六段代码:

这段相对简单,主要使用了.dt.hour()。在第一段代码中common_ts已经被转化为pandas的datetime类型。利用dt访问器,就可以获取各种时间相关的属性,如dt.hour、dt.day等。在这里是从common_ts列中提取了小时这个时间特征。


import lightgbm as lgb
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier

clf = DecisionTreeClassifier()
clf.fit(
    train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1),
    train_data['target']
)

第七段代码:

1.导入了三个库,lightbgm、sklearn.linear_model、sklearn.tree。

2.这段代码中主要用到了sklearn.tree中的DecisionTreeClassifier,并将它命名为clf。而fit函数,就是训练模型的核心方法,(具体而言,将训练特征矩阵X和目标向量y传递给模型;模型根据自己的算法,学习特征和目标之间的映射关系;通过迭代计算不断优化模型的参数,以最小化损失函数;得到一组最优的参数,建立特征到目标的映射模型;返回一个训练好的模型对象)


pd.DataFrame({
    'uuid': test_data['uuid'],
    'target': clf.predict(test_data.drop(['udmap', 'common_ts', 'uuid'], axis=1))
}).to_csv('submit.csv', index=None)

第八段代码:

整体来看是将结果转为DataFrame并写入submit.csv文件。内部为:将测试集中也删除训练集中删除的特征,调用clf.predict()对测试集进行预测,获得预测结果。最后将测试集的uuid(样本唯一标识)和预测结果写入submit.csv文件。


三、总结

可见本文分析的baseline代码思路清晰,通过数据挖掘、由现有数据扩展出数据内涵的隐藏信息,后使用决策树进行模型训练,相对简单明了。但跑分为0.62左右,满分为1,还有很大改进空间。

ps.

文中难免有疏漏或错误之处,如蒙各位读者能够提出宝贵意见,将不胜感激。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

End!ess

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值