【Datawhale夏令营】任务二学习笔记

目录

一:python语法回顾

1.1  print()

1.2  列表与字典

1.3自定义函数与return

1.4火车类(面向对象) 

实例化总结:

二:LightGBM 代码精读

2.1导入库

2.2数据准备与参数设置

 2.3时间特征函数

  2.4优化

 2.5训练与预测

三:优化讲解

3.1:

3.2优化建议:


一:python语法回顾

1.1  print()

  1. 每一个print()会默认换行,若不想换行则:print("",end=""),默认end="\t"

  2. 单行注释 使用“#”开头,只能写在一行中~

1.2  列表与字典

  1. 列表是一种序列,他是可变的:容器的唯一作用就是打包、解包、内容传递】

  2. 列表定义:p2s = []

  3. 字典是键值对的集合

  4. 定义一个集合:Dw_set = set() 用add()函数将诗句插入集合中

  5. 定义一个字典:dw_dict = {"d":"Data","w":"whale"} # key:value 键:值;

  6. 字典可以利用键去查询对应的值

  7. 字典的更新:dw_dict["w"] = "whale"

1.3自定义函数与return

     回调函数(callback)

1.4火车类(面向对象) 

  1. 发车函数里,有一个"_"意思是不赋值给任何变量,是一个黑洞

实例化总结:

 

二:LightGBM 代码精读

2.1导入库

!pip install -U lightgbm
!unzip data/data227148/data.zip
#特别适合处理大规模数据集。
#当处理大规模数据集、需要高效训练和预测速度,并且希望获得较好的性能时,LightGBM通常是一个不错的选择。


# 导入所需的库
import pandas as pd # 读取和处理csv文件的数据
#用于处理数据的工具,常用于数据加载、数据清洗和数据预处理。

import lightgbm as lgb # 机器学习模型 LightGBM
#构建梯度提升树模型,是一种高效的机器学习算法。

from sklearn.metrics import mean_absolute_error # 评分 MAE 的计算函数
#从sklearn.metrics模块中导入评分函数
#平均绝对误差(MAE),是用于回归问题的一个评价指标。

from sklearn.model_selection import train_test_split # 拆分训练集与验证集工具
#用于将数据集拆分为训练集和验证集,以便进行模型训练和评估。

#sklearn.model_selection:对机器学习模型进行参数调优、数据集拆分、交叉验证和性能评估等任务。
#train_test_split函数:将数据集划分为训练集和测试集,并且可以灵活地设置拆分比例和随机种子。


from tqdm import tqdm # 显示循环的进度条工具
#循环过程中显示进度条,方便查看代码执行进度。

2.2数据准备与参数设置

# 数据准备
train_dataset = pd.read_csv("C:\\Users\\86198\\OneDrive\\桌面\\train.csv") # 原始训练数据。
test_dataset = pd.read_csv("C:\\Users\\86198\\OneDrive\\桌面\\test.csv") # 原始测试数据(用于提交)。

submit = pd.DataFrame() # 定义提交的最终数据。
submit["序号"] = test_dataset["序号"] # 对齐测试数据的序号,保持与原始测试数据的一致性。

MAE_scores = dict() # 定义评分项。

# 模型参数设置
pred_labels = list(train_dataset.columns[-34:]) #训练数据集的最后34列是需要预测的目标变量。
train_set, valid_set = train_test_split(train_dataset, test_size=0.2) # 拆分数据集。

# 设定 LightGBM 训练参,查阅参数意义:https://lightgbm.readthedocs.io/en/latest/Parameters.html
lgb_params = {
        'boosting_type': 'gbdt',     #使用的提升方法,使用梯度提升决策树gbdt。
        'objective': 'regression',   #优化目标,这里设置为'regression',表示使用回归任务进行优化。
        'metric': 'mae',             #评估指标,使用MAE,表示使用平均绝对误差作为评估指标。
        'min_child_weight': 5,       #子节点中样本权重的最小和,用于控制过拟合。
        'num_leaves': 2 ** 5,        #每棵树上的叶子节点数,影响模型的复杂度。
        'lambda_l2': 10,             #L2正则化项的权重,用于控制模型的复杂度。
        'feature_fraction': 0.8,     #随机选择特征的比例,用于防止过拟合。
        'bagging_fraction': 0.8,     #随机选择数据的比例,用于防止过拟合。
        'bagging_freq': 4,           # 随机选择数据的频率,用于防止过拟合。
        'learning_rate': 0.05,       #学习率,控制每次迭代的步长。
        'seed': 2023,                #随机种子,用于产生随机性,保持结果的可重复性。
        'nthread' : 16,              #并行线程数,用于加速模型训练。
        'verbose' : -1,              #控制训练日志输出,-1表示禁用输出。
    }
    #调整参数是优化模型性能的重要手段

