基于Jamba模型的天气预测实战

深入探索Mamba模型架构与应用 - 商品搜索 - 京东

 DeepSeek大模型高性能核心技术与多模态融合开发 - 商品搜索 - 京东

由于大气运动极为复杂,影响天气的因素较多,而人们认识大气本身运动的能力极为有限,因此以前天气预报水平较低 。预报员在预报实践中,每次预报的过程都极为复杂,需要综合分析,并预报各气象要素,比如温度、降水等。现阶段,以往极少出现的极端天气现象越来越多,这极大地增加了预报的难度,如图11-20所示。

图11-20  天气预报

本小节将使用Jamba完成天气预测,即在给定天气因素下,预测城市是否下雨。

1. 数据集的准备

这里作者准备了来自澳大利亚多个气候站的日常共15万条收集[wy1] [晓王2] 的数据,如图11-21所示。

图11-21  澳大利亚天气数据集前5条内容

其中的变量解释如下所示。

  • Location    获取该信息的气象站的名称
  • MinTemp    以摄氏度为单位的低温度
  • MaxTemp    以摄氏度为单位的高温度
  • Rainfall    当天记录的降雨量,单位为mm
  • Evaporation    到早上9点之前的24小时的A级蒸发量(mm)
  • Sunshine    白日受到日照的完整小时
  • WindGustDir    在到午夜12点前的24小时中的强风的风向
  • WindGustSpeed    在到午夜12点前的24小时中的强风速(km/h)
  • WindDir9am    上午9点时的风向
  • WindDir3pm    下午3点时的风向
  • WindSpeed9am    上午9点之前每10分钟的风速的平均值(km/h)
  • WindSpeed3pm    下午3点之前每10分钟的风速的平均值(km/h)
  • Humidity9am    上午9点的湿度(百分比)
  • Humidity3am    下午3点的湿度(百分比)
  • Pressure9am    上午9点平均海平面上的大气压(hpa)
  • Pressure3pm    下午3点平均海平面上的大气压(hpa)
  • Cloud9am    上午9点的天空被云层遮蔽的程度,这是以oktas来衡量的,这个单位记录了云层遮挡天空的程度。0表示完全晴朗的天空,而8表示完全是阴天
  • Cloud3pm    下午3点的天空被云层遮蔽的程度
  • Temp9am    上午9点的摄氏度温度
  • Temp3pm    下午3点的摄氏度温度
  • RainToday    今日是否有雨
  • RainTomorrow    明日是否有雨

通过观察可以发现,这个特征矩阵由一部分分类变量和一部分连续变量组成,其中云层遮蔽程度虽然是以数字表示的,但是其本质却是分类变量。大多数特征都是采集的自然数据,比如蒸发量、日照时间、湿度等,而少部分特征则是人为构成的。还有一些是单纯表示样本信息的变量,比如采集信息的地点,以及采集的时间。

在我们知道了数据情况后,下一步就是确定目标标签,简单来说,就是我们的标签:明天下雨吗?目标特征RainTomorrow表示明天是否会下雨,即是或否。

2. 特征的选择与程序实现

在特征选择过程中,我们需要根据目标精准地挑选最合适的特征进行计算。以天气为例,我们推测昨天的天气状况可能会对今天的天气状况有所影响,同样,今天的天气状况也可能影响明天的天气状况。换言之,在样本之间,随着时间的推移,是存在相互影响的。然而,传统的算法往往只能捕捉到样本特征与标签之间的关系,即列与列之间的联系,而无法把握样本与样本之间的关联,也就是行与行之间的联系。

要让算法能够理解前一个样本标签对后一个样本标签的潜在影响,我们需要引入时间序列分析。时间序列分析是通过将同一统计指标的数据按其发生的时间顺序排列,以数列形式呈现出来。其主要目的是依据历史数据预测未来趋势。但据作者了解,时间序列分析通常适用于单调且唯一的时间线,即它一次只能预测一个地点的数据,而无法同时预测多个地点,除非进行循环操作。然而,我们的时间数据并非单调或唯一的,尤其是在抽样后,数据的连续性也可能被破坏。我们的数据混杂了多个地点和不同时间段的信息,这使得使用时间序列分析来处理问题变得相当复杂。

