Use LightGBM To assess the quality of each video
1. 获取数据
从大数据表直接读取数据, 数据分为小时级数据和天级数据
1.1 小时级数据
从 odps 读取,考虑到读取速度慢,属于IO 密集型任务,采用多线程方法读取数据。
每一个小时的数据作为一个文件,如:hour_2024032501.json, 表示3 月 25 日凌晨 1 点进入的新视频数据。
数据存储在 data/temp_data中。
1.2 天级别数据
从 odps 读取,天级别数据读取相对较快,采用直接读取的方法。
数据存储在 data/train_data中。
1.3 两批数据的关系
小时级数据包含不同的 features 和唯一id video_id
天级数据包含不同的值,本次训练采用 total_return作为训练数据的 label。
要注意的是:天级数据为 json 格式,其结构为
{
"datetime": {
"video_id": {} # 该视频的return 信息
}
}
后续会通过把小时级数据的 video_id,去天级数据中寻找 4 天后的回流信息,作为训练和预测数据的 label
1.4 用法
首先需要激活虚拟环境
source /root/anaconda3/bin/activate
conda activate lightGBM
cd /root/luojunhui/alg
python3 read_data_from_odps.py
之后要要求手动输入两个值,
输入 1 表示获取小时级数据,范围为 yyyymmddhh - yyyymmddhh, 数据存储在 data/temp_data, 文件格式为 hour_yyyymmddhh.json
输入 2 表示获取天级数据,范围为 yyyymmdd - yyyymmdd, 数据存储在 data/train_data, 文件格式为:daily-label-yyyymmdd-yyyymmdd.json
2. 预处理数据
2.1 处理小时级 temp_data
python3 p_data_process.py
输入 1 生成训练数据,存储在文件夹 data/train_data中,格式为 train_{}_{}.json
输入 2 生成预测数据,存储在文件夹 data/pred_data中,格式为 pred_{}_{}.json
输入开始日期字符串: yyyymmddhh
输入结束日期字符串: yyyymmddhh
区间类型,左闭右边闭
2.2 处理训练数据,把数据处理成模型需要的格式
python3 process_data.py
要注意!!!! 该 python脚本部分地方需要改代码,后面会优化
DataProcessor类在初始化的时候接受两个参数
flag 和 c
flag: 通过 1, 2 控制,输入 1, flag = "train" 表示生成训练数据, 输入 2, flag="predict", 生成预测数据。
c: 目前写死在代码中, 若不传参数,默认为 useful, 表示所有的 features
传参为 spider,表示获取 spider 的 features
传参为 user,表示获取 userupload 的 features
当要生成训练数据时,DataProcessor 类的 produce 方法会接受一个参数dt
dt = "whole"表示用所有的数据来生成训练集, 格式为
dt = "16" 表示使用 20240316 当天的数据作为预测数据
数据格式为 "data/produce_data/y_data_{}_{}_{}_{}.json".format("total_return", self.flag, dt, self.c)
3. 模型训练
3.1 训练数据
python3 main.py
输入 1 表示训练,输入 2 表示预测
训练会把模型生成,并且保存在本地, 如light_tag.bin
预测会读取本地模型,然后用预测数据来做预测,输入 dt=16, 表示拿 20240316 的数据来做预测
4. 模型评估
4.1 评估方式
预测数据会得到一个 score list, 其值范围为[0, 1]
需要做一个二进制处理,对 score_list 从小到大排序,取排序位置为 70%的数值,小于该数值的为 0, 大于等于该值的为 1
预测会打印并且存储一个 summary 文件,格式为 summary_dt.txt,文件会存 3 列东西,分别是:
real_label pred_label score,用 "\t"分割, "\n"换行
计算评估
accuracy : real_label == pred_label的数量 / 预测样本总量
召回率值: real_label == pred_label == 1 的数量 / real_label的数量
准确率值: real_label == pred_label == 1 的数量 / pred_label的数量
AUC: cat summary.txt | awk -F "\t" '{print $1" "$3}'| /root/AUC/AUC/AUC
5. 参数优化
采用贝叶斯调优, 在 main.py中把
# study = optuna.create_study(direction='maximize')
# study.optimize(L.bays_params, n_trials=100)
# print('Number of finished trials:', len(study.trials))
# print('Best trial:', study.best_trial.params)
# L.train_model()
# L.evaluate_model()
# L.feature_importance()
这段代码取消注释,再把
i = int(input("输入 1 训练, 输入 2 预测:\n"))
if i == 1:
f = "train"
dt = "whole"
L = LightGBM(flag=f, dt=dt)
L.train_model()
elif i == 2:
f = "predict"
dt = int(input("输入日期, 16-21:\n"))
L = LightGBM(flag=f, dt=dt)
L.evaluate_model()
这段代码注释掉,执行 python3 main.py即可,会跑出accuracy 值最高的参数组合
6. 分析结果
计算评估
accuracy : real_label == pred_label的数量 / 预测样本总量
召回率值: real_label == pred_label == 1 的数量 / real_label的数量
准确率值: real_label == pred_label == 1 的数量 / pred_label的数量
AUC: cat summary.txt | awk -F "\t" '{print $1" "$3}'| /root/AUC/AUC/AUC