你好,我要用matlab写一个程序,我的excel文件名是FC1_Ageing_part,采用的方法是分度聚合近似法,有以下的要求: 1.出一张关于预测数据和原始数据的拟合图,改图中只需要excel表中的第二列数据,即电压原始数据,第一列数据为时间,后面出的图x轴均为时间,预测数据采用上述所得的方法提取出来的,只需要提取出10%的数据。 2.最后需要输出一个excel表格,输出的excel数据不仅仅是第二列提取的电压数据,我要把那一列中每个数据对应的行的数据都输出来。 3.输出的还有评价性能指标MSE、RMSE、MAE和R的平方。 4.提取出来的数据用线显示,并且原始数据是黑色的线,提取出的数据为红色,预测数据直接用线,不要显示上面提取的点,不好观察 5.再出一张插值误差分布图,并且在图的合适位置显示MSE、RMSE、MAE和R的平方。
时间: 2025-07-22 15:29:41 浏览: 2
<think>我们使用分度聚合近似法(PAA)对时间序列进行降维,提取10%的数据点。然后,我们将原始数据和降维后的数据绘制在同一张图上,并计算性能指标(MSE, RMSE, MAE, R²)。同时,我们还需要输出包含原始行数据的Excel文件(即提取的点对应的整行数据),以及绘制插值误差分布图。
步骤:
1. 读取Excel文件,假设文件名为'FC1_Ageing_part.xlsx',我们使用第一列作为时间,第二列作为电压。
2. 使用PAA方法提取10%的数据点(即每隔10个点取一个点,但注意PAA是将序列分成等长的段,每段用该段的均值代替)。这里我们假设总共有N个点,我们将其分成M段,使得M为总点数的10%,即M = ceil(N/10)。然后每段取一个点(即该段的均值),这样我们得到10%的聚合点。
3. 为了绘制连续的预测线,我们需要对提取的PAA点进行插值(线性插值),使其长度与原始数据相同,这样我们才能计算误差指标。
4. 计算原始数据与插值后的预测数据之间的误差指标:MSE、RMSE、MAE和R平方。
5. 绘制原始数据(黑色线)和预测数据(红色线)的拟合图。
6. 输出一个Excel文件,包含提取的10%数据点对应的原始行数据(即提取点所在行的所有列数据)。注意,我们提取的是原始数据点(但这里我们使用PAA方法提取的是聚合点,所以实际上我们得到的是分段内的均值,但原始数据中并没有直接对应的行,因此我们需要记录每个分段的中点位置(或分段内的索引)然后从原始数据中取出这些索引对应的整行?但是PAA并不直接对应原始点,所以有两种做法:
a) 输出每个分段对应的原始数据中的第一个点(或中间点)所在的行数据。但这样输出的数据就不是我们聚合的值了,而是原始值。根据要求,我们需要输出的是提取的电压数据(即聚合值)对应的行数据。这里要求输出的是“那一列中每个数据对应的行的数据”,意思是对于每个提取的聚合点,我们输出该聚合点所代表的原始数据段中的某个原始行?但通常PAA聚合点并不对应某个具体原始点,而是代表一段。所以这里可能需要明确:我们输出的行数据是指每个分段中我们选择的代表点(比如分段中间点)对应的原始行数据?或者我们输出每个分段的所有原始行数据?但这样数据量就多了。根据要求,我们提取了10%的数据,所以输出也应该是10%的行。因此,我们选择每个分段的中间点(取整索引)对应的原始行数据,这样每个分段只输出一行,这一行包含该分段中间点的时间、电压(原始值)以及其他列的数据。但是注意,我们聚合的电压值是分段的均值,而输出的行中电压值是原始值,这并不矛盾,因为要求是输出提取的数据(即聚合点)对应的行数据(即该聚合点所代表的原始数据段中的某一行,这里我们取中间行)。这样,输出的Excel中,电压列实际上是原始值,而不是聚合的均值。但题目要求输出的是“提取的电压数据”对应的行,而提取的电压数据是聚合值,但聚合值并不在原始行中,所以这里可能有两种理解:
1)输出每个分段中第一个原始数据行(或中间行)的数据,这样电压值就是原始值,而不是聚合值。
2)另外创建一个Excel,其中包含聚合后的数据(即时间、聚合电压等),但题目要求输出的是原始行数据(即包含其他列),所以只能是第一种。
因此,我们这样处理:对于每个分段,我们取该分段中间位置对应的原始行数据(包括所有列)作为该分段的代表行。这样输出的Excel中每一行代表一个分段,但电压值是该行原本的电压值(不是聚合值)。同时,我们也会将聚合值(即每个分段的均值)保存在另一个变量中用于绘图和计算指标。但是,在绘制原始数据与预测数据时,我们使用聚合值插值后的曲线作为预测数据。
7. 绘制插值误差分布图(即原始数据与预测数据的差值图),并在图中标注性能指标。
具体实现:
步骤1:读取数据
```matlab
data = readtable('FC1_Ageing_part.xlsx');
time = data{:,1}; % 第一列时间
voltage = data{:,2}; % 第二列电压
```
步骤2:应用PAA方法提取10%的数据点
```matlab
n = length(voltage);
% 计算分段数,我们取总点数的10%,所以分段数为ceil(n/10)
num_segments = ceil(n / 10); % 10%的数据点,即分成ceil(n/10)段
% 计算每段的点数(可能不是整数,所以需要处理不等长的情况)
points_per_segment = floor(n / num_segments);
% 初始化存储聚合点的数组
paa_time = zeros(num_segments, 1);
paa_voltage = zeros(num_segments, 1);
% 同时,记录每个分段的中间点索引,用于输出原始行
segment_indices = zeros(num_segments, 1); % 存储每个分段中间点的索引
% 遍历每个分段
for i = 1:num_segments
% 计算当前分段的索引范围
start_index = (i-1) * points_per_segment + 1;
if i == num_segments
end_index = n; % 最后一个分段包含剩余所有点
else
end_index = i * points_per_segment;
end
segment = voltage(start_index:end_index);
% 计算该分段的均值
paa_voltage(i) = mean(segment);
% 取该分段中间位置的时间(取中间点的时间)
mid_index = floor((start_index + end_index) / 2);
segment_indices(i) = mid_index;
paa_time(i) = time(mid_index);
end
```
步骤3:对PAA点进行插值,得到与原始数据长度相同的预测序列
```matlab
% 使用线性插值
predicted_voltage = interp1(paa_time, paa_voltage, time, 'linear', 'extrap');
% 注意:由于PAA点的时间是每个分段的中间时间,而原始时间序列可能不是等间隔,所以用插值
% 但是,如果原始时间不是等间隔,我们插值可能会引入误差。这里假设时间序列是等间隔的,或者插值方法合适。
```
步骤4:计算性能指标
```matlab
% 计算误差
errors = voltage - predicted_voltage;
% MSE: 均方误差
MSE = mean(errors.^2);
% RMSE: 均方根误差
RMSE = sqrt(MSE);
% MAE: 平均绝对误差
MAE = mean(abs(errors));
% R²: 决定系数
SS_res = sum(errors.^2);
SS_tot = sum((voltage - mean(voltage)).^2);
R2 = 1 - (SS_res / SS_tot);
```
步骤5:绘制原始数据和预测数据拟合图
```matlab
figure;
plot(time, voltage, 'k-', 'LineWidth', 1.5); % 原始数据,黑色线
hold on;
plot(time, predicted_voltage, 'r-', 'LineWidth', 1.5); % 预测数据,红色线
xlabel('Time');
ylabel('Voltage');
legend('Original Data', 'Predicted Data');
title('Original vs Predicted Voltage');
grid on;
```
步骤6:输出提取的数据对应的原始行数据到Excel
```matlab
% 提取每个分段中间点对应的原始行数据(整行)
output_data = data(segment_indices, :); % segment_indices是每个分段中间点的索引
writetable(output_data, 'extracted_data.xlsx');
```
步骤7:绘制插值误差分布图,并标注性能指标
```matlab
figure;
plot(time, errors, 'b-');
xlabel('Time');
ylabel('Error');
title('Error Distribution');
grid on;
% 在图中合适位置标注性能指标
text_position_x = min(time) + 0.1*(max(time)-min(time));
text_position_y = max(errors) - 0.1*(max(errors)-min(errors));
text_str = {sprintf('MSE: %.4f', MSE), sprintf('RMSE: %.4f', RMSE), ...
sprintf('MAE: %.4f', MAE), sprintf('R^2: %.4f', R2)};
text(text_position_x, text_position_y, text_str, 'FontSize', 10, 'BackgroundColor', 'white');
```
注意:由于PAA方法中,我们取每个分段的均值作为聚合点,然后通过插值得到整个序列。在绘图时,原始数据是黑色线,预测数据是红色线(连续线)。误差分布图是原始数据与预测数据的差值。
但是,这里有一个问题:我们输出的Excel文件是每个分段中间点对应的原始行数据,而并不是聚合值。如果要求输出的是聚合值(即每个分段的均值)以及对应的分段中间时间,那么我们需要创建一个新表,包含paa_time和paa_voltage,并且输出该表。但是题目要求输出的是“那一列中每个数据对应的行的数据”,所以这里我们按照原始行输出。
如果要求输出的行数据中电压列是聚合值(均值),那么我们可以修改输出表:
```matlab
% 创建一个新表,包含原始行的所有列,但是将电压列替换为聚合值(paa_voltage)
output_data = data(segment_indices, :); % 先取出行
output_data.(2) = paa_voltage; % 假设第二列是电压,将其替换为聚合值
% 同时,第一列时间我们也可以替换为分段中间时间(paa_time),但题目要求输出原始行数据,所以可能不需要替换时间?但原始时间列是原始时间,而聚合点的时间是中间时间,所以不一致。这里需要明确。
% 根据要求,输出的是提取的电压数据(聚合值)对应的行数据,那么这一行应该包括原始的所有列,但是电压列应该是聚合值?还是原始值?题目没有明确,但要求是“那一列中每个数据对应的行的数据”,这个“数据”指的是提取的电压数据(聚合值),所以对应的行数据应该是聚合值所在的行(即我们构建的行,包括时间、聚合电压和其他列)。但其他列的值我们并没有聚合,所以还是原始值?这就不一致了。因此,我们只能输出原始行数据(即不修改电压列)或者输出聚合后的行(但其他列如何聚合?题目没有要求)。
所以,按照题目要求,我们输出提取的每个分段中间点的原始行数据(包括所有列),其中电压列是原始值。而聚合值我们单独保存在paa_voltage中,用于后续计算。这样,输出的Excel中电压列是原始值,而不是聚合值。如果用户需要聚合值,可以在Excel中替换或增加一列。
综上所述,我们按照上述步骤6输出。
完整代码:
注意:由于原始数据可能包含多列,我们在输出时使用整行。
下面将上述步骤整合成一个完整的MATLAB脚本。</think>以下是一个完整的MATLAB解决方案,使用分度聚合近似法(PAA)处理数据,并按要求生成图表和性能指标。代码包含详细注释说明每个步骤的功能。
```matlab
% 主程序:基于PAA的分度聚合近似法处理电池老化数据
clc; clear; close all;
%% 1. 读取Excel数据
filename = 'FC1_Ageing_part.xlsx';
data = readtable(filename); % 读取整个表格
time = data{:,1}; % 第一列时间数据
voltage = data{:,2}; % 第二列电压数据
n = length(voltage); % 数据点总数
%% 2. 分度聚合近似法(PAA)提取10%数据
k = ceil(n * 0.1); % 提取10%的数据点
segment_size = floor(n/k); % 计算每个段的长度
% 初始化存储变量
paa_time = zeros(k, 1);
paa_voltage = zeros(k, 1);
extracted_indices = zeros(k, 1);
% 分段处理
for i = 1:k
start_idx = (i-1)*segment_size + 1;
end_idx = min(i*segment_size, n);
segment = voltage(start_idx:end_idx);
% 计算段内平均值
paa_voltage(i) = mean(segment);
% 获取段中点对应的时间索引
mid_idx = round((start_idx + end_idx)/2);
paa_time(i) = time(mid_idx);
extracted_indices(i) = mid_idx;
end
%% 3. 重构预测数据(线性插值)
predicted_voltage = interp1(paa_time, paa_voltage, time, 'linear', 'extrap');
%% 4. 计算性能指标
% 误差计算
errors = voltage - predicted_voltage;
% MSE: 均方误差
MSE = mean(errors.^2);
% RMSE: 均方根误差
RMSE = sqrt(MSE);
% MAE: 平均绝对误差
MAE = mean(abs(errors));
% R²: 决定系数
SS_res = sum(errors.^2);
SS_tot = sum((voltage - mean(voltage)).^2);
R2 = 1 - (SS_res / SS_tot);
%% 5. 绘制原始数据与预测数据拟合图
figure('Position', [100, 100, 900, 400])
plot(time, voltage, 'k-', 'LineWidth', 1.5)
hold on
plot(time, predicted_voltage, 'r-', 'LineWidth', 1.5)
xlabel('Time')
ylabel('Voltage')
title('原始数据与PAA预测数据对比')
legend('原始数据', '预测数据', 'Location', 'best')
grid on
set(gca, 'FontSize', 12)
hold off
%% 6. 输出提取的数据到Excel(整行数据)
extracted_data = data(extracted_indices, :);
writetable(extracted_data, 'Extracted_Data_PAA.xlsx')
%% 7. 绘制插值误差分布图并显示性能指标
figure('Position', [100, 100, 900, 400])
plot(time, errors, 'b-', 'LineWidth', 1.5)
hold on
% 添加性能指标文本
metrics_str = {sprintf('MSE: %.4f', MSE),...
sprintf('RMSE: %.4f', RMSE),...
sprintf('MAE: %.4f', MAE),...
sprintf('R²: %.4f', R2)};
text_x = min(time) + 0.7*(max(time)-min(time));
text_y = max(errors) - 0.1*(max(errors)-min(errors));
text(text_x, text_y, metrics_str,...
'FontSize', 12,...
'BackgroundColor', 'white',...
'EdgeColor', 'black')
% 添加零误差参考线
yline(0, '--r', 'LineWidth', 1.2)
xlabel('Time')
ylabel('误差值')
title('电压预测误差分布')
grid on
set(gca, 'FontSize', 12)
hold off
%% 8. 控制台输出性能指标
fprintf('性能指标计算结果:\n')
fprintf('MSE = %.4f\n', MSE)
fprintf('RMSE = %.4f\n', RMSE)
fprintf('MAE = %.4f\n', MAE)
fprintf('R² = %.4f\n', R2)
```
### 代码解释:
1. **数据读取**:
- 使用`readtable`读取Excel文件,提取时间列(第一列)和电压列(第二列)
2. **分度聚合近似法(PAA)**:
- 将数据分成10个等长片段(10%数据)
- 计算每个片段的电压平均值作为代表值
- 记录每个片段中点对应的时间索引
3. **预测数据重构**:
- 使用线性插值`interp1`将提取的10%数据点重构为完整时间序列
- 保持与原始数据相同的时间分辨率
4. **性能指标计算**:
- MSE(均方误差):预测误差平方的平均值
- RMSE(均方根误差):MSE的平方根
- MAE(平均绝对误差):绝对误差的平均值
- R²(决定系数):模型解释的方差比例
5. **图表绘制**:
- **拟合图**:原始数据(黑线)与预测数据(红线)对比
- **误差分布图**:显示预测误差随时间变化,包含零参考线和性能指标
6. **数据输出**:
- 提取的10%数据点对应的整行数据写入新Excel文件
- 性能指标在图表和命令行同时显示
### 注意事项:
1. 确保Excel文件在MATLAB当前工作目录中
2. 如果时间列不是数值格式,需先转换为数值(如`datenum`)
3. 分段处理时使用`ceil`和`floor`确保处理所有数据点
4. 插值方法可根据需要改为'spline'或'pchip'等
5. 文本标注位置自动适应数据范围
### 输出结果:
1. 两张图表:拟合对比图和误差分布图
2. Excel文件:包含提取的10%数据点的整行数据
3. 命令行窗口显示四个性能指标值
阅读全文
相关推荐



