那么,我们可以尝试另一种思路。既然算法擅长处理的是列与列之间的关系,我们是否可以将“今天的天气影响明天的天气”这一因素转换为一个具体的特征呢?实际上,这是可行的。

我们注意到数据中有一个特征列名为RainToday,表示当前日期和地区的降雨量,即“今日的降雨量”。基于常识,我们认为今天是否下雨很可能会影响明天的天气状况。例如,在某些气候区域,一旦开始下雨,可能会持续数日;而在另一些地方,暴雨可能来得快,去得也快。因此,我们可以将时间对气候的连续影响转换为“今天是否下雨”这一特征。这样,我们可以巧妙地将原本样本间(行与行之间)的联系转换为特征与标签之间的联系(列与列之间)。

下面将使用其中6个特征'Location'、'WindGustDir'、'WindDir9am'、'WindDir3pm'、'Date'和'RainToday'完成对明日天气的预测。代码如下:

import pandas as pd
import matplotlib.pyplot as plt
import numpy as npdef preprocessing(df, index):labels = set([])for label in df[index]:labels.add(label)labels = list(labels)# print(labels)column = df[index]df.drop(axis=1, columns=index, inplace=True)if 'RainT' in index:temp = column.map(lambda x: labels.index(x))elif index == 'Date':temp = column.map(lambda x: x[5] if x[6] == '/' else x[5:7])else:temp = column.map(lambda x: labels.index(x) + 1)df.insert(0, index, temp)return dfdef get_dataset(location):  # 获取数据集df = pd.read_csv(location)# df = df[['Location', 'MinTemp', 'MaxTemp', 'Rainfall', 'Evaporation', 'Sunshine', 'WindGustDir', 'WindGustSpeed',#          'WindSpeed9am', 'WindSpeed3pm', 'Humidity9am', 'Humidity3pm', 'Pressure9am', 'Pressure3pm',#          'Cloud9am', 'Cloud3pm', 'Temp9am', 'Temp3pm', 'RainToday', 'RainTomorrow']]df = df.dropna()  # 去除包含缺失值的行# 用整数标签代替字符串型数据for label in ['Location', 'WindGustDir', 'WindDir9am', 'WindDir3pm', 'Date', 'RainToday', 'RainTomorrow']:df = preprocessing(df, label)# Date列格式转换date = df['Date'].astype(float)df.drop(axis=1, columns='Date', inplace=True)df.insert(2, 'Date', date)# 删除相关系数过低的数据for key in df.corr()['RainTomorrow'].keys():if (df.corr()['RainTomorrow'][key] < 0.1) & (df.corr()['RainTomorrow'][key] > -0.1):df.drop(axis=1, columns=key, inplace=True)return dfdf = get_dataset('./weatherAUS.csv')
df_list = df.values.tolist()
feature = df.drop(['RainTomorrow'], axis=1).values.tolist()
label = df['RainTomorrow'].values.tolist()feature = np.array(feature)
label = np.array(label)

可以看到,我们使用Pandas抽取了6个特征作为训练特征,而RainTomorrow作为预测值被记录。数据量的多少读者可以打印完成。

下面将生成数据整理成PyTorch数据读取格式为模型训练做准备,代码如下:

import torch
from torch.utils.data import Dataset, random_splitclass TextSamplerDataset(torch.utils.data.Dataset):def _ _init_ _(self, feature = feature, label = label):super()._ _init_ _()self.feature = torch.from_numpy(feature)/4.self.label = torch.from_numpy(label).int()def _ _getitem_ _(self, index):return self.feature[index],self.label[index]def _ _len_ _(self):return len(self.label)dataset = TextSamplerDataset(feature,label)# 定义分割比例
train_ratio = 0.9
val_ratio = 0.1# 计算每个分割的数据量
total_size = len(dataset)
train_size = int(train_ratio * total_size)
val_size = int(val_ratio * total_size)# 进行数据分割
train_dataset, val_dataset = random_split(dataset, [train_size, val_size])

在这里,TextSamplerDataset作为数据的文本读取类,对结果进行整合,并且由于特征值普遍较大,因此在计算时我们采用除以4的方法对其进行修正。random_split的作用是将完整的数据集按9:1的比例划分为训练集与测试集。

