当前位置: 首页 > news >正文

政安晨:【深度学习处理实践】(三)—— 处理时间序列的数据准备

在深度学习中,对时间序列的处理主要涉及到以下几个方面

  1. 序列建模:深度学习可以用于对时间序列进行建模。常用的模型包括循环神经网络(Recurrent Neural Networks, RNN)和长短期记忆网络(Long Short-Term Memory, LSTM)。这些模型可以在输入序列的基础上进行学习,捕捉序列中的时间关系和时序模式。

  2. 序列预测:深度学习也可以用于时间序列的预测。通过对历史数据进行建模,可以利用深度学习模型来预测未来的数值或趋势。常用的模型包括循环神经网络(RNN)和卷积神经网络(Convolutional Neural Networks, CNN)。

  3. 应用领域:深度学习在时间序列的处理中被广泛应用于各个领域。例如,金融领域中可以利用深度学习模型来预测股票价格;气象领域中可以利用深度学习模型来预测天气变化;语音识别领域中可以利用深度学习模型来识别语音信号中的文字内容。

总的来说,深度学习在时间序列的处理中能够利用神经网络的强大表达能力,通过学习历史数据的模式和规律,来进行序列的建模和预测。这使得深度学习成为处理时间序列数据的一种强大工具。

政安晨的个人主页政安晨

欢迎 👍点赞✍评论⭐收藏

收录专栏政安晨的机器学习笔记

希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正!

不同类型的时间序列任务

时间序列(timeseries)是指定期测量获得的任意数据比如每日股价、城市每小时耗电量或商店每周销售额

无论是自然现象(如地震活动、鱼类种群的演变或某地天气)还是人类活动模式(如网站访问者、国家GDP或信用卡交易),时间序列都无处不在。

与前面遇到的数据类型不同,处理时间序列需要了解系统的动力学(dynamics),包括系统的周期性循环、系统随时间如何变化、系统的周期规律与突然激增等。

目前,最常见的时间序列任务是预测:预测序列接下来会发生什么

比如提前几小时预测用电量,以便于预计需求;

提前几个月预测收入,以便于制订预算计划;

提前几天预测天气,以便于规划日程。预测是本章的重点内容。

但实际上,你还可以对时间序列做很多其他事情。

分类为时间序列分配一个或多个分类标签。例如,已知一名网站访问者的活动时间序列,判断该访问者是机器人还是人类。

事件检测识别连续数据流中特定预期事件的发生。一个特别有用的应用是“热词检测”,模型监控音频流并检测像“Ok Google”或“Hey Alexa”这样的话。

异常检测检测连续数据流中出现的异常情况。

公司网络出现异常活动?可能是有攻击者。

生产线出现异常读数?是时候让人去查看一下了。

异常检测通常是通过无监督学习实现的,因为你通常不知道要检测哪种异常,所以无法针对特定的异常示例进行训练。

处理时间序列时你会遇到许多特定领域的数据表示方法。例如,你可能听说过傅里叶变换,它是指将一系列值表示为不同频率的波的叠加。对那些以周期和振荡为主要特征的数据(如声音、摩天大楼的振动或人的脑电波)进行预处理时,傅里叶变换可以发挥很大作用。对于深度学习而言,傅里叶分析(或相关的梅尔频率分析)与其他特定领域的表示可以用来做特征工程。这是一种在训练模型之前准备数据的方式,以便让模型更容易运行。然而,这篇文章不会介绍这些技术,而是将重点放在构建模型上。

咱们这篇文章将介绍循环神经网络(recurrent neural network,RNN)及如何将其应用于时间序列预测。

温度预测示例

咱们这篇文章所有代码示例都针对同一个问题:已知每小时测量的气压、湿度等数据的时间序列(数据由屋顶的一组传感器记录),预测24小时之后的温度。你会发现,这是一个相当有挑战性的问题。

利用这个温度预测任务,我们会展示时间序列数据与之前见过的各类数据集在本质上有哪些不同。你会发现,密集连接网络和卷积神经网络并不适合处理这种数据集,而另一种机器学习技术——循环神经网络——在这类问题上大放异彩。

我们将使用一个天气时间序列数据集,它由德国耶拿的马克斯•普朗克生物地球化学研究所的气象站记录。在这个数据集中,每10分钟记录14个物理量(如温度、气压、湿度、风向等),其中包含多年的记录。原始数据可追溯至2003年,但本例仅使用2009年~2016年的数据。