no_info = lgb.callback.log_evaluation(period=-1) # 回调函数no_info:禁用训练日志输出。
#LightGBM通常会输出一些训练过程的信息,通过回调函数可以避免输出这些信息,使得训练过程更简洁。

 2.3时间特征函数

# 时间特征函数   特征提取
def time_feature(data: pd.DataFrame, pred_labels: list = None) -> pd.DataFrame:
    """提取数据中的时间特征。

    输入:
        data: Pandas.DataFrame
            需要提取时间特征的数据。

        pred_labels: list, 默认值: None
            需要预测的标签的列表。如果是测试集,不需要填入。

    输出: data: Pandas.DataFrame
            提取时间特征后的数据。
    """
    # 接收数据集DataFrame和可选参数pred_labels,返回处理后的DataFrame

    data = data.copy()  # 复制数据,避免后续影响原始数据。
    data = data.drop(columns=["序号"])  # 去掉”序号“特征。

    data["时间"] = pd.to_datetime(data["时间"])  # 将”时间“特征的文本内容转换为 Pandas 可处理的格式。
    data["month"] = data["时间"].dt.month  # 添加新特征“month”,代表”当前月份“。
    data["day"] = data["时间"].dt.day  # 添加新特征“day”,代表”当前日期“。
    data["hour"] = data["时间"].dt.hour  # 添加新特征“hour”,代表”当前小时“。
    data["minute"] = data["时间"].dt.minute  # 添加新特征“minute”,代表”当前分钟“。
    data["weekofyear"] = data["时间"].dt.isocalendar().week.astype(int)  # 添加新特征“weekofyear”,代表”当年第几周“,
    # 并转换成 int整数类型,否则 LightGBM 无法处理。
    data["dayofyear"] = data["时间"].dt.dayofyear  # 添加新特征“dayofyear”,代表”当年第几日“。
    data["dayofweek"] = data["时间"].dt.dayofweek  # 添加新特征“dayofweek”,代表”当周第几日“。
    data["is_weekend"] = data["时间"].dt.dayofweek // 6  # 添加新特征“is_weekend”,代表”是否是周末“,1 代表是周末,0 代表不是周末。

    data = data.drop(columns=["时间"])  # LightGBM 无法处理这个特征,它已体现在其他特征中,故丢弃。


  2.4优化

# 新加入特征代码展示(不必运行)

# 交叉特征
for i in range(1,18):
    train[f'流量{i}/上部温度设定{i}'] = train[f'流量{i}'] / train[f'上部温度设定{i}']
    test[f'流量{i}/上部温度设定{i}'] = test[f'流量{i}'] / test[f'上部温度设定{i}']
    
    train[f'流量{i}/下部温度设定{i}'] = train[f'流量{i}'] / train[f'下部温度设定{i}']
    test[f'流量{i}/下部温度设定{i}'] = test[f'流量{i}'] / test[f'下部温度设定{i}']
    
    train[f'上部温度设定{i}/下部温度设定{i}'] = train[f'上部温度设定{i}'] / train[f'下部温度设定{i}']
    test[f'上部温度设定{i}/下部温度设定{i}'] = test[f'上部温度设定{i}'] / test[f'下部温度设定{i}']
    
