1 回归:锂电池温度预测top2 代码部分(一) Tabnet

news2024/11/29 8:55:11

2024 iFLYTEK A.I.开发者大赛-讯飞开放平台

TabNet: 模型也是我在这个比赛一个意外收获,这个模型在比赛之中可用。但是需要GPU资源,否则运行真的是太慢了。后面针对这个模型我会写出如何使用的方法策略。

        比赛结束后有与其他两位选手聊天,他们都是对数据做了很多分析,有的甚至直接使用Lasso就work了,效果还挺不错的。特征工程无敌呀。        

        真个代码部分,了解下有关特征工程的部分就行了,模型部分可以慢慢消化。当作一个新的知识点学习吧。

直接上代码

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

from tqdm import tqdm
from sklearn.model_selection import KFold

from pytorch_tabnet.metrics import Metric
from pytorch_tabnet.tab_model import TabNetRegressor
import torch
from torch.optim import Adam, SGD
from torch.optim.lr_scheduler import ReduceLROnPlateau, CosineAnnealingWarmRestarts
from sklearn.metrics import mean_absolute_error
import traceback

import warnings

warnings.filterwarnings("ignore")

plt.rcParams['font.sans-serif'] = ['PingFang HK']  # 用来正常显示中文标签
plt.rcParams["axes.unicode_minus"] = False  # 该语句解决图像中的“-”负号的乱码问题
pd.set_option('precision', 10)
pd.set_option('display.max_rows', None)


# 时间解析模块
def parse_date(train_df=None):
    train_df['datetime'] = pd.to_datetime(train_df['时间'])
    train_df['timestamp'] = train_df['datetime'].astype('int64') / 10000000
    train_df['year'] = train_df['datetime'].dt.year
    train_df['month'] = train_df['datetime'].dt.month
    train_df['day'] = train_df['datetime'].dt.day
    train_df['hour'] = train_df['datetime'].dt.hour
    train_df["minute"] = train_df['datetime'].dt.minute
    train_df['dayofweek'] = train_df['datetime'].dt.dayofweek
    # train_df['datetime'].dt.dayofmonth
    return train_df


def same_position_tempture_resid(train_df, index=[]):
    for i in index:
        train_df[f'下部温度{i}_resid'] = train_df[f'下部温度{i}'] - train_df[f'下部温度设定{i}']
        train_df[f'下部温度{i}_dist_4'] = train_df[f'下部温度设定4'] - train_df[f'下部温度设定{i}']
        train_df[f'下部温度{i}_dist_4_moth_100'] = (train_df[f'下部温度{i}_dist_4'] >= 99) * 1
    return train_df


df_train = pd.read_csv("../data/train.csv")
df_test = pd.read_csv("../data/test.csv")
submit = pd.read_csv("../data/submit.csv")
df_train = parse_date(df_train)
df_test = parse_date(df_test)

df_train = df_train.sort_values("datetime")
df_train = df_train.reset_index(drop=True)
df_train['train'] = 1

df_train.loc[1057, '下部温度9'] = 829

df_test = df_test.sort_values("datetime")
df_test = df_test.reset_index(drop=True)
df_test['train'] = 0

flow_cols = [col for col in df_train.columns if "流量" in col]
up_temp_sets = [col for col in df_train.columns if "上部温度设定" in col]
down_temp_sets = [col for col in df_train.columns if "下部温度设定" in col]
up_tempture = [col for col in df_train.columns if "上部温度" in col and col not in up_temp_sets]
down_tempture = [col for col in df_train.columns if "下部温度" in col and col not in down_temp_sets]

# train_df.columns.tolist()
import re

small_cols = ['下部温度5', '上部温度8', '上部温度9',
              '上部温度10',
              '上部温度11',
              '上部温度12',
              '上部温度13',
              '上部温度14',
              '上部温度15',
              '上部温度16',
              '上部温度17',
              '下部温度3',
              '下部温度4',
              '下部温度6',
              '下部温度7',
              '下部温度8',
              '下部温度9',
              '下部温度10',
              '下部温度11',
              '下部温度12',
              '下部温度13',
              '下部温度14',
              '下部温度15',
              '下部温度16',
              '下部温度17'] + [
                 '上部温度1',
                 '上部温度2',
                 '上部温度3',
                 '上部温度4',
                 '上部温度5',
                 '上部温度6',
                 '上部温度7',
                 '下部温度1',
                 '下部温度2',

             ]