3. 天气预测模型的实现

对于天气预测模型的实现,我们将使用Jamba作为计算核心完成预测模型,而在输入的部分,由于输入的是一个1D数据,首先需要对其维度进行调整,整理成一个新的2D向量,从而进行后续的计算。

而输出层我们采用一个全连接层,将输入向量计算后整理成一个二分类,从而对结果进行预测。完整的天气预报模型如下:

class PredicateWeather(torch.nn.Module):def _ _init_ _(self,jamba_dim = 384,jamba_head = 6,feature_num = 13):super()._ _init_ _()self.feature_num = feature_numself.linear = torch.nn.Linear(feature_num,feature_num * jamba_dim)self.jamba = model.Jamba(dim=jamba_dim,attention_head_num=jamba_head)self.logits_layer = torch.nn.Linear(feature_num * jamba_dim,2)def forward(self,x):x = self.linear(x)x = einops.rearrange(x,"b (f d) -> b f d",f = self.feature_num)x = self.jamba(x)x = torch.nn.Flatten()(x)x = torch.nn.Dropout(0.1)(x)logits = self.logits_layer(x)return logits

4. 天气预报模型的训练与验证

最后,我们将使用模型在澳大利亚天气数据集上完成预测任务。在这里,我们可以同时对损失值和正确率进行监测,并通过tqdm类具体实现,代码如下:

import torch
from tqdm import tqdm
import weather_predicate
import get_weather_datasetfrom torch.utils.data import DataLoadermodel = weather_predicate.PredicateWeather()batch_size = 256
device = "cuda"model = model.to(device)# 创建数据加载器
train_loader = DataLoader(get_weather_dataset.train_dataset, batch_size=batch_size, shuffle=True)
val_loader = DataLoader(get_weather_dataset.val_dataset, batch_size=batch_size, shuffle=False)import torch
optimizer = torch.optim.AdamW(model.parameters(), lr = 2e-4)
lr_scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer,T_max = 6000,eta_min=2e-6,last_epoch=-1)
criterion = torch.nn.CrossEntropyLoss()for epoch in range(24):correct = 0  	# 用于记录正确预测的样本数量total = 0  		# 用于记录总样本数量pbar = tqdm(train_loader,total=len(train_loader))for feature,label in pbar:optimizer.zero_grad()feature = feature.float().to(device)label = label.long().to(device)logits = model(feature)loss = criterion(logits.view(-1, logits.size(-1)), label.view(-1))loss.backward()optimizer.step()lr_scheduler.step()  							# 执行优化器# 计算正确率_, predicted = torch.max(logits.data, 1)  		# 得到预测结果total += label.size(0) 							# 更新总样本数量correct += (predicted == label).sum().item()	# 更新正确预测的样本数量accuracy = 100 * correct / total  # 计算正确率pbar.set_description(f"epoch:{epoch +1},accuracy:{accuracy:.3f}%, train_loss:{loss.item():.5f}, lr:{lr_scheduler.get_last_lr()[0]*1000:.5f}")# 测试模型
model.eval()
test_correct = 0  		# 用于记录正确预测的样本数量
test_total = 0  		# 用于记录总样本数量
with torch.no_grad():for feature, label in val_loader:feature = feature.float().to(device)label = label.long().to(device)logits = model(feature)# 计算正确率_, predicted = torch.max(logits.data, 1)	# 得到预测结果test_total += label.size(0)  				# 更新总样本数量test_correct += (predicted == label).sum().item()# 更新正确预测的样本数量test_accuracy = 100 * test_correct / test_total  # 计算正确率print(f"在测试集上的准确率为:{test_accuracy}")

在这里,我们同时完成了模型的训练以及对结果的预测,并且在划分的验证集上获得了对结果准确率的验证,如下所示:

epoch:1,accuracy:69.912%, train_loss:3.56852 100%|██████████| 199/199 [00:26<00:00,  7.60it/s]
epoch:2,accuracy:74.985%, train_loss:3.15288 100%|██████████| 199/199 [00:26<00:00,  7.64it/s]
...
epoch:24,accuracy:82.689%, train_loss:0.4148 100%|██████████| 199/199 [00:26<00:00,  7.48it/s]在测试集上的准确率为:84.36724565756823