# 历史平移
for i in range(1,18):
    train[f'last1_流量{i}'] = train[f'流量{i}'].shift(1)
    train[f'last1_上部温度设定{i}'] = train[f'上部温度设定{i}'].shift(1)
    train[f'last1_下部温度设定{i}'] = train[f'下部温度设定{i}'].shift(1)
    
    test[f'last1_流量{i}'] = test[f'流量{i}'].shift(1)
    test[f'last1_上部温度设定{i}'] = test[f'上部温度设定{i}'].shift(1)
    test[f'last1_下部温度设定{i}'] = test[f'下部温度设定{i}'].shift(1)

# 差分特征
for i in range(1,18):
    train[f'last1_diff_流量{i}'] = train[f'流量{i}'].diff(1)
    train[f'last1_diff_上部温度设定{i}'] = train[f'上部温度设定{i}'].diff(1)
    train[f'last1_diff_下部温度设定{i}'] = train[f'下部温度设定{i}'].diff(1)
    
    test[f'last1_diff_流量{i}'] = test[f'流量{i}'].diff(1)
    test[f'last1_diff_上部温度设定{i}'] = test[f'上部温度设定{i}'].diff(1)
    test[f'last1_diff_下部温度设定{i}'] = test[f'下部温度设定{i}'].diff(1)
    
# 窗口统计
for i in range(1,18):
    train[f'win3_mean_流量{i}'] = (train[f'流量{i}'].shift(1) + train[f'流量{i}'].shift(2) + train[f'流量{i}'].shift(3)) / 3
    train[f'win3_mean_上部温度设定{i}'] = (train[f'上部温度设定{i}'].shift(1) + train[f'上部温度设定{i}'].shift(2) + train[f'上部温度设定{i}'].shift(3)) / 3
    train[f'win3_mean_下部温度设定{i}'] = (train[f'下部温度设定{i}'].shift(1) + train[f'下部温度设定{i}'].shift(2) + train[f'下部温度设定{i}'].shift(3)) / 3
    
    test[f'win3_mean_流量{i}'] = (test[f'流量{i}'].shift(1) + test[f'流量{i}'].shift(2) + test[f'流量{i}'].shift(3)) / 3
    test[f'win3_mean_上部温度设定{i}'] = (test[f'上部温度设定{i}'].shift(1) + test[f'上部温度设定{i}'].shift(2) + test[f'上部温度设定{i}'].shift(3)) / 3
    test[f'win3_mean_下部温度设定{i}'] = (test[f'下部温度设定{i}'].shift(1) + test[f'下部温度设定{i}'].shift(2) + test[f'下部温度设定{i}'].shift(3)) / 3

    if pred_labels:  # 如果提供了 pred_labels 参数,则执行该代码块。
        data = data.drop(columns=[*pred_labels])  # 去掉所有待预测的标签。在模型训练时不使用这些标签。

    return data  # 返回最后处理的数据。


test_features = time_feature(test_dataset)  # 处理测试集的时间特征,无需 pred_labels。

 2.5训练与预测

# 从所有待预测特征中依次取出标签进行训练与预测。
for pred_label in tqdm(pred_labels):
    # print("当前的pred_label是:", pred_label)
    train_features = time_feature(train_set, pred_labels=pred_labels)  # 处理训练集的时间特征。
    # train_features = enhancement(train_features_raw)
    # 调用time_feature函数处理训练集train_set的时间特征,并将处理后的训练集数据赋值给train_features

    train_labels = train_set[pred_label]  # 训练集的标签数据。
    # print("当前的train_labels是:", train_labels)
    # 获取当前特征标签pred_label在训练集中的真实值,并赋值给train_labels。

    train_data = lgb.Dataset(train_features, label=train_labels)  # 将训练集转换为 LightGBM 可处理的类型。
    # 将train_features和train_labels转换为LightGBM可处理的数据类型,创建训练数据集train_data。

    valid_features = time_feature(valid_set, pred_labels=pred_labels)  # 处理验证集的时间特征。
    # valid_features = enhancement(valid_features_raw)
    # 调用time_feature函数处理验证集valid_set的时间特征,并将处理后的验证集数据赋值给valid_features。

    valid_labels = valid_set[pred_label]  # 验证集的标签数据。
    # print("当前的valid_labels是:", valid_labels)
    # 获取当前特征标签pred_label在验证集中的真实值,并赋值给valid_labels。

    valid_data = lgb.Dataset(valid_features, label=valid_labels)  # 将验证集转换为 LightGBM 可处理的类型。

    # 训练模型,参数依次为:导入模型设定参数、导入训练集、设定模型迭代次数(5000)、导入验证集、禁止输出日志
    model = lgb.train(lgb_params, train_data, 5000, valid_sets=valid_data, callbacks=[no_info])

    valid_pred = model.predict(valid_features, num_iteration=model.best_iteration)  # 选择效果最好的模型进行验证集预测。
    test_pred = model.predict(test_features, num_iteration=model.best_iteration)  # 选择效果最好的模型进行测试集预测。
    MAE_score = mean_absolute_error(valid_pred, valid_labels)  # 计算验证集预测数据与真实数据的 MAE。
    MAE_scores[pred_label] = MAE_score  # 将对应标签的 MAE 值 存入评分项中。

    submit[pred_label] = test_pred  # 将测试集预测数据存入最终提交数据中。