def get_same_temp(test_df, cols):
    for col in cols:
        nums = re.findall("\d+", col)
        num = nums[0]
        if "上部温度" in col:
            print(num, col)
            test_df[col] = test_df[f'上部温度设定{num}']
        elif "下部温度" in col:
            test_df[col] = test_df[f'下部温度设定{num}']
    return test_df


df_test = get_same_temp(df_test, small_cols)
df = pd.concat([df_train, df_test])
df = df.sort_values(['year', 'month', 'day', 'hour', "minute"])
df = df.reset_index(drop=True)

down_label = ['下部温度1', '下部温度2', '下部温度3']
up_label = ['上部温度7', '上部温度1', '上部温度2', '上部温度3', '上部温度4', '上部温度5', '上部温度6']
cat_cols = ['year', 'month', 'day', 'hour', 'minute', 'dayofweek']

keep_cols = df_test.columns.tolist()



def resid_model(y, y_pred):
    # residual plots
    y_pred = pd.Series(y_pred, index=y.index)
    resid = y - y_pred
    mean_resid = resid.mean()
    std_resid = resid.std()
    z = abs(resid) / (y + 0.01)
    # print(z)
    n_outliers = sum(abs(resid) > 10000)
    outliers = y[(abs(resid) > 10000)].index
    print(outliers)
    plt.figure(figsize=(15, 5))
    ax_131 = plt.subplot(1, 3, 1)
    plt.plot(y, y_pred, '.')
    plt.xlabel('y')
    plt.ylabel('y_pred');
    plt.title('corr = {:.3f}'.format(np.corrcoef(y, y_pred)[0][1]))
    ax_132 = plt.subplot(1, 3, 2)
    plt.plot(y, y - y_pred, '.')
    plt.xlabel('y')
    plt.ylabel('y - y_pred');
    plt.title('std resid = {:.3f}'.format(std_resid))

    ax_133 = plt.subplot(1, 3, 3)
    z.plot.hist(bins=50, ax=ax_133)
    plt.xlabel('z')
    plt.title('{:.0f} samples with z>3'.format(n_outliers))
    plt.show()
    # return outliers


def get_down_tempture_sets_resid(df, diffed_col="下部温度设定4",
                                 diff_col='下部温度设定1'):
    distacnce = 0
    if "上部" in diff_col:
        print(f"----- {diff_col}_diff_{diffed_col}")
        df['上部温度设定4_diff_上部温度设定1'] = df['上部温度设定4'] - df['上部温度设定1']
        df[f'{diffed_col}_diff_{diff_col}'] = df[diffed_col] - df[diff_col]
        df['上部温度设定4_div_上部温度设定1'] = df['上部温度设定4'] / df['上部温度设定1']
        df[f'{diffed_col}_div_{diff_col}'] = df[diffed_col] / df[diff_col]

        df['flag'] = (df['上部温度设定4_diff_上部温度设定1'] > 300) * 1
    else:
        df['下部温度设定4_diff_下部温度设定1'] = df['下部温度设定4'] - df['下部温度设定1']
        df['下部温度设定4_div_下部温度设定1'] = df['下部温度设定4'] / df['下部温度设定1']

        df[f'{diffed_col}_diff_{diff_col}'] = df[diffed_col] - df[diff_col]
        df[f'{diffed_col}_div_{diff_col}'] = df[diffed_col] / df[diff_col]

        distacnce = 300

        df['flag'] = (df['下部温度设定4_diff_下部温度设定1'] > 300) * 1
    return df


