|
@@ -1,3 +1,101 @@
|
|
|
-# alg
|
|
|
+# 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
|
|
|
+
|
|
|
|
|
|
-算法
|