submit.to_csv(r"C:\Users\86198\OneDrive\桌面\submit_result.csv", index=False)  # 保存最后的预测结果到 submit_result.csv

# 保存文件并查看结果
submit.to_csv(r"C:\Users\86198\OneDrive\桌面\submit_result.csv", index=False) # 保存最后的预测结果到 submit_result.csv。
print(MAE_scores) # 查看各项的 MAE 值。

三:优化讲解

3.1:

具体地,我们可以尝试提取更多特征改善最终结果,这也是数据挖掘比赛中的主要优化方向,很多情况下决定着最终的成绩。

这里主要构建了交叉特征、历史平移特征、差分特征、和窗口统计特征;每种特征都是有理可据的,具体说明如下:

(1)交叉特征:主要提取流量、上部温度设定、下部温度设定之间的关系;

(2)历史平移特征:通过历史平移获取上个阶段的信息;

(3)差分特征:可以帮助获取相邻阶段的增长差异,描述数据的涨减变化情况。在此基础上还可以构建相邻数据比值变化、二阶差分等;

(4)窗口统计特征:窗口统计可以构建不同的窗口大小,然后基于窗口范围进统计均值、最大值、最小值、中位数、方差的信息,可以反映最近阶段数据的变化情况。

3.2优化建议:

1、过拟合现象

在代码运行的时候可以将callbacks=[no_info]去除,以查看模型运行的日志,运行结束后也可以利用代码print(MAE_scores)来打印出最终的损失,观察不难看出,模型会在一定时间后进入过拟合,因此可以尝试以一些措施来缓解这种现象。

  • 利用lightgbm自带的early_stopping_rounds参数。
  • 采用多折验证的方式扩大数据量,使得模型泛化能力增强。

2、 参数设定

此次基线没有做精确的调参处理,因此可以调参的范围还是挺大的,常用的搜索参数策略有两种:

  • 网格搜索(Grid Search):这是一种传统的参数调整方法,它会测试指定参数的所有可能组合来找出最佳参数。但是,当参数空间较大时,这种方法可能会消耗大量计算资源和时间。

  • 随机搜索(Random Search):与网格搜索相比,随机搜索不会测试所有的参数组合,而是在参数空间中随机选择一定数量的参数组合进行测试。尽管随机搜索可能无法找到最优的参数组合,但在计算资源有限的情况下,它是一个有效的选择。

3、 模型设定

我们此次基线采用的是LightGBM,我们也可以试试XGBoost, Adaboost, Catboost等等传统的模型,并且也可以使用深度学习的方法构建循环神经网络来处理此次任务,因为本质是一个时序任务,在采用机器学习的同时也可以保存模型的参数配置,尝试进行模型集成的训练。

4、 特征

在特征选择方面,目前给出的特征仅仅是单独对时间处理,与对流量\上\下\部温度设定进行处理,并未结合时间与其他特征的关系,可以尝试自己构建合理的新特征。

5、 后处理

对已经给出的csv文件仍然可以分析其趋势,抓住评估的关键来调整文件内容使得结果更加精确。

6、 迭代步数 目前设置的迭代步数为200轮,其实这对于某些预测数据来说是不够的,可以尝试自己增大迭代步数