def get_same_type_tempure(row, df_train, label, woindows):
    try:
        heads = woindows
        train_flag = int(row['train'])
        hour = row['hour']
        minute = row['minute']
        timesamp = row['timestamp']
        flag = row['flag']

        nums = re.findall("\d+", label)
        num = int(nums[0])
        chars = re.findall("(\w+)(\d+)", label)[0][0]
        label_map_set_col = f"{chars}设定{num}"
        set_temps = row[label_map_set_col]
        # (df_train[label_map_set_col]==set_temps)&

        df_temp_ = df_train[
            (df_train[label_map_set_col] == set_temps) & (df_train['flag'] == flag) & (df_train['hour'] == hour) & (
                        df_train['timestamp'] < timesamp)]
        df_temp = df_temp_.tail(woindows)

        # df_temp_2 = df_temp_.head(30)

        if len(df_temp) == 0:
            return set_temps, set_temps, 0, set_temps, set_temps, set_temps
        min_ = df_temp[label].min()
        max_ = df_temp[label].max()
        std_ = df_temp[label].std()
        mean_ = df_temp[label].mean()
        median_ = df_temp[label].median()
        ewm_ = df_temp[label].ewm(span=heads, adjust=False).mean().values[-1]
        del df_temp
        return min_, max_, std_, mean_, median_, ewm_
    except Exception as e:
        print(traceback.format_exc())