咱们在Jupyter中下载这个数据集并解压:

!wget https://s3.amazonaws.com/keras-datasets/jena_climate_2009_2016.csv.zip
!unzip jena_climate_2009_2016.csv.zip

解压数据:

接下来咱们查看数据:

查看耶拿天气数据集

import os
fname = os.path.join("jena_climate_2009_2016.csv")with open(fname) as f:data = f.read()lines = data.split("\n")
header = lines[0].split(",")
lines = lines[1:]
print(header)
print(len(lines))

演绎执行如下:

从输出可以看出,共有420 451行数据(每行数据是一个时间步,记录了1个日期和14个与天气有关的值),输出还包含以上表头

接下来,我们将所有420 451行数据转换为NumPy数组,代码如下所示:一个数组包含温度(单位为摄氏度),另一个数组包含其他数据。我们将使用这些特征来预测温度。请注意,我们舍弃了"Date Time"(日期和时间)这一列。

解析数据

import numpy as np
temperature = np.zeros((len(lines),))
raw_data = np.zeros((len(lines), len(header) - 1))
for i, line in enumerate(lines):values = [float(x) for x in line.split(",")[1:]]# 将第1列保存在temperature数组中temperature[i] = values[1]# 将所有列(包括温度)保存在raw_data数组中raw_data[i, :] = values[:]

我们来绘制温度随时间的变化曲线(单位为摄氏度),代码如下所示。在这张图中,你可以清楚地看到温度的年度周期性变化,数据跨度为8年。

绘制温度时间序列

from matplotlib import pyplot as plt
plt.plot(range(len(temperature)), temperature)

如果您的环境中还没有matplotlib,可以参考我的这篇文章安装:

政安晨:在Jupyter中【示例演绎】Matplotlib的官方指南(一){Pyplot tutorial}icon-default.png?t=N7T8https://blog.csdn.net/snowdenkeke/article/details/136096870执行如下:

上面这个是数据集整个时间范围内的温度(℃)。

现在,我们来绘制前10天温度数据的曲线,代码如下所示。由于每10分钟记录一次数据,因此每天有144个数据点(24×6=144)。

绘制前10天的温度时间序列

plt.plot(range(1440), temperature[:1440])

从上图中可以看到每天的周期性变化,尤其是最后4天特别明显。另外请注意,这10天一定是来自于寒冷的冬季月份。

始终在数据中寻找周期性

在多个时间尺度上的周期性,是时间序列数据非常重要且常见的属性。

无论是天气、商场停车位使用率、网站流量、杂货店销售额,还是健身追踪器记录的步数,你都会看到每日周期性和年度周期性(人类生成的数据通常还有每周的周期性)。

探索数据时,一定要注意寻找这些模式。

对于这个数据集,如果你想根据前几个月的数据来预测下个月的平均温度,那么问题很简单,因为数据具有可靠的年度周期性。但如果查看几天的数据,那么你会发现温度看起来要混乱得多。以天作为观察尺度,这个时间序列是可预测的吗?我们来寻找这个问题的答案。

在后续所有实验中,我们将前50%的数据用于训练,随后的25%用于验证,最后的25%用于测试,代码如下所示。处理时间序列数据时,有一点很重要验证数据和测试数据应该比训练数据更靠后,因为你是要根据过去预测未来,而不是反过来,所以验证/测试划分应该反映这一点。如果将时间轴反转,有些问题就会变得简单得多。