baseline进行修改优化后并跑通,结果可观如下:

调整参数后: 

参考文章:

datawhale暑期夏令营:datawhale开源项目

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Microsoft todo 数据导出

文章目录 官方说明: https://support.microsoft.com/zh-cn/office/导出您的-microsoft-待办事项帐户-d286b243-affb-4db4-addc-162e16588943 由于 微软待办 会自动与 Outlook 中的任务同步,因此您可以从 Outlook 中导出所有列表和任务。 若要导出列表和…

类加载机制,类加载顺序

类加载顺序 ①类加载从上往下执行,依次执行静态的初始化语句和初始化块,而且类加载优先于对象创建。(静态初始化语句和初始化块只加载一次) ②创建本类的对象时,从上往下执行一次非静态的初始化语句和初始化块&#…

企业服务器数据库被360后缀勒索病毒攻击后采取的措施

近期,360后缀勒索病毒的攻击事件频发,造成很多企业的服务器数据库遭受严重损失。360后缀勒索病毒是Beijingcrypt勒索家族中的一种病毒,该病毒的加密形式较为复杂,目前网络上没有解密工具,只有通过专业的技术人员对其进…

LinuxC语言-网络通信tcp/ip errno获取错误描述字符串

目录 服务端代码&#xff1a; 获取errno错误码&#xff1a; 客户端代码&#xff1a; 运行结果: 服务端代码&#xff1a; #include <stdio.h> #include<sys/types.h> #include<sys/socket.h> #include<string.h> #include<netinet/in.h> #in…

2022.09.17【读书笔记】丨生物信息学与功能基因组学(第十三章 蛋白质结构预测 下)

目录 蛋白质结构预测三种方法同源建模(比较建模)穿线法从头预测&#xff08;ab initio&#xff09;基于假设推荐策略 精度与方法选择Alphafold2相关信息 蛋白质结构预测 三种方法 同源建模(比较建模) 建模4步骤 1.模板选择和确定折叠构象 通过blast或delta-blast搜索同源蛋白…

【spring】spring bean的生命周期

spring bean的生命周期 文章目录 spring bean的生命周期简介一、bean的创建阶段二、bean的初始化阶段三、bean的销毁阶段四、spring bean的生命周期总述 简介 本文测试并且介绍了spring中bean的生命周期&#xff0c;如果只想知道结果可以跳到最后一部分直接查看。 一、bean的…

centos7搭建k8s环境并部署springboot项目

之前看了很多文章&#xff0c;都是部署后一直报错&#xff0c;百度解决后下次又忘了&#xff0c;这次决定把从头到尾的过程记录下来方便下次再看&#xff0c;部署参考文章尚硅谷Kubernetes&#xff08;k8s&#xff09;视频学习笔记_尚硅谷k8s笔记_溯光旅者的博客-CSDN博客 1、…

ELK报错no handler found for uri and method [PUT] 原因

执行后提示no handler found for uri and method post&#xff0c;最新版8.2的问题&#xff1f; 原因&#xff1a; index.mapping.single_type: true在索引上 设置将启用按索引的单一类型行为&#xff0c;该行为将在6.0后强制执行。 原 {type} 要改为 _doc&#xff0c;格式如…

MySQL运维:从全备sql文件中提取指定表的数据并恢复

目录 一、运行环境 二、需求说明 三、思路分析 五、具体方案 六、恢复表数据 一、运行环境 系统&#xff1a;CentOS7.3 数据库&#xff1a;MySQL 8.0.21 二、需求说明 线上有个表的数据被误操作了很多&#xff0c;无法通过bin-log进行具体的恢复。所以当前我们需要从全…

Redission分布式锁详解

前言 ​ 在分布式系统中&#xff0c;当不同进程或线程一起访问共享资源时&#xff0c;会造成资源争抢&#xff0c;如果不加以控制的话&#xff0c;就会引发程序错乱。而分布式锁它采用了一种互斥机制来防止线程或进程间相互干扰&#xff0c;从而保证了数据的一致性。 常见的分…

