赛题数据
数据文件共有 7 个,分别是:
age_train.csv | 训练集数据文件 |
age_test.csv | 测试集数据文件 |
user_basic_info.csv | 用户基本特征数据集 |
user_behavior_info_info.csv | 用户行为类汇总特征数据集 |
user_app_actived.csv | 用户激活过的 APP 列表 |
user_app_usage.csv | 30 天的 APP 使用日志 |
app_info.csv | APP 类别元数据 |
训练集数据文件 age_train.csv 每行代表一个训练样本,各字段之间由逗号分隔,格式为“uId, age_group”。我们需要将以上给出的数据进行整合,在提供的数据集文件中,其中,uId 唯一标识一个用户。age_group 的取值范围为 1,2,3,4,5,6。其中,分别代表小于等于 18 岁,19-23 岁,24-34 岁,35-44 岁,45-54 岁,大于等于 55 岁。通过数据集中的 uId 字段将用户的各个数据联系起来。下面是官方给出的数据说明:
测试集数据文件 age_test.csv 每行代表一个测试样本,格式为”uId”。uId 唯一标识用户。
用户基本特征数据集 user_basic_info.csv 每行代表一个用户的基本信息,包含用户人口属性,设备基本属性,各字段之间由逗号分隔,格式为:“uId,gender, city,prodName,ramCapacity,ramLeftRation,romCapacity,romLeftRation,color, fontSize,ct,carrier,os”。如果特征取值未知,均以 NULL 表示。
用户行为类汇总特征数据集 user_ behavior_info.csv 每行代表一个用户的行为类信息,包含对设备的使用行为汇总数据。如果特征取值未知,均以 0 表示。
用户的激活 APP 列表文件 user_app_actived.csv 每一行代表一条用户激活 app 的记录(APP 激活的含义为用户安装并使用过该 APP)。特征文件格式为:“uId,appId# appId# appId# appId……”。uId 为用户标识,appId 为 app 应用的唯一标识,多个 app 以“#”分割。
APP 使用行为日志文件 user_app_usage.csv 存放了 30 天内按天统计每个用户对具体某个 app 的累计打开次数和使用时长,格式为:“uId,appId,duration,times,use_date”。
字段的含义分别是用户标识,app 应用包名,1 天内用户对某 app 的累计使用时长,1 天内用户对某 app 的累计打开次数,use_date 代表使用日期。
APP 对应类别文件 app_info.csv 每一行代表一条 app 的信息,格式如下:“appId, category”,记录每个 app 所属的应用类型。如果一个 app 对应所属多个类型则会存在多条记录。
脱敏处理:appId 做匿名化处理。
数据分析处理
三、分片读取数据
我们将数据集 user_app_usage.csv 解压,发现该数据集大小有 23.8G,无法直接读取,考虑使用 pandas 的 get_chunk()方法进行处理,chunk 是“厚片”的意思,指定一个 chunksize 就设定一个 chunk 是几行数据,我们每次读取数据集中的 1000000 条记录进行处理。
四、处理缺失值
我们发现在 user_basic_info 数据集中,有字段存在数据缺失的情况,其中fontSize 的缺失值是字段中最大的,而 ramCapacity、ramLeftRation、romCapacity、 romLeftRation、和 ct 这些字段的缺失比例都不大,我们可以用各个字段的平均值、中位数或者众数进行补齐。
五、数据类型转换
在 user_basic_info 数据集中,city、prodName、color、carrier、os、ct 字段都是字符串类型。为了后续模型训练,将这些字段转换成数字类型。其中 ct 字段存在缺失,将缺失的部分单独设为一个数字。
在 app_info.csvt 数据集记录了每个 app 所属的类别,一共有 40 个类别,是字符串类型。为了方便后面的模型训练,将这些类别转换成数字(0~39)。
六、特征提取
user_app_usage.csv 数据集特征提取
根据 baseline 给出的方法,对数据集表中的数据进行简单分析,对一些能直接从数据集表中提取的特征进行简单提取,对 user_app_usage.csv 数据集进行提取后得到的一些特征,通过训练后预测其准确率为 0.421769。
之前我们在处理大数据集时利用 pandas 的 get_chunk()方法,每次读取1000000条数据进行处理,提取以下特征。
usage_cnt | 用户使用记录总数 |
usage_appid_cnt | 用户使用的不同 app 总数 |
usage_date_cnt | 用户使用的不同日期总数 |
duration_mean | 每条记录的平均使用时长 |
duration_max | 使用时长的最大值 |
duration_std | 使用时长的标准差 |
times_mean | 每条记录的平均打开次数 |
times_max | 打开次数的最大值 |
times_std | 打开次数的标准差 |
category | 用户使用 app 的类别总数 |
usage_most_used_category | 用户使用频率最多的 app 类别 |
其它数据集特征提取
下面是另外两个数据集的特种字段以上特征都可以在赛题分析中找到相应的解释。
user_basic_info.csv | gender |
user_basic_info.csv | prodName |
user_basic_info.csv | ramCapacity |
user_basic_info.csv | ramLeftRation |
user_basic_info.csv | romCapacity |
user_basic_info.csv | romLeftRation |
user_basic_info.csv | color |
user_basic_info.csv | ct |
user_basic_info.csv | os |
user_basic_info.csv | carrier |
user_basic_info.csv | fontSize |
user_behaviour_info.csv | bootTimes |
user_behaviour_info.csv | AFuncTimes |
user_behaviour_info.csv | BFuncTimes |
user_behaviour_info.csv | CFuncTimes |
user_behaviour_info.csv | DFuncTimes |
user_behaviour_info.csv | EFuncTimes |
user_behaviour_info.csv | FFuncTimes |
user_behaviour_info.csv | FFuncSum |
user_app_actived.csv 数据集特征处理
我们从 user_app_actived.csv 中提取了 40 个特征值,描述的是每个用户激活40个类别 app 的数量,预测准确率为 0.502583。
在将 app_info.csv 中的类型值转成数字后,我们发现在原有列表中会有相同的 appld 属于不同的类别:
我们需要建立一个新的 app_info 列表,将相同的 appId 的类别整合到一起变成同一个列表,从其中获得 appId 与其所属类别的字典,目的是在之后提取特征时更快地索引到每个 app 对应的类别。
建立二维数组,存储每个用户激活的 40 个类别 app 的数量,原因是数组操作的速度远远快于 DataFrame 中的 loc()和 at()操作。
读取 user_app_actived[‘appId’],通过 split(‘#’)操作将每条记录分为每个单独的 appId,使用字典获得每个 appId 所属的类别,在数组相应未知加 1。将数组转换成 DataFrame,并加入 uid 列。
七、模型选择
我使用的训练模型是 baseline 中的 LightGBM 方法的 gbdt(传统的梯度提升决策树)。对于这类基于树的模型,最耗时的部分就是在进行特征选择结点分裂时,需要遍历所有可能的划分点,计算信息增益,从而找到最优的划分点。前面虽然有了各类的算法对这个过程进行优化,比如 XGBoost,但是在特征维数很高,样本量很大的情况下,它的效率和灵活性还是不够好。LightGBM 这个模型极大的提升了计算效率。在快的同时,还能保证模型的精度,这是它最大的优点。
我使用了 StratifiedKFold k 折交叉切分验证,共分为 5 折,分别训练后得到 5 次测试集预测结果,然后进行投票,选出最恰当的预测结果,作为该模型的最终预测结果。
baseline 中的初始参数在训练时将学习率设置为 0.1,max_bin 设置为 230, feature_fraction 设置为 0.8,使得模型能够快速完成训练,准确率比之前也有提高。
在我们对数据进行了特征提取和特征选择的工作之后,为了获得更好的准确率,我们需要对参数进行调整。根据 LightGBM 文档中的参数优化我将学习率设置为 0.05,num_leaves 设置为 50,min_data_in_leaf 设置为 50,max_bin 设置为400,最终获得了的准确率。
LightGBM 使用 leaf-wise 的树生长策略,与 depth-wise 的树生长策略相较, leaf-wise 算法可以收敛的更快。但是,如果参数选择不当的话,leaf-wise 算法有可能导致过拟合.