(这段代码是计算用于训练、验证和测试的样本数

num_train_samples = int(0.5 * len(raw_data))
num_val_samples = int(0.25 * len(raw_data))
num_test_samples = len(raw_data) - num_train_samples - num_val_samples
print("num_train_samples:", num_train_samples)
print("num_val_samples:", num_val_samples)
print("num_test_samples:", num_test_samples)

执行如下:

准备数据

这个问题的确切表述如下:每小时采样一次数据,给定前5天的数据,我们能否预测24小时之后的温度?

我们对数据进行预处理,将其转换为神经网络可以处理的格式。这很简单。因为数据已经是数值型的,所以不需要做向量化。但数据中的每个时间序列位于不同的范围,比如气压大约在1000毫巴(mbar)1,而水汽浓度(H2OC)大约为3毫摩尔/摩尔(mmol/mol)。我们将对每个时间序列分别做规范化,使其处于相近的范围,并且都取较小的值,代码如下所示:我们使用前210 225个时间步作为训练数据,所以只计算这部分数据的均值和标准差。

(如下代码为数据规范化

mean = raw_data[:num_train_samples].mean(axis=0)
raw_data -= mean
std = raw_data[:num_train_samples].std(axis=0)
raw_data /= std

接下来我们创建一个Dataset对象,它可以生成过去5天的数据批量,以及24小时之后的目标温度。由于数据集中的样本是高度冗余的(对于样本N和样本N+1,二者的大部分时间步是相同的),因此显式地保存每个样本将浪费资源。相反,我们将实时生成样本,仅保存最初的数组raw_data和temperature。

我们可以轻松地编写一个Python生成器来完成这项工作,但也可以直接利用Keras内置的数据集函数(timeseries_dataset_from_array()),从而减少工作量。一般来说,你可以将这个函数用于任意类型的时间序列预测任务。

理解timeseries_dataset_from_array()

为了理解timeseries_dataset_from_array()的作用,我们来看一个简单的例子。这个例子的大致思想是:给定一个由时间序列数据组成的数组(data参数),timeseries_dataset_from_array()可以给出从原始时间序列中提取的窗口(我们称之为“序列”)。

举个例子,对于data = [0, 1, 2, 3, 4, 5, 6]和sequence_length = 3,timeseries_dataset_from_array()将生成以下样本:[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4,5], [4, 5, 6]。

你还可以向timeseries_dataset_from_array()传入targets参数(一个数组)。targets数组的第一个元素应该对应data数组生成的第一个序列的预期目标。因此,做时间序列预测时,targets应该是与data大致相同的数组,并偏移一段时间。

例如,对于data = [0, 1, 2, 3, 4, 5, 6, ...]和sequence_length = 3,你可以传入targets = [3,4, 5, 6, ...],创建一个数据集并预测时间序列的下一份数据。我们来试一下。

import numpy as np
from tensorflow import keras# 生成一个从0到9的有序整数数组
int_sequence = np.arange(10)
dummy_dataset = keras.utils.timeseries_dataset_from_array(# 序列将从[0, 1, 2, 3, 4, 5, 6]中抽样data=int_sequence[:-3],# 对于以data[N]开头的序列,其目标是data[N+3]targets=int_sequence[3:],# 序列长度是3个时间步sequence_length=3,# 序列批量大小为2batch_size=2,
)for inputs, targets in dummy_dataset:for i in range(inputs.shape[0]):print([int(x) for x in inputs[i]], int(targets[i]))

代码运行如下:

我们将使用timeseries_dataset_from_array()来创建3个数据集,分别用于训练、验证和测试,代码如下所示:

我们将使用以下参数值。

sampling_rate = 6:观测数据的采样频率是每小时一个数据点,也就是说,每6个数据点保留一个。

sequence_length = 120:给定过去5天(120小时)的观测数据。

delay = sampling_rate * (sequence_length + 24- 1):序列的目标是序列结束24小时之后的温度。创建训练数据集时,我们传入start_index = 0和end_index = num_train_samples,只使用前50%的数据。对于验证数据集,我们传入start_index =num_train_samples和end_index =num_train_samples + num_val_samples,使用接下来25%的数据。最后对于测试数据集,我们传入start_index =num_train_samples + num_val_samples,使用剩余数据。

创建3个数据集,分别用于训练、验证和测试:

sampling_rate = 6
sequence_length = 120
delay = sampling_rate * (sequence_length + 24 - 1)
batch_size = 256train_dataset = keras.utils.timeseries_dataset_from_array(raw_data[:-delay],targets=temperature[delay:],sampling_rate=sampling_rate,sequence_length=sequence_length,shuffle=True,batch_size=batch_size,start_index=0,end_index=num_train_samples)val_dataset = keras.utils.timeseries_dataset_from_array(raw_data[:-delay],targets=temperature[delay:],sampling_rate=sampling_rate,sequence_length=sequence_length,shuffle=True,batch_size=batch_size,start_index=num_train_samples,end_index=num_train_samples + num_val_samples)test_dataset = keras.utils.timeseries_dataset_from_array(raw_data[:-delay],targets=temperature[delay:],sampling_rate=sampling_rate,sequence_length=sequence_length,shuffle=True,batch_size=batch_size,start_index=num_train_samples + num_val_samples)

每个数据集都会生成一个元组(samples, targets),其中samples是包含256个样本的批量,每个样本包含连续120小时的输入数据;targets是包含相应的256个目标温度的数组。请注意,因为样本已被随机打乱,所以一批数据中的两个连续序列(如samples[0]和samples[1])不一定在时间上接近。我们来查看数据集的输出,如下代码所示:

查看一个数据集的输出

for samples, targets in train_dataset:print("samples shape:", samples.shape)print("targets shape:", targets.shape)break

演绎如下:


咱们先告一段落,下篇文章继续。

相关文章:

政安晨:【深度学习处理实践】(三)—— 处理时间序列的数据准备

在深度学习中,对时间序列的处理主要涉及到以下几个方面: 序列建模:深度学习可以用于对时间序列进行建模。常用的模型包括循环神经网络(Recurrent Neural Networks, RNN)和长短期记忆网络(Long Short-Term M…...

PCL不同格式点云读取速度(Binary和ASCII )

首先说明一点:Binary(二进制)格式点云文件进行读取时要比Ascll码格式点云读取时要快的多,尤其是对于大型的点云文件,如几百万、甚至几千万个点云的情况下。 今天遇到了一种情况,在写项目的时候进行点云读取,读取的时候…...

Neo4J图数据库入门示例

前言 - Neo4j和MySQL的区别 Neo4j 和 MySQL 是两种不同类型的数据库,它们在数据模型、用途、性能和查询语言等方面有着显著的区别。以下是它们的主要区别: 数据模型: Neo4j 是一种图数据库,它使用图数据模型来存储和查询数据。在…...

牛客每日一题之 二维前缀和

题目介绍: 题目链接:【模板】二维前缀和_牛客题霸_牛客网 先举两个简单的例子,来帮大家理解题目,注意理解二维前缀和要先要一维前缀和的基础,不了解的可以看我上一篇博客。 若x11,y11, x23, y2 3,这是要…...

动态规划 Leetcode 70 爬楼梯

爬楼梯 Leetcode 70 学习记录自代码随想录 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例 1: 输入:n 2 输出:2 解释:有两种方法可以爬到…...

(未解决)macOS matplotlib 中文是方框

reference: Mac OS系统下实现python matplotlib包绘图显示中文(亲测有效)_mac plt 中文值-CSDN博客 module ‘matplotlib.font_manager‘ has no attribute ‘_rebuild‘解决方法_font_manager未解析-CSDN博客 # 问题描述(笑死 显而易见 # solve 找到…...

深入探讨C#中的递归算法

一、什么是递归算法? 递归是指一个函数或方法在执行过程中调用自身的情况。递归算法是编程中常见的一种解决问题的方法。它将一个问题分解成一个或多个与原问题相似但规模更小的子问题,然后通过解决这些子问题来解决原问题。递归算法通常用于解决重复性的…...

三款顶级开源RAG (检索增强生成)工具:Verba、Unstructured 和 Neum

三款顶级开源RAG (检索增强生成)工具:Verba、Unstructured 和 Neum 概述 随着企业对话式数据处理需求的提升,面临的挑战是数据隐私性和缺乏企业级解决方案。虽然类似LangChain能在短时间内构建RAG应用,但忽视了文档解析、多来源数据ETL、批量…...

VC++、MFC中操作excel时,CRange中get_EntireRow()和get_EntireColumn()函数的用法及区别是什么?

在VC和MFC中操作Excel时,通过COM接口与Excel交互时,CRange 对象(或更准确地说是 Excel::Range 对象)代表一个单元格范围。CRange 类提供了一系列方法来获取或操作这个范围内的单元格。其中,get_EntireRow() 和 get_Ent…...

npm 操作报错记录1- uninstall 卸载失效

npm 操作报错记录1- uninstall 卸载失效 1、问题描述 安装了包 vue/cli-plugin-eslint4.5.0 vue/eslint-config-prettier9.0.0 但是没有使用 -d ,所以想重新安装,就使用 uninstall 命令卸载,结果卸载了没反应,也没有报错&#xf…...

openCV保存图像

保存图像 //保存为png透明通道vector<int>opts;opts.push_back(IMWRITE_PAM_FORMAT_RGB_ALPHA);imwrite("D:/img_bgra.png", img, opts);//保存为单通道灰度图像img cv::imread(imagePath.toStdString(), IMREAD_GRAYSCALE);vector<int> opts_gray;opts…...

mac 配置.bash_profile不生效问题

1、问题描述 mac系统中配置了环境变量只能在当前终端生效&#xff0c;切换了终端就无效了&#xff0c;查了下问题所在。mac系统会预装一个终极shell - zsh&#xff0c;环境变量读取在 .zshrc 文件下。 2、解决方案 1、切换终端到bash 切换终端到bash chsh -s /bin/bash 切换终端…...

【Cesium for Supermap】S3MTiles图层box裁剪

效果图&#xff1a; 代码&#xff1a; let viewer new Cesium.Viewer(cesiumContainer);// 添加SuperMap iServer发布的S3M缓存服务let promise viewer.scene.addS3MTilesLayerByScp("http://www.supermapol.com/realspace/services/3D-BIMbuilding/rest/realspace/data…...

PAT部分题目相关知识点——python

python中的整除 在Python中&#xff0c;整除&#xff08;也称为地板除&#xff09;可以使用**//**运算符来实现。当使用//运算符时&#xff0c;结果将是一个整数&#xff0c;它表示除法运算的整数部分&#xff0c;舍去任何小数部分。 示例&#xff1a; # 使用整除运算符 // …...

Redis核心数据结构之字典(二)

字典 解决键冲突 当有两个或以上数量的键被分配到了一个哈希表数组的同一个索引上面&#xff0c;我们称这些键发生了冲突(collision)。 Redis的哈希表使用链地址法(separate chaining)来解决键冲突&#xff0c;每个哈希表节点都有一个next指针&#xff0c;多个哈希表节点可以…...

拯救行动(BFS)

公主被恶人抓走&#xff0c;被关押在牢房的某个地方。牢房用 N \times M (N, M \le 200)NM(N,M≤200) 的矩阵来表示。矩阵中的每项可以代表道路&#xff08;&#xff09;、墙壁&#xff08;#&#xff09;、和守卫&#xff08;x&#xff09;。 英勇的骑士&#xff08;r&#xf…...

985硕的4家大厂实习与校招经历专题分享(part2)

我的个人经历&#xff1a; 985硕士24届毕业生&#xff0c;实验室方向:CV深度学习 就业&#xff1a;工程-java后端 关注大模型相关技术发展 校招offer: 阿里巴巴 字节跳动 等10 研究生期间独立发了一篇二区SCI 实习经历:字节 阿里 京东 B站 &#xff08;只看大厂&#xff0c;面试…...

【NR技术】 3GPP支持无人机的关键技术以及场景

1 背景 人们对使用蜂窝连接来支持无人机系统(UAS)的兴趣浓厚&#xff0c;3GPP生态系统为UAS的运行提供了极好的好处。无处不在的覆盖范围、高可靠性和QoS、强大的安全性和无缝移动性是支持UAS指挥和控制功能的关键因素。与此同时&#xff0c;监管机构正在调查安全和性能标准以及…...

【译】WordPress Bricks主题安全漏洞曝光,25,000个安装受影响

WordPress的Bricks主题存在一个严重的安全漏洞&#xff0c;恶意威胁行为者正在积极利用该漏洞在易受攻击的安装上运行任意PHP代码。 该漏洞被跟踪为CVE-2024-25600&#xff08;CVSS评分&#xff1a;9.8&#xff09;&#xff0c;使未经身份验证的攻击者能够实现远程代码执行。它…...

【C++ 23种设计模式】

C 23种设计模式 ■ 创建型模式(5种)■ 工厂模式■ 抽象工厂模式■ 原型模式■ 单例模式■ 第一种&#xff1a;单线程&#xff08;懒汉&#xff09;■ 第二种&#xff1a;多线程&#xff08;互斥量实现锁懒汉&#xff09;■ 第三种&#xff1a;多线程&#xff08;const static饿…...

亚信安慧AntDB:企业数据管理的明日之星

在信息科技飞速发展的时代&#xff0c;亚信科技AntDB团队提出了一项颠覆性的“超融合”理念&#xff0c;旨在满足企业日益增长的复杂混合负载和多样化数据类型的业务需求。这一创新性框架的核心思想在于融合多引擎和多能力&#xff0c;充分发挥分布式数据库引擎的架构优势&…...

Android Gradle开发与应用 (三) : Groovy语法概念与闭包

1. Groovy介绍 Groovy是一种基于Java平台的动态编程语言&#xff0c;与Java是完全兼容&#xff0c;除此之外有很多的语法糖来方便我们开发。Groovy代码能够直接运行在Java虚拟机&#xff08;JVM&#xff09;上&#xff0c;也可以被编译成Java字节码文件。 以下是Groovy的一些…...

Android 14 设置锁屏为NONE后开启双卡PIN锁,重启设备后,输完卡1的PIN码就进入了安卓界面,未提示输入卡2的PIN码

一.问题背景 目前在多个Android14平台发现开启双卡PIN码并且关闭屏幕锁的情况下,第二个PIN码锁输入弹框不能弹出问题,导致第二个卡不能注网。 如下是未修改前重启后解锁卡1PIN码的状态 可以看出卡2不能正常使用 二.何处关闭了卡2的PIN锁? 1.添加日志 首先在KeyguardSecu…...

2024 GoLand激活,分享几个GoLand激活的方案

文章目录 GoLand公司简介我这边使用GoLand的理由GoLand 最新变化GoLand 2023.3 最新变化AI Assistant 正式版GoLand 中的 AI Assistant&#xff1a;_Rename_&#xff08;重命名&#xff09;GoLand 中的 AI Assistant&#xff1a;_Write documentation_&#xff08;编写文档&…...

linux中对信号的认识

信号的概念与相关知识认识 信号是向目标进程发送消息通知的的一种机制。 信号可以以异步的方式发送给进程&#xff0c;也就是说&#xff0c;进程无需主动等待&#xff0c;而是在任何时间都可以接收到信号。 信号的种类 用kill-l命令查看系统定义的信号列表&#xff1a; 前台…...

【万题详解】P1048 [NOIP2005 普及组] 采药

题目描述 链接——题目在这里&#xff01;&#xff01;&#xff01; 辰辰是个天资聪颖的孩子&#xff0c;他的梦想是成为世界上最伟大的医师。为此&#xff0c;他想拜附近最有威望的医师为师。医师为了判断他的资质&#xff0c;给他出了一个难题。医师把他带到一个到处都是草…...

Golang基于Redis bitmap实现布隆过滤器(完结版)

Golang基于Redis bitmap实现布隆过滤器&#xff08;完结版&#xff09; 为了防止黑客恶意刷接口&#xff08;请求压根不存在的数据&#xff09;&#xff0c;目前通常有以下几种做法&#xff1a; 限制IP&#xff08;限流&#xff09;Redis缓存不存在的key布隆过滤器挡在Redis前 …...

Java基础-内部类

内部类 引言内部类的共性成员内部类静态内部类非静态内部类 局部内部类匿名内部类内部类的使用场景和好处 引言 Java不仅可以定义变量和方法,还可以定义类. 内部类允许你把一些逻辑相关的类组织在一起,并可以控制内部中类的可见性. 这么看来,内部类就像是代码一种隐藏机制:将类…...

设计模式-行为型模式-职责链模式

在软件系统运行时&#xff0c;对象并不是孤立存在的&#xff0c;它们可以通过相互通信协作完成某些功能&#xff0c;一个对象在运行时也将影响到其他对象的运行。行为型模式&#xff08;Behavioral Pattern&#xff09;关注系统中对象之间的交互&#xff0c;研究系统在运行时对…...

代码随想录算法训练营第四十天|LeetCode343 整数拆分、LeetCode96 不同的二叉搜索树

343.整数拆分 思路&#xff1a;确定dp数组以及下标的含义 dp[i]代表 i可以被拆分后的最大乘积。确定递推公式&#xff0c;假如拆成连个数&#xff0c;dp[i] j*(i-j),拆成两个数以上&#xff0c;dp[i]j*dp[i-j]&#xff0c;j的范围为1到i-1.dp[i]找到所有情况的最大值。初始化…...