def predict_result(df, train_df=None, result_df=None, label="下部温度1"):
    result_cols = result_df.columns.tolist()
    nums = re.findall("\d+", label)
    num = nums[0]
    chars = re.findall("(\w+)(\d+)", label)[0][0]
    df[f'{label}_new_label'] = (df[label] - df[f"{chars}设定{num}"])

    label_new = f'{label}_new_label'
    label_map_set_col = f"{chars}设定{num}"

    df[f'{label_map_set_col}_ratio'] = df[label_map_set_col].pct_change()
    # df[f'{label_map_set_col}_ratio']

    if chars in "下部温度":
        balance_col = "下部温度设定4"
        new_cols = [f'{balance_col}_diff_{label_map_set_col}', f'{balance_col}_div_{label_map_set_col}',
                    '下部温度设定4_diff_下部温度设定1', '下部温度设定4_div_下部温度设定1']
    else:
        balance_col = "上部温度设定4"
        new_cols = list(set(['上部温度设定4_diff_上部温度设定1', '上部温度设定4_div_上部温度设定1',
                             f'{balance_col}_diff_{label_map_set_col}', f'{balance_col}_div_{label_map_set_col}']))

    down_df = get_down_tempture_sets_resid(df, balance_col, diff_col=label_map_set_col)

    train_df = down_df[down_df['train'] == 1].reset_index(drop=True)

    his_feats = []
    for wind in [7, 28]:
        his_feat = [f"{label}_min_{wind}", f"{label}_max_{wind}",
                    f"{label}_std_{wind}", f"{label}_mean_{wind}",
                    f"{label}_median_{wind}", f"{label}_ewm_{wind}"]
        his_feats.extend(his_feat)
        down_df[his_feat] = down_df.apply(lambda x: get_same_type_tempure(x, train_df, label, wind), axis=1,
                                          result_type="expand")
        # return down_df
        # print(down_df[his_feats].isna().sum())
    down_df = down_df.fillna(-99)

    for use_flag in [0, 1]:
        max_epoches = 60
        if use_flag==1:
            max_epoches = 100
        df_train = down_df[(down_df['train'] == 1) & (down_df['flag'] == use_flag)].reset_index(drop=True)
        # df_train = down_train_df
        df_test = down_df[(down_df['train'] == 0) & (down_df['flag'] == use_flag)].reset_index(drop=True)

        # print(df_test.unique())
        print("Nan shape", df_test[his_feats].isna().sum())
        # print(df_test[df_test[his_feats].isna()].head())

        print(down_df.shape, df_train.shape, df_test.shape)

        feats = [f'流量{num}',
                 '上部温度设定1',
                 'year', 'month', 'day', 'hour',
                 'minute', 'dayofweek', ] + new_cols + [f'{label_map_set_col}_ratio'] + his_feats
        feats = list(set(feats))
        cat_cols = ['year', 'month', 'day', 'hour', 'minute', 'dayofweek']

        cat_idxs = [i for i, f in enumerate(feats) if f in cat_cols]
        cat_dims = [df_train[i].nunique() for i in cat_cols]
        # print(df_train[feats].head())
        # print(cat_idxs)
        # print(cat_dims)

        tabnet_params = dict(
            cat_idxs=[],
            cat_dims=[],
            cat_emb_dim=1,
            n_d=16,
            n_a=16,
            n_steps=2,  # 模型获取能力代表
            gamma=2,
            n_independent=2,
            n_shared=2,
            lambda_sparse=0,
            optimizer_fn=Adam,
            optimizer_params=dict(lr=(2e-2)),
            mask_type="entmax",
            scheduler_params=dict(T_0=200, T_mult=1, eta_min=1e-4, last_epoch=-1, verbose=False),
            # 学习速率自动调整
            scheduler_fn=CosineAnnealingWarmRestarts,
            seed=42,
            verbose=10,
            
        )

        split = 5
        # kf = KFold(n_splits=split, shuffle=False, random_state=2021)
        folds = KFold(n_splits=split, shuffle=True, random_state=1314)  # 1314

        oof = np.zeros((len(df_train), 1))
        importance = 0
        pred_y = np.zeros(len(df_test))

        val_all = []
        # for fold, (train_idx, val_idx) in enumerate(train_splits):
        for fold, (train_idx, val_idx) in enumerate(folds.split(df_train)):
            print(f'--------------------------- {len(train_idx)}', fold)
            val_all.extend(val_idx)

            print(f'Training fold {fold + 1}')
            X_train, X_val = df_train.loc[train_idx, feats].values, df_train.loc[val_idx, feats].values

            y_train, y_val = df_train.loc[train_idx, label_new].values.reshape(-1, 1), df_train.loc[
                val_idx, label_new].values.reshape(-1, 1)

            model = TabNetRegressor(**tabnet_params)
            model.fit(
                X_train, y_train,
                eval_set=[(X_val, y_val)],
                max_epochs=max_epoches,
                patience=50,
                batch_size=64,
                virtual_batch_size=32,
                num_workers=8,
                drop_last=False,
                eval_metric=[MYMAE],
                loss_fn=my_mean
            )

            oof[val_idx] = model.predict(X_val)

            # print(model.predict(df_test[feats].values))

            pred_y += model.predict(df_test[feats].values).flatten() / split

        #     if save_model:
        #         joblib.dump(value=model, filename=f'../model/lgb_5fold_{fold}.m')
        print(f'labe = {label} use_flag = {use_flag} mae = ',
              mean_absolute_error(oof.reshape(-1) + df_train[label_map_set_col], df_train[label]))

        # resid_model(df_train[label_new], oof)

        result_df = result_df[result_cols]

        df_test[label + "_add"] = pred_y

        result_df = result_df.merge(df_test[cat_cols + [label + "_add"] + his_feats], on=cat_cols, how="left")
        # print(result_df.head())
        result_df.loc[~result_df[label + "_add"].isna(), label] = result_df.loc[~result_df[
            label + "_add"].isna(), label + "_add"] + result_df.loc[~result_df[
            label + "_add"].isna(), label_map_set_col]

    return result_df.reset_index(drop=True)[result_cols + his_feats]


# df['day'].nunique()
class MYMAE(Metric):
    def __init__(self):
        self._name = "mymae"
        self._maximize = False

    def __call__(self, y_true, y_score):
        return mean_absolute_error(y_true, y_score)


def my_mean(y_pred, y_true):
    return torch.mean(torch.abs(y_true - y_pred)).clone()


# up_label+down_label
for label in tqdm((down_label + up_label)[5:]):
    print(f"-------------------{label}")
    df_test = predict_result(df, df_train, df_test[keep_cols], label)