可以看到,经过24轮的预测,在训练集上我们获得了82.69%的准确率,而将模型和训练参数迁移到验证集上,我们获得了84.37%的准确率。当然,从训练集上的结果来看,此时可能还没有充分完成特征的训练,模型仍旧除于“欠拟合”状态,还需要继续训练,这一点有兴趣的读者可以继续尝试完成。

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

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

相关文章

GAMES202-高质量实时渲染(Real-Time Shadows)

目录 Shadow MappingshadowMapping的问题shadow mapping背后的数学PCF&#xff08;Percentage Closer Filtering&#xff09;PCSS&#xff08;Percentage closer soft shadows&#xff09;VSSM&#xff08;Variance Soft Shadow Mapping&#xff09;优化步骤3优化步骤1SAT&…

iphonex uniapp textarea标签兼容性处理过程梳理

嗨&#xff0c;我是小路。今天主要和大家分享的主题是“iphonex uniapp textarea标签兼容性处理过程梳理”。 在uniapp项目中&#xff0c;经常会使用到uniapp原生的textarea标签&#xff0c;但在手机兼容性这块&#xff0c;textarea并不是很好用&#xff0c;会出现一些…

C++ 区分关键字和标识符

1. 关键字&#xff08;Keywords&#xff09; 定义&#xff1a;关键字是编程语言预定义的具有特定意义的单词。它们是语言的一部分&#xff0c;C编译器具有特殊的理解规则&#xff0c;不能作为用户自定义的标识符。作用&#xff1a;关键字用于定义语言结构&#xff0c;如声明变…

杭电oj(1087、1203、1003)题解

DP 即动态规划&#xff08;Dynamic Programming&#xff09;&#xff0c;是一种通过把原问题分解为相对简单的子问题&#xff0c;并保存子问题的解来避免重复计算&#xff0c;从而解决复杂问题的算法策略。以下从几个方面简述动态规划&#xff1a; 基本思想 动态规划的核心在…

一键多环境构建——用 Hvigor 玩转 HarmonyOS Next

引言 在 HarmonyOS Next 的应用开发中&#xff0c;常常需要针对不同环境&#xff08;测试、预发、线上&#xff09;或不同签名&#xff08;调试、正式&#xff09;输出多个 APP/HAP 包。虽然 HarmonyOS 提供了多目标构建&#xff08;Multi-Target Build&#xff09;能力&#…

qt/c++云对象浏览器

简介 本项目为基于QT5和C11的云对象存储可视化管理工具 源码获取 int main(){ printf("源码联系绿泡泡:%s","joyfelic"); return 0; }

【Ubuntu】提升 docker ps -a 输出的可读性:让 Docker 容器状态更清晰

提升 docker ps -a 输出的可读性&#xff1a;让 Docker 容器状态更清晰 当我们使用 docker ps -a 查看所有 Docker 容器时&#xff0c;输出的信息通常会非常多&#xff0c;尤其是在容器数量较多时。默认输出中包含容器 ID、名称、镜像、状态、端口等信息&#xff0c;容易让人眼…

Spring Security自定义身份认证

尽管项目启动时&#xff0c;Spring Security会提供了默认的用户信息&#xff0c;可以快速认证和启动&#xff0c;但大多数应用程序都希望使用自定义的用户认证。对于自定义用户认证&#xff0c;Spring Security提供了多种认证方式&#xff0c;常用的有In-Memory Authentication…

在亚马逊云服务器上部署WordPress服务

在亚马逊云服务器上部署WordPress服务第一步&#xff1a;创建EC2实例第二步&#xff1a;初始设置与安装第三步&#xff1a;配置MySQL与WordPress第四步&#xff1a;配置Apache与WordPress第五步&#xff1a;访问WordPress第六步&#xff1a;测试数据库连接第七步&#xff1a;使…

Web3.0的认知补充(去中心化)

涉及开发技术&#xff1a; Vue Web3.js Solidity 基本认知 Web3.0含义&#xff1a; 新一代互联网思想&#xff1a;去中心化及用户为中心的互联网 数据&#xff1a;可读可写可授权 核心技术&#xff1a;区块链、NFT 应用&#xff1a;互联网上应用 NFT &…