MFC第二十一天 CS架构多页面开发与数据交互、CImageList图像列表介绍 、CListCtrl-SetItem设置列表项的方法

文章目录 CImageList图像列表介绍CListCtrl图标的原理CListCtrl列表图标设置CListCtrl-SetItem设置列表项的方法 CS架构多页面开发与数据交互添加用户实现向导多页数据交互pch.hCLientXq.h CAppCPage1.hCPage1.cppCPage2.hCPage2.cppCWorkerDlg .hCWorkerDlg.cpp 多页数据修改C…

FRR+VPP

安装 三者的结合&#xff0c;实际上编译安装好就行了&#xff0c;不需要做任何代码上的修改&#xff0c;只需要安装和配置&#xff0c;然后你就有了一台路由器。 FRRouting使用frr-8.5.2版本&#xff0c;VPP使用23.06版本&#xff0c;DPDK和lcpng是VPP的插件&#xff0c;安装…

Spring Boot 应用程序生命周期扩展点妙用

文章目录 前言1. 应用程序生命周期扩展点2. 使用场景示例2.1 SpringApplicationRunListener2.2 ApplicationEnvironmentPreparedEvent2.3 ApplicationPreparedEvent2.4 ApplicationStartedEvent2.5 ApplicationReadyEvent2.6 ApplicationFailedEvent2.7 ApplicationRunner 3. 参…

Linux查看内存的几种方法

PS的拼接方法 ps aux|head -1;ps aux|grep -v PID|sort -rn -k 4|head 进程的 status 比如说你要查看的进程pid是33123 cat /proc/33123/status VmRSS: 表示占用的物理内存 top PID&#xff1a;进程的ID USER&#xff1a;进程所有者 PR&#xff1a;进程的优先级别&#x…

Vue2基础一、快速入门

零、文章目录 Vue2基础一、快速入门 1、Vue 概念 &#xff08;1&#xff09;为什么学 前端必备技能 岗位多&#xff0c;绝大互联网公司都在使用Vue 提高开发效率 高薪必备技能&#xff08;Vue2Vue3&#xff09; &#xff08;2&#xff09;Vue是什么 **概念&#xff1a;…

ARP协议(地址解析协议)详解

ARP协议&#xff08;地址解析协议&#xff09;详解 ARP协议的作用映射方式静态映射动态映射 ARP原理及流程ARP请求ARP响应 ARP协议报文首部 ARP协议的作用 ARP协议是“Address Resolution Protocol”&#xff08;地址解析协议&#xff09;的缩写。其作用是在以太网环境中&…

【李宏毅 DLHLP 深度学习人类语言处理 HW1】

李宏毅 DLHLP 深度学习人类语言处理 HW1 相关资料HW1 语音小白在网上没有找到这门课的作业分享&#xff0c;那就记录一下自己的作业吧。 相关资料 课程官网&#xff1a;https://speech.ee.ntu.edu.tw/~hylee/dlhlp/2020-spring.php 作业github代码1&#xff1a;https://githu…

给jupter设置新环境

文章目录 给jupternotebook设置新环境遇到的报错添加路径的方法 给jupternotebook设置新环境 # 先在anaconda界面新建环境 conda env list # 查看conda prompt下的有的环境变量 带星号的是当前活跃的 activate XXXX pip install ipykernel ipython ipython kernel install --u…

【机器学习】西瓜书学习心得及课后习题参考答案—第3章线性模型

过了一遍第三章&#xff0c;大致理解了内容&#xff0c;认识了线性回归模型&#xff0c;对数几率回归模型&#xff0c;线性判别分析方法&#xff0c;以及多分类学习&#xff0c;其中有很多数学推理过程以参考他人现有思想为主&#xff0c;没有亲手去推。 术语学习 线性模型 l…

Ubuntu /dev/loop<0..n>挂载的目录的分析

执行命令df -h lkmaoubuntu:~$ df -h Filesystem Size Used Avail Use% Mounted on udev 1.6G 0 1.6G 0% /dev tmpfs 391M 2.1M 389M 1% /run /dev/sda1 59G 30G 26G 54% / tmpfs 2.0G 0 2.0G 0% /dev/s…
最新文章