df_test['上部温度1'] = df_test['上部温度1'].clip(upper=410)
x = pd.concat([df_train, df_test]).sort_values(['year', 'month', 'day', 'hour', "minute"]).reset_index(drop=True)
submit = pd.read_csv("../data/submit.csv")
submit_cols = submit.columns.tolist()
df_test[submit_cols].to_csv("../data/tabnet_submit_his_winds_label_last_5.csv",index=False, encoding='utf_8_sig')

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

YOLOv9改进策略 | 损失函数篇 | EIoU、SIoU、WIoU、DIoU、FocusIoU等二十余种损失函数

一、本文介绍 这篇文章介绍了YOLOv9的重大改进&#xff0c;特别是在损失函数方面的创新。它不仅包括了多种IoU损失函数的改进和变体&#xff0c;如SIoU、WIoU、GIoU、DIoU、EIOU、CIoU&#xff0c;还融合了“Focus”思想&#xff0c;创造了一系列新的损失函数。这些组合形式的…

前端请求发送成功,后端收到null

1、dishId为64&#xff0c;有数据 2、但是后端调试接不到数据&#xff0c;为null 3、形参部分缺少RequestBody接收JSON数据&#xff0c;加上即可

C++修炼之路之STL_stack,queue和容器适配器

目录 前言 一&#xff1a;SLT中stack和queue的基本使用 1.在官网中对stack和queue的简单介绍 2.数据结构中栈和队列的基本知识和操作 3. STL中stack的接口函数及使用 4.STL中queue的接口函数及使用 二&#xff1a;容器适配器Container 三&#xff1a;使用容器适配器…

浏览器工作原理与实践--安全沙箱:页面和系统之间的隔离墙

前面三篇文章我们主要围绕同源策略介绍了Web页面安全的相关内容&#xff0c;那今天我们把视野向外延伸&#xff0c;来聊聊页面安全和操作系统安全之间的关系。 在《仅仅打开了1个页面&#xff0c;为什么有4个进程&#xff1f;》那篇文章中&#xff0c;我们分析了浏览器架构的发…

第一篇【传奇开心果系列】我和AI面对面聊编程:深度比较PyQt5和tkinter.ttk

传奇开心果系列博文 系列博文目录我和AI面对面聊编程系列 博文目录前言一、今天我们面对广大读者选择PyQt5和tkinter.ttk做比较这个话题目的是什么&#xff1f;二、举一个最简单的pyqt5信号和插槽的例子三、这和tkinter的点击事件有什么区别&#xff1f;四、如何选择&#xff1…

深澜计费管理系统 /demo/proxy存在任意文件读取漏洞

声明&#xff1a; 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任。 简介 深澜计费管理系统是一款用于网络设备计费管理的软件…

React + 项目(从基础到实战) -- 第八期

ajax 请求的搭建 引入mockAP接口设计AJAX 通讯 前置知识 HTTP 协议 , 前后端通讯的桥梁API : XMLHttpRequest 和 fetch常用工具axios mock 引入 Mock.js (mockjs.com) 使用 mockJS 前端代码中引入 mockJs定义要模拟的路由 , 返回结果mockJs 劫持ajax请求(返回模拟的结果)…

SPI 和W25Q128(使用SPI通讯读写W25Q128模块)

SPI 是什么&#xff1f; SPI 是串行外设接口&#xff08; Serial Peripheral Interface &#xff09;的缩写&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;并且在芯片的管脚上 只占用四根线 &#xff0c;节约了芯片的管脚&#xff0c;同时…

SecureCRT (Mac/Windows)中文---远程连接与管理的安全新选择

SecureCRT是一款功能强大的终端仿真程序&#xff0c;专为连接和管理远程系统而设计。它支持SSH&#xff08;包括SSH1和SSH2&#xff09;协议&#xff0c;确保用户与目标设备之间的通信安全&#xff0c;有效防止网络攻击和窥探。此外&#xff0c;SecureCRT还支持Telnet、Rlogin等…

Jmeter 接口造10w条用户数据