如何修复宝可梦时时刻刻冒险无法正常工作

宝可梦的时时刻刻冒险模式是一项强大的功能&#xff0c;即使应用程序关闭&#xff0c;它也能追踪你的步行距离。它的工作原理是将你的步数与 iOS 上的 Apple Health 或 Android 上的 Google Fit 同步。它对于孵化宝可梦蛋和赚取好友糖果至关重要&#xff0c;但一旦它停止工作&a…

redis常用集合操作命令

在 Redis 的命令行界面&#xff08;redis-cli&#xff09;中&#xff0c; Redis 的集合&#xff08;Set&#xff09;是无序的&#xff0c;且集合中的元素是唯一的。Redis 本身没有直接提供获取集合中某个特定属性的命令&#xff0c;因为集合中的元素是简单的值&#xff0c;而不…

初识数据结构——二叉树从基础概念到实践应用

数据结构专栏 ⬅(click) 初识二叉树&#xff1a;从基础概念到实践应用&#x1f333; 一、树型结构基础 1.1 树的基本概念 树是一种非线性的数据结构&#xff0c;由n(n>0)个有限节点组成一个具有层次关系的集合。它看起来像一棵倒挂的树&#xff0c;根朝上而叶朝下。 关键特…

驼峰命名法(Camel Case)与匈牙利命名法(Hungarian Notation)详解

驼峰命名法&#xff08;Camel Case&#xff09;与匈牙利命名法&#xff08;Hungarian Notation&#xff09;详解及对比‌ ‌1. 驼峰命名法&#xff08;Camel Case&#xff09;‌ ‌定义‌ 驼峰命名法&#xff08;Camel Case&#xff09;是一种变量、函数、类等标识符的命名方…

keil 中优化等级的bug

一&#xff0c;问题描述 程序中代码有的执行&#xff0c;有的不执行&#xff0c;仔细研究&#xff0c;查询人工智能。 程序中printf打印后面的代码不执行&#xff0c; 然后过几十个函数又开始正常了。 二.分析问题 跳过函数一般又判断和Goto等语句&#xff0c;其它的溢出和错误…

织梦dedecms网站如何修改上一篇下一篇的标题字数

一般情况下&#xff0c;如果你的上一篇和下一篇是2行布局就不需要限制标题的字数了&#xff0c;如果你要一行布局上一篇和下一篇标题过长就会打乱网页布局&#xff0c;那么限制上一篇和下一篇的标题字数是需要的&#xff0c;避免页面看起来杂乱不堪。 织梦dedecms网站如何修改…

信创系统 sudoers 权限配置实战!从小白到高手

好文链接&#xff1a;实战&#xff01;银河麒麟 KYSEC 安全中心执行控制高级配置指南 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于信创终端操作系统中 sudoers 文件详解的实用文章&#xff01;在 Linux 系统中&#xff0c;sudo 是一项非常重要的权限控制机制…

《明解C语言入门篇》读书笔记四

目录 第四章&#xff1a;程序的循环控制 第一节&#xff1a;do语句 do语句 复合语句&#xff08;程序块&#xff09;中的声明 读取一定范围内的值 逻辑非运算符 德摩根定律 德摩根定律 求多个整数的和及平均值 复合赋值运算符 后置递增运算符和后置递减运算符 练习…

vite+vue2+elementui构建之 vite.config.js

webpack版本太低&#xff0c;构建依赖太多&#xff0c;头大。 各种查阅资料&#xff0c;弄了一份直通构建vite构建elementUi核心文件&#xff0c; 构建基于开源若依vue2vue3版本改造&#xff0c;感谢开源&#xff0c;感谢若依。 package.json 地址 vitevue2elementui构建之…

超参数详解:从基础概念到优化策略的全面指南

摘要 本文深入解析机器学习中超参数的核心概念&#xff0c;详细对比参数与超参数的本质区别&#xff0c;系统介绍学习率、隐含层数量等常见超参数类型&#xff0c;以及网格搜索、贝叶斯优化等主流寻优方法。结合超参数搜索的标准流程&#xff0c;通过具体案例演示如何高效调整…