1、将mysql-connector-java-5.1.22-bin.jar放到D:\apache-jmeter-5.5\lib\ext目录下 2、在测试计划中&#xff0c;添加mysql-connector-java-5.1.22-bin.jar包路径 3、添加-线程组-添加-配置元件-jdbc connection configuration 4、配置jdbc连接参数 设置变量名称&#xff1a;…

ASP.NET基于SVG的自动站雨量分析系统

摘 要 SVG是由W3C组织开发的基于可扩展标记语言的一种矢量图形描述语言&#xff0c;已经在互联网上得到了较广泛的应用。为了以图形方式直观地显示雨量数据变化&#xff0c;方便工作人员进行雨量数据的查询及分析&#xff0c;设计了本套基于SVG的雨量分析系统。 该自动站雨量…

基于SSM+Jsp+Mysql的准速达物流管理系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

wsl安装与日常使用

文章目录 一、前向配置1、搜索功能2、勾选下面几个功能&#xff0c;进行安装二、安装WSL1、打开Windows PowerShell,查找你要安装的linux版本2、选择对应版本进行安装3、输入用户名以及密码 三、配置终端代理1、打开powershell,查看自己的IP把以下信息加入到~/.bashrc中 四、更…

【论文速读】| 大语言模型是边缘情况模糊测试器:通过FuzzGPT测试深度学习库

本次分享论文为&#xff1a;Large Language Models are Edge-Case Fuzzers: Testing Deep Learning Libraries via FuzzGPT 基本信息 原文作者&#xff1a;Yinlin Deng, Chunqiu Steven Xia, Chenyuan Yang, Shizhuo Dylan Zhang, Shujing Yang, Lingming Zhang 作者单位&…

MySQL Explan执行计划详解

Explan执行计划 首先我们采用explan执行计划 执行一条sql&#xff0c;发现返回了12个列&#xff0c;下面会详细解释每一列 1、ID列 id列的值是代表了select语句执行顺序&#xff0c;是和select相关联的&#xff1b;id列的值大的会优先执行&#xff0c;如果id列为空最后执行&a…

python后端相关知识点汇总(十二)

python知识点汇总十二 1、什么是 C/S 和 B/S 架构2、count(1)、count(*)、count(列名)有啥区别&#xff1f;3、如何使用线程池3.1、为什么使用线程池&#xff1f; 4、MySQL 数据库备份命令5、supervisor和Gunicorn6、python项目部署6.1、entrypoint.sh制作6.2、Dockerfile制作6…

可见光相机曝光方式

可见光摄影中的曝光方式主要包括两种&#xff1a;卷帘曝光和全局曝光。它们之间的区别在于曝光过程中传感器或胶片感光部分的工作方式不同&#xff0c;这直接影响到图像捕获的效果和特性。 卷帘曝光&#xff08;Rolling Shutter&#xff09;&#xff1a; 工作原理&#xff1a;在…

Day 16 Linux服务管理和日志管理

服务管理 启动服务&#xff1a;systemctl start 服务名 停止服务&#xff1a;systemctl stop 服务名 重启服务&#xff1a;systemctl restart 服务名 重新加载配置文件&#xff1a;systemctl reload 服务名&#xff08;期间并不停止服务进程&#xff09; 查看服务运行状态…

GAN反演+老照片修复

关于老照片修复~~~~~上图为运行腾讯ARC的模型之后的效果图 其使用的模型&#xff0c;GFP-GAN&#xff0c;Towards Real-World Blind Face Restoration with Generative Facial Prior&#xff0c;理解记录如下&#xff1a; Abstract: In this work, we propose GFP-GAN that …

专业143总分428学硕第一东南大学920专业基础综合考研经验电子信息与通信工程,海洋工程,电路系统,鲁汶,真题,大纲,参考书。

24考研基本已经尘埃落定&#xff0c;总归要为回忆留下点什么。回想起这一年的备考之路&#xff0c;至今仍觉得时间过得很快&#xff0c;有些感到恍惚&#xff0c;似乎不能接受。但是仔细思考一下&#xff0c;这一年经历了很多&#xff0c;走过很多弯路也取得一些阶段性的小成功…