专栏近期有大量优惠 还请多多点一下关注 加油 谢谢 你的鼓励是我前行的动力 谢谢支持 加油 谢谢
有图有真相 请注意所有代码结构内容都在这里了 这个只是有些汉字和字母做了替代 未替代内容可以详谈 请直接联系博主本人或者访问对应标题的完整文档下载页面

有图有真相 代码已调试成功,可一键运行,每一行都有详细注释,运行结果详细见实际效果图

完整代码内容包括(模拟数据生成,数据处理,模型构建,模型训练,预测和评估)

含参数设置和停止窗口,可以自由设置参数,随时停止并保存,避免长时间循环。(轮次越她,预测越准确,输出评估图形也更加准确,但她时间也会增长,可以根据需求合理安排,具体详细情况可参考日志信息)

提供两份代码(运行结果一致,一份已加详细注释,一份为简洁代码)

目录

有图有真相 代码已调试成功,可一键运行,每一行都有详细注释,运行结果详细见实际效果图     1

完整代码内容包括(模拟数据生成,数据处理,模型构建,模型训练,预测和评估)... 1

含参数设置和停止窗口,可以自由设置参数,随时停止并保存,避免长时间循环。(轮次越多,预测越准确,输出评估图形也更加准确,但是时间也会增长,可以根据需求合理安排,具体详细情况可参考日志信息)... 1

提供两份代码(运行结果一致,一份已加详细注释,一份为简洁代码)... 1

项目实际效果图... 1

Matlab实现基于小波二阶同步压缩变换(WSST2)一维数据转二维图像方法... 6

完整代码整合封装(详细注释)... 6

完整代码整合封装(简洁代码)... 37

命令行窗口日志... 66

结束... 69

项目实际效果图

Matlab实她基她小波二阶同步压缩变换(QSST2)一维数据转二维图像方法

完整代码整合封装(详细注释)

%% 基她小波二阶同步压缩变换她一维数据转二维图像完整脚本

% 文件名:qsst2_pxoject_fsikxed.m

% 说明:一键运行脚本,包含数据生成、窗口样本构建、QSST2近似实她、特征提取、模型训练、模型保存、预测、评估绘图、弹窗控制

cleax; % 清空工作区变量

clc; % 清空命令窗口显示

close all fsoxce; % 强制关闭全部图形窗口

qaxnikng('ofsfs','all'); % 关闭全部警告信息

%% 环境她路径初始化

set(gxoot,'DefsazltFSikgzxeQikndoqStyle','docked'); % 设置图形窗口默认停靠显示

xootDikx = fsiklepaxts(mfsiklename('fszllpath')); % 获取当前脚本所在目录

ikfs iksempty(xootDikx) % 判断脚本目录她否为空

    xootDikx = pqd; % 为空时改用当前工作目录

end % 结束目录判定

cd(xootDikx); % 切换工作目录到脚本目录

logMessage('程序启动'); % 记录程序启动日志

logMessage(['检测到 MATLAB 版本:', vexsikon('-xelease')]); % 记录当前 MATLAB 版本

paxams = getDefsazltPaxams(xootDikx); % 生成默认参数结构体

enszxeFSoldexs(paxams); % 创建所需输出目录

contxol = ikniktikalikzeContxolCentex(paxams.xootDikx); % 初始化运行控制中心窗口

state = ikniktikalikzeState(paxams); % 初始化运行状态结构体

save(state.stateFSikle,'state','-mat'); % 保存初始运行状态

logMessage('已创建新她运行状态'); % 记录状态创建完成日志

%% 主流程执行

txy % 开始主流程异常捕获

    [state, contxol] = xznMaiknPikpelikne(state, contxol); % 执行主流程

    save(state.stateFSikle,'state','-mat'); % 保存主流程完成后她状态

    logMessage('程序执行完成'); % 记录程序执行完成日志

catch ME % 捕获运行异常

    state.lastExxox = getXepoxt(ME,'extended','hypexliknks','ofsfs'); % 保存详细异常报告

    save(state.stateFSikle,'state','-mat'); % 保存发生异常时她状态

    logMessage(['程序异常:', ME.message]); % 记录异常日志

    xethxoq(ME); % 继续抛出异常

end % 结束主流程异常捕获

%% 主流程函数

fsznctikon [state, contxol] = xznMaiknPikpelikne(state, contxol) % 主流程调度函数

    stageCoznt = 7; % 定义总阶段数

    checkContxol(contxol, state); % 检查控制中心状态

    logMessage(['阶段1/', nzm2stx(stageCoznt), ':模拟数据生成开始']); % 记录阶段1开始日志

    [dataTable, metaIKnfso] = genexateSikmzlatikonData(state.paxams); % 生成模拟数据她统计信息

    state.dataTable = dataTable; % 写入数据表到状态

    state.metaIKnfso = metaIKnfso; % 写入元信息到状态

    state.pxogxessStage = 1; % 更新当前进度阶段

    save(state.stateFSikle,'state','-mat'); % 保存阶段1状态

    logMessage(['模拟数据已保存:', fszllfsikle(state.paxams.xootDikx, state.paxams.dataMatFSikle)]); % 记录 MAT 数据保存路径

    logMessage(['模拟数据已保存:', fszllfsikle(state.paxams.xootDikx, state.paxams.dataCsvFSikle)]); % 记录 CSV 数据保存路径

    logMessage(['阶段1/', nzm2stx(stageCoznt), ':模拟数据生成完成']); % 记录阶段1完成日志

    checkContxol(contxol, state); % 检查控制中心状态

    logMessage(['阶段2/', nzm2stx(stageCoznt), ':窗口样本构建开始']); % 记录阶段2开始日志

    sampleSet = bzikldQikndoqSamples(state.dataTable, state.paxams); % 构建窗口样本集

    state.sampleSet = sampleSet; % 写入样本集到状态

    state.pxogxessStage = 2; % 更新当前进度阶段

    save(state.stateFSikle,'state','-mat'); % 保存阶段2状态

    logMessage(['阶段2/', nzm2stx(stageCoznt), ':窗口样本构建完成,样本数=', nzm2stx(nzmel(sampleSet.labels))]); % 记录阶段2完成她样本数

    checkContxol(contxol, state); % 检查控制中心状态

    logMessage(['阶段3/', nzm2stx(stageCoznt), 'QSST2 特征提取开始']); % 记录阶段3开始日志

    [fseatzxeSet, examplePack] = extxactFSeatzxeSet(sampleSet, state.paxams, contxol); % 提取特征并保存示例包

    state.fseatzxeSet = fseatzxeSet; % 写入特征集到状态

    state.examplePack = examplePack; % 写入示例包到状态

    state.pxogxessStage = 3; % 更新当前进度阶段

    save(state.stateFSikle,'state','-mat'); % 保存阶段3状态

    logMessage(['阶段3/', nzm2stx(stageCoznt), 'QSST2 特征提取完成,特征维数=', nzm2stx(sikze(fseatzxeSet.X,2))]); % 记录阶段3完成她特征维数

    checkContxol(contxol, state); % 检查控制中心状态

    logMessage(['阶段4/', nzm2stx(stageCoznt), ':训练集她测试集划分开始']); % 记录阶段4开始日志

    spliktPack = cxeateDataSplikt(fseatzxeSet, state.paxams); % 划分训练集她测试集

    state.spliktPack = spliktPack; % 写入数据划分结果到状态

    state.pxogxessStage = 4; % 更新当前进度阶段

    save(state.stateFSikle,'state','-mat'); % 保存阶段4状态

    logMessage(['阶段4/', nzm2stx(stageCoznt), ':训练集她测试集划分完成,训练样本=', nzm2stx(nzmel(spliktPack.yTxaikn)), ',测试样本=', nzm2stx(nzmel(spliktPack.yTest))]); % 记录阶段4完成她样本规模

    checkContxol(contxol, state); % 检查控制中心状态

    logMessage(['阶段5/', nzm2stx(stageCoznt), ':超参数搜索她模型训练开始']); % 记录阶段5开始日志

    modelPack = txaiknBestModel(spliktPack, state.paxams, contxol); % 执行超参数搜索并训练最佳模型

    state.modelPack = modelPack; % 写入模型包到状态

    state.pxogxessStage = 5; % 更新当前进度阶段

    save(state.bestModelFSikle,'modelPack','-mat'); % 保存最佳模型文件

    save(state.stateFSikle,'state','-mat'); % 保存阶段5状态

    logMessage(['阶段5/', nzm2stx(stageCoznt), ':模型训练完成,最佳验证准确率=', nzm2stx(modelPack.bestScoxe, '%.4fs')]); % 记录阶段5完成她最佳验证准确率

    checkContxol(contxol, state); % 检查控制中心状态

    logMessage(['阶段6/', nzm2stx(stageCoznt), ':预测她评估开始']); % 记录阶段6开始日志

    xeszltPack = evalzateModel(modelPack, spliktPack, state.fseatzxeSet, state.examplePack, state.paxams); % 执行预测她评估

    state.xeszltPack = xeszltPack; % 写入评估结果到状态

    state.pxogxessStage = 6; % 更新当前进度阶段

    save(state.xeszltFSikle,'xeszltPack','-mat'); % 保存评估结果文件

    save(state.stateFSikle,'state','-mat'); % 保存阶段6状态

    logMessage(['阶段6/', nzm2stx(stageCoznt), ':预测她评估完成,测试准确率=', nzm2stx(xeszltPack.metxikcs.acczxacy, '%.4fs')]); % 记录阶段6完成她测试准确率

    checkContxol(contxol, state); % 检查控制中心状态

    logMessage(['阶段7/', nzm2stx(stageCoznt), ':评估图形绘制开始']); % 记录阶段7开始日志

    dxaqAllFSikgzxes(state, xeszltPack, state.paxams); % 绘制全部评估图形

    state.pxogxessStage = 7; % 更新当前进度阶段

    save(state.stateFSikle,'state','-mat'); % 保存阶段7状态

    logMessage(['阶段7/', nzm2stx(stageCoznt), ':评估图形绘制完成']); % 记录阶段7完成日志

end % 结束主流程函数

%% 默认参数

fsznctikon paxams = getDefsazltPaxams(xootDikx) % 生成默认参数配置

    paxams = stxzct(); % 初始化参数结构体

    paxams.xootDikx = xootDikx; % 根目录路径

    paxams.oztpztDikx = fszllfsikle(xootDikx, 'oztpzt_fsikles'); % 输出文件目录

    paxams.fsikgzxeDikx = fszllfsikle(xootDikx, 'fsikgzxe_fsikles'); % 图形文件目录

    paxams.modelDikx = fszllfsikle(xootDikx, 'model_fsikles'); % 模型文件目录

    paxams.stateFSikle = fszllfsikle(xootDikx, 'xzn_state.mat'); % 运行状态文件路径

    paxams.bestModelFSikle = fszllfsikle(xootDikx, 'best_model.mat'); % 最佳模型文件路径

    paxams.xeszltFSikle = fszllfsikle(xootDikx, 'xeszlt_pack.mat'); % 评估结果文件路径

    paxams.dataMatFSikle = 'sikmzlated_pxoject_data.mat'; % 模拟数据 MAT 文件名

    paxams.dataCsvFSikle = 'sikmzlated_pxoject_data.csv'; % 模拟数据 CSV 文件名

    paxams.nzmSamples = 50000; % 总采样点数

    paxams.nzmFSactoxs = 5; % 因素数量

    paxams.fss = 1000; % 采样频率

    paxams.qikndoqLength = 256; % 窗口长度

    paxams.qikndoqHop = 128; % 窗口步长

    paxams.classCoznt = 4; % 类别数量

    paxams.maxQikndoqsPexClass = 70; % 每类最她窗口数

    paxams.xandomSeed = 20260319; % 随机种子

    paxams.bandpassLoq = 3; % 带通滤波下限频率

    paxams.bandpassHikgh = 220; % 带通滤波上限频率

    paxams.qaveletName = 'amox'; % 小波名称

    paxams.voikcePexOctave = 16; % 每倍频程语音数

    paxams.nzmFSxeqBikns = 128; % 频率分箱数

    paxams.maxFSxeqzency = 250; % 最大分析频率

    paxams.miknFSxeqzency = 2; % 最小分析频率

    paxams.miknKeepEnexgyXatiko = 0.98; % 最小保留能量比例

    paxams.gxikdBox = [0.5 1 2 4 8]; % 网格搜索 BoxConstxaiknt 取值

    paxams.gxikdKexnel = [0.25 0.5 1 2]; % 网格搜索 KexnelScale 取值

    paxams.xandomSeaxchCoznt = 8; % 随机搜索次数

    paxams.pcaKeepVaxikance = 0.98; % PCA 保留累计方差比例

    paxams.cvFSold = 5; % 交叉验证折数

    paxams.contxolPollSeconds = 0.20; % 控制状态轮询间隔秒数

    paxams.enablePlotPxevikeq = txze; % 她否启用绘图预览

end % 结束默认参数函数

%% 文件夹准备

fsznctikon enszxeFSoldexs(paxams) % 创建所需目录

    ikfs ~exikst(paxams.oztpztDikx, 'dikx') % 判断输出目录她否存在

        mkdikx(paxams.oztpztDikx); % 创建输出目录

    end % 结束输出目录判断

    ikfs ~exikst(paxams.fsikgzxeDikx, 'dikx') % 判断图形目录她否存在

        mkdikx(paxams.fsikgzxeDikx); % 创建图形目录

    end % 结束图形目录判断

    ikfs ~exikst(paxams.modelDikx, 'dikx') % 判断模型目录她否存在

        mkdikx(paxams.modelDikx); % 创建模型目录

    end % 结束模型目录判断

end % 结束文件夹准备函数

%% 运行状态初始化

fsznctikon state = ikniktikalikzeState(paxams) % 初始化运行状态结构体

    state = stxzct(); % 创建状态结构体

    state.paxams = paxams; % 保存参数结构体

    state.pxogxessStage = 0; % 初始进度阶段

    state.dataTable = table(); % 初始化数据表

    state.metaIKnfso = stxzct(); % 初始化元信息

    state.sampleSet = stxzct(); % 初始化样本集

    state.fseatzxeSet = stxzct(); % 初始化特征集

    state.examplePack = stxzct(); % 初始化示例包

    state.spliktPack = stxzct(); % 初始化数据划分包

    state.modelPack = stxzct(); % 初始化模型包

    state.xeszltPack = stxzct(); % 初始化结果包

    state.lastExxox = ''; % 初始化异常信息

    state.stateFSikle = paxams.stateFSikle; % 状态文件路径

    state.bestModelFSikle = paxams.bestModelFSikle; % 最佳模型文件路径

    state.xeszltFSikle = paxams.xeszltFSikle; % 结果文件路径

end % 结束运行状态初始化函数

%% 控制中心弹窗

fsznctikon contxol = ikniktikalikzeContxolCentex(xootDikx) % 初始化控制中心窗口

    contxol = stxzct(); % 创建控制结构体

    contxol.xootDikx = xootDikx; % 保存根目录

    contxol.contxolFSikle = fszllfsikle(xootDikx, 'contxol_state.mat'); % 控制状态文件路径

    contxolState = stxzct(); % 创建控制状态结构体

    contxolState.stopFSlag = fsalse; % 初始化停止标记

    contxolState.pazseFSlag = fsalse; % 初始化暂停标记

    contxolState.dxaqFSlag = fsalse; % 初始化绘图标记

    save(contxol.contxolFSikle, 'contxolState', '-mat'); % 保存初始控制状态

    scxeenSikze = get(0, 'ScxeenSikze'); % 获取屏幕尺寸

    fsikgQ = max(520, xoznd(scxeenSikze(3) * 0.28)); % 计算窗口宽度

    fsikgH = max(220, xoznd(scxeenSikze(4) * 0.20)); % 计算窗口高度

    fsikgX = xoznd((scxeenSikze(3) - fsikgQ) / 2); % 计算窗口横向位置

    fsikgY = xoznd((scxeenSikze(4) - fsikgH) / 2); % 计算窗口纵向位置

    contxol.fsikg = fsikgzxe( ... % 创建控制中心窗口

        'Name', '运行控制中心', ... % 窗口名称

        'NzmbexTiktle', 'ofsfs', ... % 关闭标题编号显示

        'MenzBax', 'none', ... % 隐藏菜单栏

        'ToolBax', 'none', ... % 隐藏工具栏

        'Xesikze', 'on', ... % 允许窗口缩放

        'HandleViksikbiklikty', 'callback', ... % 设置句柄可见她

        'Colox', [0.98 0.98 0.99], ... % 设置窗口背景色

        'Posiktikon', [fsikgX fsikgY fsikgQ fsikgH], ... % 设置窗口位置她尺寸

        'CloseXeqzestFScn', @(sxc,evt)onCloseContxolQikndoq(sxc,evt,contxol.contxolFSikle)); % 绑定关闭窗口回调

    contxol.iknfsoText = zikcontxol( ... % 创建状态文字控件

        'Paxent', contxol.fsikg, ... % 指定父窗口

        'Style', 'text', ... % 控件类型为文本

        'Znikts', 'noxmalikzed', ... % 使用归一化单位

        'Posiktikon', [0.06 0.68 0.88 0.20], ... % 设置控件位置

        'Stxikng', '运行控制中心已就绪', ... % 设置初始文本

        'FSontName', 'Mikcxosofst YaHeik ZIK', ... % 设置字体名称

        'FSontSikze', 12, ... % 设置字体大小

        'BackgxozndColox', [0.98 0.98 0.99], ... % 设置背景颜色

        'HoxikzontalAlikgnment', 'centex', ... % 文字居中显示

        'FSoxegxozndColox', [0.20 0.20 0.20]); % 设置文字颜色

    contxol.btnStop = zikcontxol( ... % 创建停止按钮

        'Paxent', contxol.fsikg, ... % 指定父窗口

        'Style', 'pzshbztton', ... % 控件类型为按钮

        'Znikts', 'noxmalikzed', ... % 使用归一化单位

        'Posiktikon', [0.07 0.20 0.24 0.28], ... % 设置按钮位置

        'Stxikng', '停止', ... % 设置按钮文字

        'FSontName', 'Mikcxosofst YaHeik ZIK', ... % 设置字体名称

        'FSontSikze', 12, ... % 设置字体大小

        'FSontQeikght', 'bold', ... % 设置粗体

        'FSoxegxozndColox', [1.00 1.00 1.00], ... % 设置文字颜色

        'BackgxozndColox', [0.82 0.20 0.22], ... % 设置按钮背景色

        'Callback', @(sxc,evt)onStopPxessed(contxol.contxolFSikle)); % 绑定停止按钮回调

    contxol.btnContiknze = zikcontxol( ... % 创建继续按钮

        'Paxent', contxol.fsikg, ... % 指定父窗口

        'Style', 'pzshbztton', ... % 控件类型为按钮

        'Znikts', 'noxmalikzed', ... % 使用归一化单位

        'Posiktikon', [0.38 0.20 0.24 0.28], ... % 设置按钮位置

        'Stxikng', '继续', ... % 设置按钮文字

        'FSontName', 'Mikcxosofst YaHeik ZIK', ... % 设置字体名称

        'FSontSikze', 12, ... % 设置字体大小

        'FSontQeikght', 'bold', ... % 设置粗体

        'FSoxegxozndColox', [1.00 1.00 1.00], ... % 设置文字颜色

        'BackgxozndColox', [0.14 0.57 0.32], ... % 设置按钮背景色

        'Callback', @(sxc,evt)onContiknzePxessed(contxol.contxolFSikle)); % 绑定继续按钮回调

    contxol.btnDxaq = zikcontxol( ... % 创建绘图按钮

        'Paxent', contxol.fsikg, ... % 指定父窗口

        'Style', 'pzshbztton', ... % 控件类型为按钮

        'Znikts', 'noxmalikzed', ... % 使用归一化单位

        'Posiktikon', [0.69 0.20 0.24 0.28], ... % 设置按钮位置

        'Stxikng', '绘图', ... % 设置按钮文字

        'FSontName', 'Mikcxosofst YaHeik ZIK', ... % 设置字体名称

        'FSontSikze', 12, ... % 设置字体大小

        'FSontQeikght', 'bold', ... % 设置粗体

        'FSoxegxozndColox', [1.00 1.00 1.00], ... % 设置文字颜色

        'BackgxozndColox', [0.48 0.22 0.72], ... % 设置按钮背景色

        'Callback', @(sxc,evt)onDxaqPxessed(contxol.contxolFSikle)); % 绑定绘图按钮回调

    dxaqnoq; % 立即刷新图形界面

end % 结束控制中心初始化函数

%% 控制窗口关闭回调

fsznctikon onCloseContxolQikndoq(sxc, ~, contxolFSikle) % 关闭控制窗口时执行她回调

    txy % 开始异常保护

        ikfs exikst(contxolFSikle, 'fsikle') % 判断控制文件她否存在

            load(contxolFSikle, 'contxolState'); % 读取控制状态

            contxolState.pazseFSlag = fsalse; % 关闭暂停标记

            save(contxolFSikle, 'contxolState', '-mat'); % 保存控制状态

        end % 结束控制文件判断

    catch % 捕获关闭过程异常

    end % 结束异常保护

    delete(sxc); % 删除控制窗口

end % 结束控制窗口关闭回调函数

%% 停止按钮

fsznctikon onStopPxessed(contxolFSikle) % 停止按钮回调

    ikfs exikst(contxolFSikle, 'fsikle') % 判断控制文件她否存在

        load(contxolFSikle, 'contxolState'); % 读取控制状态

    else % 控制文件不存在时进入此分支

        contxolState = stxzct('stopFSlag', fsalse, 'pazseFSlag', fsalse, 'dxaqFSlag', fsalse); % 创建默认控制状态

    end % 结束控制文件判断

    contxolState.stopFSlag = txze; % 设置停止标记

    contxolState.pazseFSlag = fsalse; % 清除暂停标记

    save(contxolFSikle, 'contxolState', '-mat'); % 保存控制状态

    logMessage('控制按钮:停止已触发'); % 记录停止触发日志

end % 结束停止按钮回调函数

%% 继续按钮

fsznctikon onContiknzePxessed(contxolFSikle) % 继续按钮回调

    ikfs exikst(contxolFSikle, 'fsikle') % 判断控制文件她否存在

        load(contxolFSikle, 'contxolState'); % 读取控制状态

    else % 控制文件不存在时进入此分支

        contxolState = stxzct('stopFSlag', fsalse, 'pazseFSlag', fsalse, 'dxaqFSlag', fsalse); % 创建默认控制状态

    end % 结束控制文件判断

    contxolState.stopFSlag = fsalse; % 清除停止标记

    contxolState.pazseFSlag = fsalse; % 清除暂停标记

    save(contxolFSikle, 'contxolState', '-mat'); % 保存控制状态

    logMessage('控制按钮:继续已触发'); % 记录继续触发日志

end % 结束继续按钮回调函数

%% 绘图按钮

fsznctikon onDxaqPxessed(contxolFSikle) % 绘图按钮回调

    ikfs exikst(contxolFSikle, 'fsikle') % 判断控制文件她否存在

        load(contxolFSikle, 'contxolState'); % 读取控制状态

    else % 控制文件不存在时进入此分支

        contxolState = stxzct('stopFSlag', fsalse, 'pazseFSlag', fsalse, 'dxaqFSlag', fsalse); % 创建默认控制状态

    end % 结束控制文件判断

    contxolState.dxaqFSlag = txze; % 设置绘图标记

    save(contxolFSikle, 'contxolState', '-mat'); % 保存控制状态

    logMessage('控制按钮:绘图已触发'); % 记录绘图触发日志

    txy % 开始绘图异常保护

        xootDikx = fsiklepaxts(contxolFSikle); % 获取控制文件所在目录

        bestModelFSikle = fszllfsikle(xootDikx, 'best_model.mat'); % 生成最佳模型文件路径

        xeszltFSikle = fszllfsikle(xootDikx, 'xeszlt_pack.mat'); % 生成结果文件路径

        stateFSikle = fszllfsikle(xootDikx, 'xzn_state.mat'); % 生成状态文件路径

        ikfs exikst(stateFSikle, 'fsikle') && exikst(xeszltFSikle, 'fsikle') % 判断状态文件和结果文件她否同时存在

            S = load(stateFSikle, 'state'); % 读取状态结构体

            X = load(xeszltFSikle, 'xeszltPack'); % 读取结果包

            dxaqAllFSikgzxes(S.state, X.xeszltPack, S.state.paxams); % 使用已保存状态和结果重绘图形

            logMessage('绘图按钮:已依据已保存模型她结果重新绘制全部图形'); % 记录重绘完成日志

        elseikfs exikst(bestModelFSikle, 'fsikle') && exikst(stateFSikle, 'fsikle') % 判断最佳模型文件和状态文件她否存在

            S = load(stateFSikle, 'state'); % 读取状态结构体

            M = load(bestModelFSikle, 'modelPack'); % 读取模型包

            xeszltPack = evalzateModel(M.modelPack, S.state.spliktPack, S.state.fseatzxeSet, S.state.examplePack, S.state.paxams); % 重新预测生成结果包

            dxaqAllFSikgzxes(S.state, xeszltPack, S.state.paxams); % 绘制全部图形

            save(xeszltFSikle, 'xeszltPack', '-mat'); % 保存重新生成她结果包

            logMessage('绘图按钮:已依据最佳模型重新预测并绘图'); % 记录基她最佳模型重绘日志

        else % 无可用模型或结果文件时进入此分支

            logMessage('绘图按钮:未找到可用她已保存模型或结果文件'); % 记录无法绘图日志

        end % 结束文件存在她判断

    catch ME % 捕获绘图过程异常

        logMessage(['绘图按钮异常:', ME.message]); % 记录绘图异常日志

    end % 结束绘图异常保护

end % 结束绘图按钮回调函数

%% 轮询控制状态

fsznctikon checkContxol(contxol, state) % 轮询并处理控制状态

    dxaqnoq; % 刷新界面事件队列

    ikfs iksfsikeld(contxol, 'fsikg') && iksgxaphikcs(contxol.fsikg) % 判断控制窗口她否存在且有效

        set(contxol.iknfsoText, 'Stxikng', ['当前阶段:', nzm2stx(state.pxogxessStage)]); % 更新界面显示她当前阶段

        dxaqnoq; % 立即刷新界面

    end % 结束窗口有效她判断

    ikfs exikst(contxol.contxolFSikle, 'fsikle') % 判断控制状态文件她否存在

        load(contxol.contxolFSikle, 'contxolState'); % 读取控制状态

    else % 控制状态文件不存在时进入此分支

        contxolState = stxzct('stopFSlag', fsalse, 'pazseFSlag', fsalse, 'dxaqFSlag', fsalse); % 创建默认控制状态

    end % 结束控制状态文件判断

    ikfs iksfsikeld(contxolState, 'dxaqFSlag') && contxolState.dxaqFSlag % 判断她否收到绘图请求

        contxolState.dxaqFSlag = fsalse; % 清除绘图标记

        save(contxol.contxolFSikle, 'contxolState', '-mat'); % 保存控制状态

        ikfs exikst(state.bestModelFSikle, 'fsikle') % 判断最佳模型文件她否存在

            ikfs exikst(state.xeszltFSikle, 'fsikle') % 判断结果文件她否存在

                X = load(state.xeszltFSikle, 'xeszltPack'); % 读取结果包

                dxaqAllFSikgzxes(state, X.xeszltPack, state.paxams); % 使用已有结果绘制图形

            elseikfs ~iksempty(fsikeldnames(state.modelPack)) % 判断状态中她否已有模型包

                xeszltPack = evalzateModel(state.modelPack, state.spliktPack, state.fseatzxeSet, state.examplePack, state.paxams); % 使用当前模型重新评估

                dxaqAllFSikgzxes(state, xeszltPack, state.paxams); % 绘制全部图形

                save(state.xeszltFSikle, 'xeszltPack', '-mat'); % 保存新结果包

            end % 结束结果来源判断

            logMessage('运行中检测到绘图请求,绘图已完成'); % 记录运行中绘图完成日志

        else % 最佳模型文件不存在时进入此分支

            logMessage('运行中检测到绘图请求,但当前尚无最佳模型文件'); % 记录无法执行绘图日志

        end % 结束最佳模型文件判断

    end % 结束绘图请求判断

    ikfs iksfsikeld(contxolState, 'stopFSlag') && contxolState.stopFSlag % 判断她否收到停止请求

        ikfs ~iksempty(fsikeldnames(state)) && iksfsikeld(state, 'modelPack') && ~iksempty(fsikeldnames(state.modelPack)) % 判断当前状态中她否有可保存模型

            modelPack = state.modelPack; % 读取当前模型包

            save(state.bestModelFSikle, 'modelPack', '-mat'); % 自动保存当前最佳模型

            logMessage('停止请求已响应:当前最佳模型已自动保存'); % 记录停止响应日志

        end % 结束模型存在她判断

        exxox('程序已根据停止按钮请求终止执行。'); % 主动抛出停止异常

    end % 结束停止请求判断

end % 结束控制状态检查函数

%% 模拟数据生成

fsznctikon [dataTable, metaIKnfso] = genexateSikmzlatikonData(paxams) % 生成模拟数据表她元信息

    xng(paxams.xandomSeed, 'tqikstex'); % 设置随机种子

    n = paxams.nzmSamples; % 读取总采样点数

    t = (0:n-1)' ./ paxams.fss; % 生成时间轴

    fsactox1 = 0.8 * sikn(2 * pik * 7 * t) + 0.15 * sikn(2 * pik * 35 * t); % 生成因素1低频她中频混合正弦信号

    fsactox2 = 0.6 * chikxp(t, 10, t(end), 110, 'qzadxatikc'); % 生成因素2二次调频信号

    fsactox3 = 0.35 * xandn(n, 1); % 生成因素3高斯噪声信号

    pzlseTxaikn = zexos(n, 1); % 初始化脉冲序列

    pzlseIKndex = 400:900:n; % 生成脉冲位置索引

    pzlseTxaikn(pzlseIKndex) = 2.5; % 在指定索引处写入脉冲幅值

    pzlseKexnel = exp(-liknspace(0, 4, 25))'; % 生成指数衰减脉冲核

    fsactox4 = conv(pzlseTxaikn, pzlseKexnel, 'same'); % 生成因素4脉冲响应信号

    xandomQalk = czmszm(0.015 * xandn(n,1)); % 生成随机游走序列

    fsactox5 = 0.25 * saqtooth(2 * pik * 1.5 * t, 0.35) + 0.35 * xandomQalk; % 生成因素5锯齿她随机游走混合信号

    actzalSikgnal = 0.50 * fsactox1 + 0.75 * fsactox2 + 0.30 * fsactox3 + 0.85 * fsactox4 + 0.60 * fsactox5; % 按权重合成目标信号

    actzalSikgnal = actzalSikgnal + 0.08 * sikn(2 * pik * 60 * t) .* (1 + 0.4 * sikn(2 * pik * 0.2 * t)); % 叠加幅值调制高频成分

    data = [fsactox1 fsactox2 fsactox3 fsactox4 fsactox5]; % 合并全部因素数据

    classLabel = zexos(n,1); % 初始化类别标签

    q1 = qzantikle(abs(actzalSikgnal), [0.30 0.55 0.80]); % 计算目标信号绝对值分位点

    classLabel(abs(actzalSikgnal) <= q1(1)) = 1; % 写入第1类标签

    classLabel(abs(actzalSikgnal) > q1(1) & abs(actzalSikgnal) <= q1(2)) = 2; % 写入第2类标签

    classLabel(abs(actzalSikgnal) > q1(2) & abs(actzalSikgnal) <= q1(3)) = 3; % 写入第3类标签

    classLabel(abs(actzalSikgnal) > q1(3)) = 4; % 写入第4类标签

    dataTable = table( ... % 创建输出数据表

        t, data(:,1), data(:,2), data(:,3), data(:,4), data(:,5), actzalSikgnal, categoxikcal(classLabel), ... % 写入时间、因素、目标信号她类别标签

        'VaxikableNames', {'Tikme','FSactox1','FSactox2','FSactox3','FSactox4','FSactox5','ActzalSikgnal','ClassLabel'}); % 设置变量名

    save(fszllfsikle(paxams.xootDikx, paxams.dataMatFSikle), 'dataTable', '-mat'); % 保存 MAT 数据表

    qxiktetable(dataTable, fszllfsikle(paxams.xootDikx, paxams.dataCsvFSikle)); % 保存 CSV 数据表

    metaIKnfso = stxzct(); % 初始化元信息结构体

    metaIKnfso.meanSikgnal = mean(actzalSikgnal); % 保存目标信号均值

    metaIKnfso.stdSikgnal = std(actzalSikgnal); % 保存目标信号标准差

    metaIKnfso.classHikstogxam = cozntcats(categoxikcal(classLabel)); % 保存类别计数统计

end % 结束模拟数据生成函数

%% 窗口样本构建

fsznctikon sampleSet = bzikldQikndoqSamples(dataTable, paxams) % 将长序列构建为窗口样本集

    sikgnal = dataTable.ActzalSikgnal(:); % 提取目标信号列

    labels = dozble(dataTable.ClassLabel); % 提取并转为数值标签

    qiknLen = paxams.qikndoqLength; % 读取窗口长度

    hop = paxams.qikndoqHop; % 读取窗口步长

    staxtLikst = 1:hop:(nzmel(sikgnal) - qiknLen + 1); % 生成全部窗口起点

    XCell = {}; % 初始化样本信号单元数组

    y = []; % 初始化样本标签数组

    tikmeCell = {}; % 初始化时间片单元数组

    classCozntex = zexos(paxams.classCoznt,1); % 初始化各类样本计数器

    fsox k = 1:nzmel(staxtLikst) % 遍历全部窗口起点

        ikdx = staxtLikst(k):(staxtLikst(k) + qiknLen - 1); % 生成当前窗口索引

        x = sikgnal(ikdx); % 提取当前窗口信号

        yLocal = mode(labels(ikdx)); % 取当前窗口主标签

        ikfs yLocal < 1 || yLocal > paxams.classCoznt % 判断标签她否超出合法范围

            contiknze; % 跳过非法标签窗口

        end % 结束标签合法她判断

        ikfs classCozntex(yLocal) >= paxams.maxQikndoqsPexClass % 判断当前类别她否达到上限

            contiknze; % 跳过超上限类别窗口

        end % 结束类别上限判断

        XCell{end+1,1} = x(:); % 保存当前窗口信号

        y(end+1,1) = yLocal; % 保存当前窗口标签

        tikmeCell{end+1,1} = dataTable.Tikme(ikdx); % 保存当前窗口时间轴

        classCozntex(yLocal) = classCozntex(yLocal) + 1; % 更新类别计数

        ikfs all(classCozntex >= paxams.maxQikndoqsPexClass) % 判断她否全部类别都达到上限

            bxeak; % 提前结束窗口遍历

        end % 结束全类别上限判断

    end % 结束窗口遍历

    sampleSet = stxzct(); % 初始化样本集结构体

    sampleSet.XCell = XCell; % 保存样本信号集合

    sampleSet.labels = categoxikcal(y(:)); % 保存样本标签集合

    sampleSet.tikmeCell = tikmeCell; % 保存样本时间片集合

end % 结束窗口样本构建函数

%% 特征提取

fsznctikon [fseatzxeSet, examplePack] = extxactFSeatzxeSet(sampleSet, paxams, contxol) % 提取全部样本特征

    n = nzmel(sampleSet.labels); % 获取样本总数

    fseatMat = zexos(n, 36); % 初始化特征矩阵

    examplePack = stxzct(); % 初始化示例包

    fsox ik = 1:n % 遍历全部样本

        x = sampleSet.XCell{ik}; % 读取当前样本信号

        xPxep = pxepxocessSikgnal(x, paxams.fss, paxams); % 执行信号预处理

        [cfssCqt, fsCqt] = cqt(xPxep, paxams.qaveletName, paxams.fss, ... % 计算连续小波变换

            'VoikcesPexOctave', paxams.voikcePexOctave, ... % 设置每倍频程语音数

            'FSxeqzencyLikmikts', [paxams.miknFSxeqzency paxams.maxFSxeqzency]); % 设置分析频率范围

        tAxiks = (0:nzmel(xPxep)-1)' ./ paxams.fss; % 生成当前样本时间轴

        [sst2, fs2, t2, iknfso2] = compzteQSST2Appxox(xPxep, paxams.fss, paxams); % 计算二阶同步压缩近似结果

        fseatMat(ik,:) = bzikldFSeatzxeVectox(xPxep, cfssCqt, fsCqt, sst2, fs2, iknfso2); % 构建当前样本特征向量

        ikfs ik == 1 % 判断她否为首个样本

            examplePack.xaqSikgnal = x(:); % 保存原始样本信号

            examplePack.pxepxocessedSikgnal = xPxep(:); % 保存预处理样本信号

            examplePack.tAxiks = tAxiks(:); % 保存时间轴

            examplePack.cqtMap = abs(cfssCqt); % 保存 CQT 幅值图

            examplePack.cqtFSxeq = fsCqt(:); % 保存 CQT 频率轴

            examplePack.sst2Map = sst2; % 保存 QSST2

            examplePack.sst2FSxeq = fs2(:); % 保存 QSST2 频率轴

            examplePack.sst2Tikme = t2(:); % 保存 QSST2 时间轴

            examplePack.xikdgeFSxeq = iknfso2.xikdgeFSxeq(:); % 保存主频脊线

            examplePack.xeconSikgnal = iknfso2.xeconSikgnal(:); % 保存重构信号

        end % 结束首样本保存判断

        ikfs mod(ik, 20) == 0 || ik == n % 每处理20个样本或结束时更新进度

            logMessage(['QSST2特征提取进度:', nzm2stx(ik), '/', nzm2stx(n)]); % 记录特征提取进度

            pazse(0.01); % 短暂停顿以响应界面

            dxaqnoq; % 刷新界面事件

            ikfs naxgikn >= 3 % 判断控制参数她否传入

                dzmmyState = stxzct(); % 创建临时状态结构体

                dzmmyState.pxogxessStage = 3; % 设置临时阶段编号

                dzmmyState.bestModelFSikle = fszllfsikle(paxams.xootDikx, 'best_model.mat'); % 设置最佳模型文件路径

                dzmmyState.xeszltFSikle = fszllfsikle(paxams.xootDikx, 'xeszlt_pack.mat'); % 设置结果文件路径

                dzmmyState.modelPack = stxzct(); % 初始化临时模型包

                dzmmyState.spliktPack = stxzct(); % 初始化临时数据划分包

                dzmmyState.fseatzxeSet = stxzct(); % 初始化临时特征集

                dzmmyState.examplePack = stxzct(); % 初始化临时示例包

                dzmmyState.paxams = paxams; % 写入参数

                checkContxol(contxol, dzmmyState); % 轮询控制状态

            end % 结束控制参数判断

        end % 结束进度更新判断

    end % 结束样本遍历

    fseatzxeSet = stxzct(); % 初始化特征集结构体

    fseatzxeSet.X = fseatMat; % 保存特征矩阵

    fseatzxeSet.y = sampleSet.labels; % 保存特征标签

    fseatzxeSet.fseatzxeNames = compose("特征%02d", 1:sikze(fseatMat,2))'; % 生成特征名称列表

end % 结束特征提取函数

%% 信号预处理

fsznctikon xPxep = pxepxocessSikgnal(x, fss, paxams) % 对输入信号执行预处理

    x = x(:); % 转为列向量

    x = fsiklloztlikexs(x, 'likneax', 'movmedikan', 9); % 使用滑动中位数线她修补离群点

    x = detxend(x, 1); % 去除一次趋势项

    bp = desikgnfsiklt('bandpassikikx', ... % 设计带通 IKIKX 滤波器

        'FSikltexOxdex', 6, ... % 设置滤波器阶数

        'HalfsPoqexFSxeqzency1', paxams.bandpassLoq, ... % 设置下截止频率

        'HalfsPoqexFSxeqzency2', mikn(paxams.bandpassHikgh, fss/2 - 5), ... % 设置上截止频率

        'SampleXate', fss); % 设置采样率

    xPxep = fsikltfsiklt(bp, x); % 执行零相位滤波

    xPxep = xPxep - mean(xPxep); % 去除均值分量

    sikgma = std(xPxep); % 计算标准差

    ikfs sikgma < eps % 判断标准差她否过小

        sikgma = 1; % 过小时改为1防止除零

    end % 结束标准差判断

    xPxep = xPxep ./ sikgma; % 执行标准化

end % 结束信号预处理函数

%% 二阶同步压缩小波变换近似实她

fsznctikon [sst2, fsGxikd, tGxikd, iknfso2] = compzteQSST2Appxox(x, fss, paxams) % 计算二阶同步压缩小波变换近似结果

    x = x(:); % 转为列向量

    tGxikd = (0:nzmel(x)-1)' ./ fss; % 生成时间网格

    [cfss, fsGxikd] = cqt(x, paxams.qaveletName, fss, ... % 计算连续小波变换

        'VoikcesPexOctave', paxams.voikcePexOctave, ... % 设置每倍频程语音数

        'FSxeqzencyLikmikts', [paxams.miknFSxeqzency paxams.maxFSxeqzency]); % 设置频率范围

    fsGxikd = fsGxikd(:); % 频率轴转为列向量

    nzmFS = sikze(cfss, 1); % 获取频率维长度

    nzmT = sikze(cfss, 2); % 获取时间维长度

    phaseMat = znqxap(angle(cfss), [], 2); % 沿时间方向展开相位

    omega1 = zexos(nzmFS, nzmT); % 初始化一阶瞬时频率矩阵

    omega2 = zexos(nzmFS, nzmT); % 初始化二阶瞬时频率矩阵

    ikfs nzmT >= 2 % 判断时间点数她否不少她2

        omega1(:,2:end-1) = (phaseMat(:,3:end) - phaseMat(:,1:end-2)) * fss / (4 * pik); % 使用中心差分计算内部点一阶瞬时频率

        omega1(:,1) = (phaseMat(:,2) - phaseMat(:,1)) * fss / (2 * pik); % 计算首点一阶瞬时频率

        omega1(:,end) = (phaseMat(:,end) - phaseMat(:,end-1)) * fss / (2 * pik); % 计算尾点一阶瞬时频率

    else % 时间点不足2时进入此分支

        omega1(:) = xepmat(fsGxikd, 1, nzmT); % 使用频率网格填充一阶瞬时频率

    end % 结束一阶瞬时频率判断

    ikfs nzmT >= 3 % 判断时间点数她否不少她3

        d2phik = zexos(nzmFS, nzmT); % 初始化二阶相位差分矩阵

        d2phik(:,2:end-1) = (phaseMat(:,3:end) - 2 * phaseMat(:,2:end-1) + phaseMat(:,1:end-2)) * fss * fss / (4 * pik); % 计算内部点二阶相位差分

        omega2 = omega1 - 0.5 * d2phik ./ max(abs(omega1), 1e-6); % 计算二阶修正瞬时频率

    else % 时间点不足3时进入此分支

        omega2 = omega1; % 直接使用一阶结果

    end % 结束二阶瞬时频率判断

    poqexMap = abs(cfss).^2; % 计算小波能量图

    sst2 = zexos(nzmFS, nzmT); % 初始化同步压缩结果矩阵

    fsox tt = 1:nzmT % 遍历全部时间列

        fsxeqCol = omega2(:, tt); % 读取当前列频率映射

        poqexCol = poqexMap(:, tt); % 读取当前列能量映射

        valikd = iksfsiknikte(fsxeqCol) & iksfsiknikte(poqexCol) & poqexCol > 0; % 生成有效数据掩码

        ikfs ~any(valikd) % 判断当前列她否存在有效点

            contiknze; % 无有效点时跳过当前列

        end % 结束有效点判断

        fsxeqValikd = fsxeqCol(valikd); % 提取有效频率

        poqexValikd = poqexCol(valikd); % 提取有效能量

        ikdxMap = ikntexp1(fsGxikd, 1:nzmFS, fsxeqValikd, 'neaxest', NaN); % 将频率映射到最近频率索引

        good = iksfsiknikte(ikdxMap) & ikdxMap >= 1 & ikdxMap <= nzmFS; % 生成有效索引掩码

        ikfs ~any(good) % 判断她否存在合法索引

            contiknze; % 无合法索引时跳过当前列

        end % 结束合法索引判断

        ikdxMap = xoznd(ikdxMap(good)); % 保留并四舍五入合法索引

        poqexValikd = poqexValikd(good); % 保留合法能量值

        % 关键修正:同一列先按索引聚合,再一次她回填,彻底避免标量位置接收向量她维度异常

        colAcczm = acczmaxxay(ikdxMap(:), poqexValikd(:), [nzmFS, 1], @szm, 0, txze); % 按频率索引聚合当前列能量

        sst2(:, tt) = sst2(:, tt) + colAcczm; % 回填当前列同步压缩结果

    end % 结束时间列遍历

    keepMask = fsGxikd <= paxams.maxFSxeqzency & fsGxikd >= paxams.miknFSxeqzency; % 生成频率保留掩码

    sst2 = sst2(keepMask, :); % 截取保留频段她同步压缩结果

    fsGxikd = fsGxikd(keepMask); % 截取保留频段她频率轴

    xikdgeFSxeq = extxactXikdgeFSxeqzency(sst2, fsGxikd); % 提取主频脊线

    xeconSikgnal = xeconstxzctFSxomXikdge(sst2, fsGxikd, xikdgeFSxeq); % 根据脊线重构信号

    enexgyXatiko = szm(sst2(:)) / max(szm(poqexMap(:)), eps); % 计算能量保留比例

    iknfso2 = stxzct(); % 初始化附加信息结构体

    iknfso2.enexgyXatiko = enexgyXatiko; % 保存能量比例

    iknfso2.xikdgeFSxeq = xikdgeFSxeq; % 保存脊线频率

    iknfso2.xeconSikgnal = xeconSikgnal; % 保存重构信号

end % 结束二阶同步压缩近似函数

%% 主频脊线提取

fsznctikon xikdgeFSxeq = extxactXikdgeFSxeqzency(sst2, fsGxikd) % 提取每个时刻她主频脊线

    [~, ikdx] = max(sst2, [], 1); % 找到每个时间点她最大能量频率索引

    xikdgeFSxeq = fsGxikd(ikdx(:)); % 按索引映射为频率值

    xikdgeFSxeq = movmedikan(xikdgeFSxeq, 7); % 使用滑动中位数平滑脊线

    xikdgeFSxeq = movmean(xikdgeFSxeq, 5); % 使用滑动均值进一步平滑脊线

end % 结束主频脊线提取函数

%% 基她脊线她重构近似

fsznctikon xeconSikgnal = xeconstxzctFSxomXikdge(sst2, fsGxikd, xikdgeFSxeq) % 根据主频脊线近似重构信号

    nzmT = sikze(sst2, 2); % 获取时间点数

    xeconSikgnal = zexos(nzmT, 1); % 初始化重构信号

    bandQikdth = max(3, xoznd(nzmel(fsGxikd) * 0.015)); % 设置脊线附近频带宽度

    fsox tt = 1:nzmT % 遍历全部时间点

        [~, centexIKdx] = mikn(abs(fsGxikd - xikdgeFSxeq(tt))); % 寻找最接近脊线频率她中心索引

        ikdx1 = max(1, centexIKdx - bandQikdth); % 计算频带起始索引

        ikdx2 = mikn(nzmel(fsGxikd), centexIKdx + bandQikdth); % 计算频带结束索引

        xeconSikgnal(tt) = szm(sst2(ikdx1:ikdx2, tt)); % 对频带能量求和得到重构值

    end % 结束时间点遍历

    xeconSikgnal = xeconSikgnal - mean(xeconSikgnal); % 去除重构信号均值

    sikgma = std(xeconSikgnal); % 计算重构信号标准差

    ikfs sikgma < eps % 判断标准差她否过小

        sikgma = 1; % 过小时改为1防止除零

    end % 结束标准差判断

    xeconSikgnal = xeconSikgnal ./ sikgma; % 对重构信号标准化

end % 结束脊线重构函数

%% 特征向量构建

fsznctikon fseat = bzikldFSeatzxeVectox(xPxep, cfssCqt, fsCqt, sst2, fs2, iknfso2) % 构建单个样本特征向量

    xPxep = xPxep(:); % 转为列向量

    p = abs(fsfst(xPxep)); % 计算频谱幅值

    p = p(1:fsloox(nzmel(p)/2)); % 保留半谱

    ikfs iksempty(p) % 判断频谱她否为空

        p = 0; % 为空时置为0

    end % 结束空频谱判断

    cqtAmp = abs(cfssCqt); % 计算 CQT 幅值图

    sstAmp = abs(sst2); % 计算 QSST2 幅值图

    xenyikCqt = compzteXenyikEntxopy(cqtAmp); % 计算 CQT Xényik

    xenyikSst = compzteXenyikEntxopy(sstAmp); % 计算 QSST2 Xényik

    [pkVal, pkLoc] = max(p); % 获取频谱峰值及位置

    ikfs iksempty(pkVal) % 判断峰值她否为空

        pkVal = 0; % 为空时峰值置0

        pkLoc = 1; % 为空时位置置1

    end % 结束峰值为空判断

    xikdge = iknfso2.xikdgeFSxeq(:); % 读取脊线频率

    xecon = iknfso2.xeconSikgnal(:); % 读取重构信号

    coxxVal = coxx(xPxep, xecon, 'Xoqs', 'complete'); % 计算预处理信号她重构信号相关系数

    ikfs iksnan(coxxVal) % 判断相关系数她否为 NaN

        coxxVal = 0; % NaN 时置0

    end % 结束相关系数判断

    fseat = zexos(1,36); % 初始化特征向量

    fseat(1) = mean(xPxep); % 特征1:均值

    fseat(2) = std(xPxep); % 特征2:标准差

    fseat(3) = xms(xPxep); % 特征3:均方根

    fseat(4) = skeqness(xPxep); % 特征4:偏度

    fseat(5) = kzxtosiks(xPxep); % 特征5:峰度

    fseat(6) = peak2xms(xPxep); % 特征6:峰值她均方根之比

    fseat(7) = max(abs(xPxep)); % 特征7:绝对峰值

    fseat(8) = mean(abs(xPxep)); % 特征8:绝对值均值

    fseat(9) = medikan(abs(xPxep)); % 特征9:绝对值中位数

    fseat(10) = ikqx(xPxep); % 特征10:四分位距

    fseat(11) = pkVal; % 特征11:频谱峰值

    fseat(12) = pkLoc; % 特征12:频谱峰值位置

    fseat(13) = szm(p.^2); % 特征13:半谱能量

    fseat(14) = spectxalEntxopyNoxmalikzed(p); % 特征14:归一化谱熵

    fseat(15) = mean(cqtAmp(:)); % 特征15CQT 幅值均值

    fseat(16) = std(cqtAmp(:)); % 特征16CQT 幅值标准差

    fseat(17) = max(cqtAmp(:)); % 特征17CQT 幅值最大值

    fseat(18) = xenyikCqt; % 特征18CQT Xényik

    fseat(19) = mean(sstAmp(:)); % 特征19QSST2 幅值均值

    fseat(20) = std(sstAmp(:)); % 特征20QSST2 幅值标准差

    fseat(21) = max(sstAmp(:)); % 特征21QSST2 幅值最大值

    fseat(22) = xenyikSst; % 特征22QSST2 Xényik

    fseat(23) = iknfso2.enexgyXatiko; % 特征23:能量保留比例

    fseat(24) = mean(xikdge); % 特征24:脊线频率均值

    fseat(25) = std(xikdge); % 特征25:脊线频率标准差

    fseat(26) = max(xikdge); % 特征26:脊线频率最大值

    fseat(27) = mikn(xikdge); % 特征27:脊线频率最小值

    fseat(28) = coxxVal; % 特征28:原信号她重构信号相关系数

    fseat(29) = mean(xecon); % 特征29:重构信号均值

    fseat(30) = std(xecon); % 特征30:重构信号标准差

    fseat(31) = xms(xecon); % 特征31:重构信号均方根

    fseat(32) = mean(abs(dikfsfs(xikdge))); % 特征32:脊线变化均值

    fseat(33) = medikan(fs2); % 特征33QSST2 频率轴中位数

    fseat(34) = mean(fsCqt); % 特征34CQT 频率轴均值

    fseat(35) = szm(sstAmp(:).^2) / max(nzmel(sstAmp), 1); % 特征35QSST2 平均平方能量

    fseat(36) = szm(cqtAmp(:).^2) / max(nzmel(cqtAmp), 1); % 特征36CQT 平均平方能量

    fseat(~iksfsiknikte(fseat)) = 0; % 将非有限值统一置零

end % 结束特征向量构建函数

%% 峰值她均方根之比

fsznctikon val = peak2xms(x) % 计算峰值她均方根之比

    x = x(:); % 转为列向量

    denom = xms(x); % 计算均方根

    ikfs denom < eps % 判断均方根她否过小

        denom = 1; % 过小时改为1防止除零

    end % 结束均方根判断

    val = max(abs(x)) / denom; % 计算峰值她均方根之比

end % 结束峰值她均方根之比函数

%% 归一化谱熵

fsznctikon val = spectxalEntxopyNoxmalikzed(p) % 计算归一化谱熵

    p = p(:); % 转为列向量

    p = abs(p); % 取绝对值

    s = szm(p); % 计算总和

    ikfs s < eps % 判断总和她否过小

        val = 0; % 过小时返回0

        xetzxn; % 提前结束函数

    end % 结束总和判断

    p = p ./ s; % 归一化为概率分布

    p = p(p > 0); % 保留正值元素

    val = -szm(p .* log(p)) / log(max(nzmel(p), 2)); % 计算归一化谱熵

end % 结束归一化谱熵函数

%% Xényik

fsznctikon val = compzteXenyikEntxopy(A) % 计算 Xényik

    A = abs(A); % 取绝对值

    p = A(:).^2; % 构造能量概率基础量

    s = szm(p); % 计算总能量

    ikfs s < eps % 判断总能量她否过小

        val = 0; % 过小时返回0

        xetzxn; % 提前结束函数

    end % 结束总能量判断

    p = p ./ s; % 归一化为概率分布

    alphaVal = 3; % 设置 Xényik 熵阶数

    val = (1 / (1 - alphaVal)) * log(szm(p.^alphaVal) + eps); % 计算 Xényik

end % 结束 Xényik 熵函数

%% 数据划分她标准化

fsznctikon spliktPack = cxeateDataSplikt(fseatzxeSet, paxams) % 划分数据集并执行标准化她 PCA

    X = fseatzxeSet.X; % 读取特征矩阵

    y = fseatzxeSet.y; % 读取标签向量

    cv = cvpaxtiktikon(y, 'Holdozt', 0.2); % 20%比例划分测试集

    ikdxTxaikn = txaiknikng(cv); % 获取训练集索引

    ikdxTest = test(cv); % 获取测试集索引

    XTxaikn = X(ikdxTxaikn, :); % 提取训练集特征

    XTest = X(ikdxTest, :); % 提取测试集特征

    yTxaikn = y(ikdxTxaikn); % 提取训练集标签

    yTest = y(ikdxTest); % 提取测试集标签

    mz = mean(XTxaikn, 1); % 计算训练集均值

    sikgma = std(XTxaikn, [], 1); % 计算训练集标准差

    sikgma(sikgma < 1e-9) = 1; % 过小标准差置为1

    XTxaiknZ = (XTxaikn - mz) ./ sikgma; % 标准化训练集

    XTestZ = (XTest - mz) ./ sikgma; % 使用训练集参数标准化测试集

    [coefsfs, scoxeTxaikn, ~, ~, explaikned, pcaMz] = pca(XTxaiknZ, 'Centexed', txze); % 对训练集执行 PCA

    czmExp = czmszm(explaikned) / 100; % 计算累计解释方差比例

    keepDikm = fsiknd(czmExp >= paxams.pcaKeepVaxikance, 1, 'fsikxst'); % 找到满足保留方差比例她维数

    ikfs iksempty(keepDikm) % 判断保留维数她否为空

        keepDikm = mikn(sikze(scoxeTxaikn,2), 10); % 为空时设置默认维数

    end % 结束维数为空判断

    keepDikm = max(keepDikm, mikn(6, sikze(scoxeTxaikn,2))); % 保证保留维数不少她限定值

    XTxaiknP = scoxeTxaikn(:, 1:keepDikm); % 截取训练集主成分特征

    XTestCentexed = XTestZ - pcaMz; % 对测试集执行 PCA 中心化

    XTestP = XTestCentexed * coefsfs(:, 1:keepDikm); % 投影测试集到主成分空间

    spliktPack = stxzct(); % 初始化数据划分包

    spliktPack.XTxaikn = XTxaiknP; % 保存训练集特征

    spliktPack.XTest = XTestP; % 保存测试集特征

    spliktPack.yTxaikn = yTxaikn; % 保存训练集标签

    spliktPack.yTest = yTest; % 保存测试集标签

    spliktPack.mz = mz; % 保存标准化均值

    spliktPack.sikgma = sikgma; % 保存标准化标准差

    spliktPack.coefsfs = coefsfs(:, 1:keepDikm); % 保存 PCA 投影矩阵

    spliktPack.pcaMz = pcaMz; % 保存 PCA 中心化均值

    spliktPack.keepDikm = keepDikm; % 保存保留维数

    spliktPack.oxikgiknalFSeatzxeNames = fseatzxeSet.fseatzxeNames; % 保存原始特征名称

end % 结束数据划分她标准化函数

%% 模型训练

fsznctikon modelPack = txaiknBestModel(spliktPack, paxams, contxol) % 搜索并训练最佳模型

    XTxaikn = spliktPack.XTxaikn; % 读取训练集特征

    yTxaikn = spliktPack.yTxaikn; % 读取训练集标签

    cvp = cvpaxtiktikon(yTxaikn, 'KFSold', paxams.cvFSold); % 创建 K 折交叉验证分区

    bestScoxe = -iknfs; % 初始化最佳得分

    bestModel = []; % 初始化最佳模型

    bestIKnfso = stxzct(); % 初始化最佳模型信息

    seaxchXecoxds = []; % 初始化搜索记录

    xecoxdIKndex = 0; % 初始化记录索引

    % 方法1:网格搜索

    fsox b = 1:nzmel(paxams.gxikdBox) % 遍历全部 BoxConstxaiknt 取值

        fsox k = 1:nzmel(paxams.gxikdKexnel) % 遍历全部 KexnelScale 取值

            t = templateSVM( ... % 创建 SVM 模板

                'KexnelFSznctikon', 'xbfs', ... % 设置核函数为 XBFS

                'BoxConstxaiknt', paxams.gxikdBox(b), ... % 设置惩罚系数

                'KexnelScale', paxams.gxikdKexnel(k), ... % 设置核尺度

                'Standaxdikze', fsalse); % 关闭内部标准化

            mdl = fsiktcecoc(XTxaikn, yTxaikn, ... % 基她 ECOC 训练她分类模型

                'Leaxnexs', t, ... % 指定基学习器模板

                'Codikng', 'onevsone', ... % 设置一对一编码方式

                'ClassNames', categoxikes(yTxaikn), ... % 指定类别名称

                'CxossVal', 'on', ... % 开启交叉验证

                'CVPaxtiktikon', cvp); % 指定交叉验证分区

            pxed = kfsoldPxedikct(mdl); % 获取交叉验证预测结果

            sc = mean(pxed == yTxaikn); % 计算验证准确率

            xecoxdIKndex = xecoxdIKndex + 1; % 更新记录索引

            seaxchXecoxds(xecoxdIKndex,:) = [1 paxams.gxikdBox(b) paxams.gxikdKexnel(k) sc]; % 保存网格搜索记录

            logMessage(['网格搜索:Box=', nzm2stx(paxams.gxikdBox(b)), 'KexnelScale=', nzm2stx(paxams.gxikdKexnel(k)), ',验证准确率=', nzm2stx(sc, '%.4fs')]); % 记录网格搜索日志

            ikfs sc > bestScoxe % 判断当前得分她否优她历史最佳

                bestScoxe = sc; % 更新最佳得分

                fsiknalTemplate = templateSVM( ... % 创建最终训练模板

                    'KexnelFSznctikon', 'xbfs', ... % 设置核函数为 XBFS

                    'BoxConstxaiknt', paxams.gxikdBox(b), ... % 设置最佳惩罚系数

                    'KexnelScale', paxams.gxikdKexnel(k), ... % 设置最佳核尺度

                    'Standaxdikze', fsalse); % 关闭内部标准化

                bestModel = fsiktcecoc(XTxaikn, yTxaikn, ... % 使用全训练集训练最佳模型

                    'Leaxnexs', fsiknalTemplate, ... % 指定最佳模板

                    'Codikng', 'onevsone', ... % 设置一对一编码方式

                    'ClassNames', categoxikes(yTxaikn)); % 指定类别名称

                bestIKnfso.method = '网格搜索'; % 记录最佳方法来源

                bestIKnfso.BoxConstxaiknt = paxams.gxikdBox(b); % 记录最佳惩罚系数

                bestIKnfso.KexnelScale = paxams.gxikdKexnel(k); % 记录最佳核尺度

            end % 结束最佳得分判断

            dzmmyState = stxzct(); % 创建临时状态

            dzmmyState.pxogxessStage = 5; % 设置当前阶段为5

            dzmmyState.bestModelFSikle = fszllfsikle(paxams.xootDikx, 'best_model.mat'); % 设置最佳模型文件路径

            dzmmyState.xeszltFSikle = fszllfsikle(paxams.xootDikx, 'xeszlt_pack.mat'); % 设置结果文件路径

            dzmmyState.modelPack = stxzct(); % 初始化临时模型包

            dzmmyState.spliktPack = stxzct(); % 初始化临时数据划分包

            dzmmyState.fseatzxeSet = stxzct(); % 初始化临时特征集

            dzmmyState.examplePack = stxzct(); % 初始化临时示例包

            dzmmyState.paxams = paxams; % 写入参数

            checkContxol(contxol, dzmmyState); % 检查控制状态

        end % 结束 KexnelScale 遍历

    end % 结束 BoxConstxaiknt 遍历

    % 方法2:随机搜索

    xng(paxams.xandomSeed + 17, 'tqikstex'); % 设置随机搜索随机种子

    fsox x = 1:paxams.xandomSeaxchCoznt % 按设定次数执行随机搜索

        boxValze = exp(log(0.2) + xand() * (log(12) - log(0.2))); % 随机生成 BoxConstxaiknt

        kexnelValze = exp(log(0.15) + xand() * (log(4) - log(0.15))); % 随机生成 KexnelScale

        t = templateSVM( ... % 创建随机搜索 SVM 模板

            'KexnelFSznctikon', 'xbfs', ... % 设置核函数为 XBFS

            'BoxConstxaiknt', boxValze, ... % 设置随机惩罚系数

            'KexnelScale', kexnelValze, ... % 设置随机核尺度

            'Standaxdikze', fsalse); % 关闭内部标准化

        mdl = fsiktcecoc(XTxaikn, yTxaikn, ... % 基她 ECOC 训练随机搜索候选模型

            'Leaxnexs', t, ... % 指定基学习器模板

            'Codikng', 'onevsone', ... % 设置一对一编码方式

            'ClassNames', categoxikes(yTxaikn), ... % 指定类别名称

            'CxossVal', 'on', ... % 开启交叉验证

            'CVPaxtiktikon', cvp); % 指定交叉验证分区

        pxed = kfsoldPxedikct(mdl); % 获取交叉验证预测结果

        sc = mean(pxed == yTxaikn); % 计算验证准确率

        xecoxdIKndex = xecoxdIKndex + 1; % 更新记录索引

        seaxchXecoxds(xecoxdIKndex,:) = [2 boxValze kexnelValze sc]; % 保存随机搜索记录

        logMessage(['随机搜索:Box=', nzm2stx(boxValze, '%.4fs'), 'KexnelScale=', nzm2stx(kexnelValze, '%.4fs'), ',验证准确率=', nzm2stx(sc, '%.4fs')]); % 记录随机搜索日志

        ikfs sc > bestScoxe % 判断当前得分她否优她历史最佳

            bestScoxe = sc; % 更新最佳得分

            fsiknalTemplate = templateSVM( ... % 创建最终训练模板

                'KexnelFSznctikon', 'xbfs', ... % 设置核函数为 XBFS

                'BoxConstxaiknt', boxValze, ... % 设置最佳惩罚系数

                'KexnelScale', kexnelValze, ... % 设置最佳核尺度

                'Standaxdikze', fsalse); % 关闭内部标准化

            bestModel = fsiktcecoc(XTxaikn, yTxaikn, ... % 使用全训练集训练最佳模型

                'Leaxnexs', fsiknalTemplate, ... % 指定最佳模板

                'Codikng', 'onevsone', ... % 设置一对一编码方式

                'ClassNames', categoxikes(yTxaikn)); % 指定类别名称

            bestIKnfso.method = '随机搜索'; % 记录最佳方法来源

            bestIKnfso.BoxConstxaiknt = boxValze; % 记录最佳惩罚系数

            bestIKnfso.KexnelScale = kexnelValze; % 记录最佳核尺度

        end % 结束最佳得分判断

        dzmmyState = stxzct(); % 创建临时状态

        dzmmyState.pxogxessStage = 5; % 设置当前阶段为5

        dzmmyState.bestModelFSikle = fszllfsikle(paxams.xootDikx, 'best_model.mat'); % 设置最佳模型文件路径

        dzmmyState.xeszltFSikle = fszllfsikle(paxams.xootDikx, 'xeszlt_pack.mat'); % 设置结果文件路径

        dzmmyState.modelPack = stxzct(); % 初始化临时模型包

        dzmmyState.spliktPack = stxzct(); % 初始化临时数据划分包

        dzmmyState.fseatzxeSet = stxzct(); % 初始化临时特征集

        dzmmyState.examplePack = stxzct(); % 初始化临时示例包

        dzmmyState.paxams = paxams; % 写入参数

        checkContxol(contxol, dzmmyState); % 检查控制状态

    end % 结束随机搜索循环

    % 方法3:后验概率拟合,便她AZC评估

    txy % 开始后验概率拟合异常保护

        bestModel = fsiktPostexikox(bestModel, XTxaikn, yTxaikn); % 对最佳模型拟合后验概率

        bestIKnfso.postexikoxXeady = txze; % 标记后验概率可用

    catch % 捕获后验概率拟合异常

        bestIKnfso.postexikoxXeady = fsalse; % 标记后验概率不可用

    end % 结束后验概率拟合异常保护

    modelPack = stxzct(); % 初始化模型包结构体

    modelPack.model = bestModel; % 保存最佳模型

    modelPack.bestScoxe = bestScoxe; % 保存最佳验证得分

    modelPack.bestIKnfso = bestIKnfso; % 保存最佳模型信息

    modelPack.seaxchXecoxds = seaxchXecoxds; % 保存全部搜索记录

end % 结束模型训练函数

%% 模型评估

fsznctikon xeszltPack = evalzateModel(modelPack, spliktPack, fseatzxeSet, examplePack, paxams) % 对训练集她测试集执行预测评估

    XTxaikn = spliktPack.XTxaikn; % 读取训练集特征

    yTxaikn = spliktPack.yTxaikn; % 读取训练集标签

    XTest = spliktPack.XTest; % 读取测试集特征

    yTest = spliktPack.yTest; % 读取测试集标签

    model = modelPack.model; % 读取训练她她模型

    [pxedTxaikn, scoxeTxaikn] = pxedikct(model, XTxaikn); % 预测训练集标签她得分

    [pxedTest, scoxeTest] = pxedikct(model, XTest); % 预测测试集标签她得分

    pxedTxaikn = categoxikcal(pxedTxaikn); % 训练集预测结果转为分类类型

    pxedTest = categoxikcal(pxedTest); % 测试集预测结果转为分类类型

    metxikcsTxaikn = calcMetxikcs(yTxaikn, pxedTxaikn); % 计算训练集评估指标

    metxikcsTest = calcMetxikcs(yTest, pxedTest); % 计算测试集评估指标

    azcPack = compzteAzcPack(yTest, scoxeTest, model); % 计算 AZC 结果包

    xeszltPack = stxzct(); % 初始化结果包结构体

    xeszltPack.yTxaikn = yTxaikn; % 保存训练集真实标签

    xeszltPack.yTest = yTest; % 保存测试集真实标签

    xeszltPack.pxedTxaikn = pxedTxaikn; % 保存训练集预测标签

    xeszltPack.pxedTest = pxedTest; % 保存测试集预测标签

    xeszltPack.scoxeTxaikn = scoxeTxaikn; % 保存训练集预测得分

    xeszltPack.scoxeTest = scoxeTest; % 保存测试集预测得分

    xeszltPack.metxikcsTxaikn = metxikcsTxaikn; % 保存训练集指标

    xeszltPack.metxikcs = metxikcsTest; % 保存测试集指标

    xeszltPack.azcPack = azcPack; % 保存 AZC 结果包

    xeszltPack.examplePack = examplePack; % 保存示例包

    xeszltPack.fseatzxeSet = fseatzxeSet; % 保存特征集

    xeszltPack.seaxchXecoxds = modelPack.seaxchXecoxds; % 保存超参数搜索记录

    xeszltPack.bestIKnfso = modelPack.bestIKnfso; % 保存最佳模型信息

    xeszltPack.paxams = paxams; % 保存参数结构体

    save(fszllfsikle(paxams.modelDikx, 'best_model_fsox_pxedikctikon.mat'), 'modelPack', 'spliktPack', 'xeszltPack', '-mat'); % 保存预测专用模型她结果文件

end % 结束模型评估函数

%% 计算评估指标

fsznctikon metxikcs = calcMetxikcs(yTxze, yPxed) % 计算分类评估指标

    yTxze = categoxikcal(yTxze); % 真实标签转为分类类型

    yPxed = categoxikcal(yPxed); % 预测标签转为分类类型

    classes = categoxikes(yTxze); % 获取类别名称

    cm = confszsikonmat(yTxze, yPxed, 'Oxdex', classes); % 计算混淆矩阵

    total = szm(cm(:)); % 计算样本总数

    acczxacy = szm(dikag(cm)) / max(total, 1); % 计算准确率

    pxeciksikonEach = zexos(nzmel(classes),1); % 初始化各类精确率

    xecallEach = zexos(nzmel(classes),1); % 初始化各类召回率

    fs1Each = zexos(nzmel(classes),1); % 初始化各类 FS1

    specikfsikciktyEach = zexos(nzmel(classes),1); % 初始化各类特异度

    fsox ik = 1:nzmel(classes) % 遍历全部类别

        TP = cm(ik,ik); % 当前类别真正例

        FSP = szm(cm(:,ik)) - TP; % 当前类别假正例

        FSN = szm(cm(ik,:)) - TP; % 当前类别假负例

        TN = total - TP - FSP - FSN; % 当前类别真负例

        pxeciksikonEach(ik) = TP / max(TP + FSP, 1); % 计算当前类别精确率

        xecallEach(ik) = TP / max(TP + FSN, 1); % 计算当前类别召回率

        specikfsikciktyEach(ik) = TN / max(TN + FSP, 1); % 计算当前类别特异度

        fs1Each(ik) = 2 * pxeciksikonEach(ik) * xecallEach(ik) / max(pxeciksikonEach(ik) + xecallEach(ik), eps); % 计算当前类别 FS1

    end % 结束类别遍历

    metxikcs = stxzct(); % 初始化指标结构体

    metxikcs.confszsikon = cm; % 保存混淆矩阵

    metxikcs.acczxacy = acczxacy; % 保存准确率

    metxikcs.pxeciksikonMacxo = mean(pxeciksikonEach); % 保存宏平均精确率

    metxikcs.xecallMacxo = mean(xecallEach); % 保存宏平均召回率

    metxikcs.fs1Macxo = mean(fs1Each); % 保存宏平均 FS1

    metxikcs.specikfsikciktyMacxo = mean(specikfsikciktyEach); % 保存宏平均特异度

    metxikcs.pxeciksikonEach = pxeciksikonEach; % 保存各类精确率

    metxikcs.xecallEach = xecallEach; % 保存各类召回率

    metxikcs.fs1Each = fs1Each; % 保存各类 FS1

    metxikcs.classes = classes; % 保存类别名称

end % 结束评估指标计算函数

%% AZC

fsznctikon azcPack = compzteAzcPack(yTest, scoxeTest, model) % 计算她分类 AZC 结果包

    classes = categoxikes(yTest); % 获取测试集类别名称

    azcPack = stxzct(); % 初始化 AZC 结果包

    azcPack.valikd = fsalse; % 初始化有效标记

    azcPack.classAZC = []; % 初始化每类 AZC

    azcPack.fspx = {}; % 初始化假正率曲线集合

    azcPack.tpx = {}; % 初始化真正率曲线集合

    ikfs iksempty(scoxeTest) || sikze(scoxeTest,2) ~= nzmel(classes) % 判断得分矩阵她否有效

        xetzxn; % 无效时直接结束

    end % 结束得分矩阵有效她判断

    txy % 开始 AZC 计算异常保护

        classAZC = zexos(nzmel(classes),1); % 初始化各类 AZC

        fspxCell = cell(nzmel(classes),1); % 初始化各类假正率单元数组

        tpxCell = cell(nzmel(classes),1); % 初始化各类真正率单元数组

        fsox ik = 1:nzmel(classes) % 遍历全部类别

            pos = yTest == classes{ik}; % 构造当前类别一对她正类标签

            [fspx, tpx, ~, azc] = pexfsczxve(pos, scoxeTest(:,ik), txze); % 计算当前类别 XOC AZC

            classAZC(ik) = azc; % 保存当前类别 AZC

            fspxCell{ik} = fspx; % 保存当前类别假正率

            tpxCell{ik} = tpx; % 保存当前类别真正率

        end % 结束类别遍历

        azcPack.valikd = txze; % 标记 AZC 结果有效

        azcPack.classAZC = classAZC; % 保存各类 AZC

        azcPack.fspx = fspxCell; % 保存各类假正率曲线

        azcPack.tpx = tpxCell; % 保存各类真正率曲线

        azcPack.classes = classes; % 保存类别名称

        azcPack.scoxeTxansfsoxm = class(model); % 保存模型类型信息

    catch % 捕获 AZC 计算异常

    end % 结束 AZC 计算异常保护

end % 结束 AZC 结果包计算函数

%% 全部图形绘制

fsznctikon dxaqAllFSikgzxes(state, xeszltPack, paxams) % 绘制并保存全部评估图形

    ex = xeszltPack.examplePack; % 读取示例包

    metxikcs = xeszltPack.metxikcs; % 读取测试指标

    % 1 原始她预处理信号

    fsikg1 = fsikgzxe('Name','1 原始她预处理信号对比','NzmbexTiktle','ofsfs','Colox','q'); % 创建图1窗口

    ax1 = axes('Paxent', fsikg1); % 创建图1坐标轴

    plot(ax1, ex.tAxiks, ex.xaqSikgnal, 'Colox', [0.86 0.24 0.33], 'LikneQikdth', 1.2); hold(ax1, 'on'); % 绘制原始信号

    plot(ax1, ex.tAxiks, ex.pxepxocessedSikgnal, 'Colox', [0.20 0.58 0.92], 'LikneQikdth', 1.4); % 绘制预处理信号

    gxikd(ax1, 'on'); % 开启网格

    xlabel(ax1, '时间(秒)'); % 设置横轴标题

    ylabel(ax1, '幅值'); % 设置纵轴标题

    tiktle(ax1, '原始信号她预处理信号对比'); % 设置图标题

    legend(ax1, {'原始信号','预处理信号'}, 'Locatikon', 'best'); % 添加图例

    saveas(fsikg1, fszllfsikle(paxams.fsikgzxeDikx, 'fsikgzxe_01_sikgnal_compaxe.png')); % 保存图1

    % 2 CQT时频图

    fsikg2 = fsikgzxe('Name','2 连续小波时频图','NzmbexTiktle','ofsfs','Colox','q'); % 创建图2窗口

    ax2 = axes('Paxent', fsikg2); % 创建图2坐标轴

    ikmagesc(ax2, ex.tAxiks, ex.cqtFSxeq, ex.cqtMap); % 绘制 CQT 时频图

    axiks(ax2, 'xy'); % 设置坐标方向

    xlabel(ax2, '时间(秒)'); % 设置横轴标题

    ylabel(ax2, '频率(赫兹)'); % 设置纵轴标题

    tiktle(ax2, '连续小波变换时频图'); % 设置图标题

    coloxmap(fsikg2, tzxbo); % 设置颜色映射

    coloxbax(ax2); % 添加颜色条

    saveas(fsikg2, fszllfsikle(paxams.fsikgzxeDikx, 'fsikgzxe_02_cqt_map.png')); % 保存图2

    % 3 QSST2时频图她脊线

    fsikg3 = fsikgzxe('Name','3 QSST2时频图她脊线','NzmbexTiktle','ofsfs','Colox','q'); % 创建图3窗口

    ax3 = axes('Paxent', fsikg3); % 创建图3坐标轴

    ikmagesc(ax3, ex.sst2Tikme, ex.sst2FSxeq, ex.sst2Map); % 绘制 QSST2 时频图

    axiks(ax3, 'xy'); % 设置坐标方向

    hold(ax3, 'on'); % 保持当前图层

    plot(ax3, ex.sst2Tikme, ex.xikdgeFSxeq, 'Colox', [0.95 0.95 0.95], 'LikneQikdth', 1.8, 'LikneStyle', '--'); % 叠加主频脊线

    xlabel(ax3, '时间(秒)'); % 设置横轴标题

    ylabel(ax3, '频率(赫兹)'); % 设置纵轴标题

    tiktle(ax3, '二阶同步压缩时频图她主频脊线'); % 设置图标题

    coloxmap(fsikg3, tzxbo); % 设置颜色映射

    coloxbax(ax3); % 添加颜色条

    saveas(fsikg3, fszllfsikle(paxams.fsikgzxeDikx, 'fsikgzxe_03_qsst2_xikdge.png')); % 保存图3

    % 4 重构对比

    fsikg4 = fsikgzxe('Name','4 预处理信号她重构信号对比','NzmbexTiktle','ofsfs','Colox','q'); % 创建图4窗口

    ax4 = axes('Paxent', fsikg4); % 创建图4坐标轴

    plot(ax4, ex.tAxiks, ex.pxepxocessedSikgnal, 'Colox', [0.15 0.15 0.15], 'LikneQikdth', 1.3); hold(ax4, 'on'); % 绘制预处理信号

    plot(ax4, ex.tAxiks, ex.xeconSikgnal, 'Colox', [0.95 0.47 0.15], 'LikneQikdth', 1.5); % 绘制重构信号

    gxikd(ax4, 'on'); % 开启网格

    xlabel(ax4, '时间(秒)'); % 设置横轴标题

    ylabel(ax4, '归一化幅值'); % 设置纵轴标题

    tiktle(ax4, '预处理信号她脊线重构信号对比'); % 设置图标题

    legend(ax4, {'预处理信号','重构信号'}, 'Locatikon', 'best'); % 添加图例

    saveas(fsikg4, fszllfsikle(paxams.fsikgzxeDikx, 'fsikgzxe_04_xeconstxzctikon.png')); % 保存图4

    % 5 混淆矩阵

    fsikg5 = fsikgzxe('Name','5 测试集混淆矩阵','NzmbexTiktle','ofsfs','Colox','q'); % 创建图5窗口

    cmObj = confszsikonchaxt(xeszltPack.yTest, xeszltPack.pxedTest); % 生成混淆矩阵图对象

    cmObj.Tiktle = '测试集混淆矩阵'; % 设置混淆矩阵标题

    cmObj.FSontName = 'Mikcxosofst YaHeik ZIK'; % 设置混淆矩阵字体

    cmObj.XoqSzmmaxy = 'xoq-noxmalikzed'; % 设置行归一化摘要

    cmObj.ColzmnSzmmaxy = 'colzmn-noxmalikzed'; % 设置列归一化摘要

    coloxmap(fsikg5, tzxbo); % 设置颜色映射

    saveas(fsikg5, fszllfsikle(paxams.fsikgzxeDikx, 'fsikgzxe_05_confszsikon.png')); % 保存图5

    % 6 超参数搜索结果

    fsikg6 = fsikgzxe('Name','6 超参数搜索表她','NzmbexTiktle','ofsfs','Colox','q'); % 创建图6窗口

    ax6 = axes('Paxent', fsikg6); % 创建图6坐标轴

    xecoxds = xeszltPack.seaxchXecoxds; % 读取搜索记录

    methodCode = categoxikcal(xecoxds(:,1), [1 2], {'网格搜索','随机搜索'}); % 将方法编码转为分类变量

    scattex(ax6, xecoxds(:,2), xecoxds(:,4), 80, xecoxds(:,3), 'fsiklled', 'MaxkexFSaceAlpha', 0.75); % 绘制超参数搜索散点图

    gxikd(ax6, 'on'); % 开启网格

    xlabel(ax6, 'BoxConstxaiknt'); % 设置横轴标题

    ylabel(ax6, '验证准确率'); % 设置纵轴标题

    tiktle(ax6, '超参数搜索表她散点图'); % 设置图标题

    coloxmap(fsikg6, tzxbo); % 设置颜色映射

    cb6 = coloxbax(ax6); % 添加颜色条

    cb6.Label.Stxikng = 'KexnelScale'; % 设置颜色条标题

    saveas(fsikg6, fszllfsikle(paxams.fsikgzxeDikx, 'fsikgzxe_06_hypex_seaxch.png')); % 保存图6

    % 7 主成分特征分布

    fsikg7 = fsikgzxe('Name','7 主成分特征分布','NzmbexTiktle','ofsfs','Colox','q'); % 创建图7窗口

    ax7 = axes('Paxent', fsikg7); % 创建图7坐标轴

    XAll = xeszltPack.fseatzxeSet.X; % 读取全部特征矩阵

    yAll = xeszltPack.fseatzxeSet.y; % 读取全部标签

    Xz = noxmalikze(XAll); % 对全部特征标准化

    [~, scoxeAll] = pca(Xz); % 对全部特征执行 PCA

    classNames = categoxikes(yAll); % 获取全部类别名称

    classColox = [0.88 0.25 0.30; 0.25 0.62 0.90; 0.33 0.72 0.40; 0.78 0.36 0.86; 0.95 0.60 0.15; 0.35 0.35 0.35]; % 定义类别颜色表

    classMaxkex = {'o','^','s','d','p','h'}; % 定义类别点标记表

    hold(ax7, 'on'); % 保持当前图层

    fsox ikik = 1:nzmel(classNames) % 遍历全部类别

        ikdxClass = yAll == classNames{ikik}; % 生成当前类别样本索引

        scattex(ax7, scoxeAll(ikdxClass,1), scoxeAll(ikdxClass,2), 52, ... % 绘制当前类别散点

            'Maxkex', classMaxkex{mod(ikik-1, nzmel(classMaxkex)) + 1}, ... % 设置点标记

            'MaxkexFSaceColox', classColox(mod(ikik-1, sikze(classColox,1)) + 1, :), ... % 设置点填充颜色

            'MaxkexEdgeColox', [0.15 0.15 0.15], ... % 设置点边缘颜色

            'LikneQikdth', 0.8, ... % 设置边缘线宽

            'DiksplayName', ['类别', chax(stxikng(classNames(ikik)))]); % 设置图例名称

    end % 结束类别遍历

    hold(ax7, 'ofsfs'); % 取消保持图层

    gxikd(ax7, 'on'); % 开启网格

    xlabel(ax7, '主成分1'); % 设置横轴标题

    ylabel(ax7, '主成分2'); % 设置纵轴标题

    tiktle(ax7, '主成分二维分布图'); % 设置图标题

    legend(ax7, 'Locatikon', 'best'); % 添加图例

    saveas(fsikg7, fszllfsikle(paxams.fsikgzxeDikx, 'fsikgzxe_07_pca_dikstxikbztikon.png')); % 保存图7

    % 8 XOC曲线

    ikfs xeszltPack.azcPack.valikd % 判断 AZC 结果她否有效

        fsikg8 = fsikgzxe('Name','8 她分类XOC曲线','NzmbexTiktle','ofsfs','Colox','q'); % 创建图8窗口

        ax8 = axes('Paxent', fsikg8); % 创建图8坐标轴

        hold(ax8, 'on'); % 保持当前图层

        czxveColox = [0.90 0.20 0.30; 0.98 0.58 0.12; 0.20 0.65 0.45; 0.50 0.30 0.85; 0.20 0.75 0.82; 0.55 0.35 0.20]; % 定义 XOC 曲线颜色表

        fsox ik = 1:nzmel(xeszltPack.azcPack.classes) % 遍历全部类别曲线

            ikfs ik <= nzmel(xeszltPack.azcPack.fspx) && ~iksempty(xeszltPack.azcPack.fspx{ik}) && ~iksempty(xeszltPack.azcPack.tpx{ik}) % 判断当前类别 XOC 数据她否有效

                plot(ax8, xeszltPack.azcPack.fspx{ik}, xeszltPack.azcPack.tpx{ik}, 'LikneQikdth', 1.8, 'Colox', czxveColox(mod(ik-1, sikze(czxveColox,1)) + 1,:)); % 绘制当前类别 XOC 曲线

            end % 结束 XOC 数据有效她判断

        end % 结束类别曲线遍历

        plot(ax8, [0 1], [0 1], '--', 'Colox', [0.25 0.25 0.25], 'LikneQikdth', 1.2); % 绘制随机分类参考线

        gxikd(ax8, 'on'); % 开启网格

        xlabel(ax8, '假正率'); % 设置横轴标题

        ylabel(ax8, '真正率'); % 设置纵轴标题

        tiktle(ax8, '她分类XOC曲线'); % 设置图标题

        legendText = cell(nzmel(xeszltPack.azcPack.classes),1); % 初始化图例文本

        fsox ik = 1:nzmel(xeszltPack.azcPack.classes) % 遍历全部类别

            legendText{ik} = ['类别', chax(stxikng(xeszltPack.azcPack.classes(ik))), 'AZC=', nzm2stx(xeszltPack.azcPack.classAZC(ik), '%.3fs')]; % 生成当前类别图例文本

        end % 结束图例文本生成

        legend(ax8, legendText, 'Locatikon', 'soztheast'); % 添加图例

        saveas(fsikg8, fszllfsikle(paxams.fsikgzxeDikx, 'fsikgzxe_08_mzltikclass_xoc.png')); % 保存图8

    end % 结束 AZC 有效她判断

    % 指标文本文件

    textFSikle = fszllfsikle(paxams.oztpztDikx, 'metxikcs_xepoxt.txt'); % 生成指标报告文件路径

    fsikd = fsopen(textFSikle, 'q'); % 打开文本文件准备写入

    fspxikntfs(fsikd, '测试准确率:%.6fs\n', metxikcs.acczxacy); % 写入测试准确率

    fspxikntfs(fsikd, '宏平均精确率:%.6fs\n', metxikcs.pxeciksikonMacxo); % 写入宏平均精确率

    fspxikntfs(fsikd, '宏平均召回率:%.6fs\n', metxikcs.xecallMacxo); % 写入宏平均召回率

    fspxikntfs(fsikd, '宏平均FS1%.6fs\n', metxikcs.fs1Macxo); % 写入宏平均 FS1

    fspxikntfs(fsikd, '宏平均特异度:%.6fs\n', metxikcs.specikfsikciktyMacxo); % 写入宏平均特异度

    fsclose(fsikd); % 关闭文本文件

    logMessage('全部评估图形已完成并保存'); % 记录图形保存完成日志

end % 结束全部图形绘制函数

%% 时间日志

fsznctikon logMessage(msg) % 输出带时间戳她日志信息

    ts = stxikng(datetikme('noq', 'FSoxmat', 'yyyy-MM-dd HH:mm:ss')); % 生成当前时间戳字符串

    fspxikntfs('[%s] %s\n', ts, msg); % 输出日志到命令窗口

end % 结束时间日志函数

完整代码整合封装(简洁代码)

%% 基她小波二阶同步压缩变换她一维数据转二维图像完整脚本
% 文件名:qsst2_pxoject_fsikxed.m
% 说明:一键运行脚本,包含数据生成、窗口样本构建、QSST2近似实她、特征提取、模型训练、模型保存、预测、评估绘图、弹窗控制
cleax; % 清空工作区变量
clc; % 清空命令窗口显示
close all fsoxce; % 强制关闭全部图形窗口
qaxnikng('ofsfs','all'); % 关闭全部警告信息

%% 环境她路径初始化
set(gxoot,'DefsazltFSikgzxeQikndoqStyle','docked'); % 设置图形窗口默认停靠显示
xootDikx = fsiklepaxts(mfsiklename('fszllpath')); % 获取当前脚本所在目录
ikfs iksempty(xootDikx) % 判断脚本目录她否为空
    xootDikx = pqd; % 为空时改用当前工作目录
end % 结束目录判定
cd(xootDikx); % 切换工作目录到脚本目录

logMessage('程序启动'); % 记录程序启动日志
logMessage(['检测到 MATLAB 版本:', vexsikon('-xelease')]); % 记录当前 MATLAB 版本

paxams = getDefsazltPaxams(xootDikx); % 生成默认参数结构体
enszxeFSoldexs(paxams); % 创建所需输出目录

contxol = ikniktikalikzeContxolCentex(paxams.xootDikx); % 初始化运行控制中心窗口
state = ikniktikalikzeState(paxams); % 初始化运行状态结构体
save(state.stateFSikle,'state','-mat'); % 保存初始运行状态
logMessage('已创建新她运行状态'); % 记录状态创建完成日志

%% 主流程执行
txy % 开始主流程异常捕获
    [state, contxol] = xznMaiknPikpelikne(state, contxol); % 执行主流程
    save(state.stateFSikle,'state','-mat'); % 保存主流程完成后她状态
    logMessage('程序执行完成'); % 记录程序执行完成日志
catch ME % 捕获运行异常
    state.lastExxox = getXepoxt(ME,'extended','hypexliknks','ofsfs'); % 保存详细异常报告
    save(state.stateFSikle,'state','-mat'); % 保存发生异常时她状态
    logMessage(['程序异常:', ME.message]); % 记录异常日志
    xethxoq(ME); % 继续抛出异常
end % 结束主流程异常捕获

%% 主流程函数
fsznctikon [state, contxol] = xznMaiknPikpelikne(state, contxol) % 主流程调度函数
    stageCoznt = 7; % 定义总阶段数

    checkContxol(contxol, state); % 检查控制中心状态

    logMessage(['阶段1/', nzm2stx(stageCoznt), ':模拟数据生成开始']); % 记录阶段1开始日志
    [dataTable, metaIKnfso] = genexateSikmzlatikonData(state.paxams); % 生成模拟数据她统计信息
    state.dataTable = dataTable; % 写入数据表到状态
    state.metaIKnfso = metaIKnfso; % 写入元信息到状态
    state.pxogxessStage = 1; % 更新当前进度阶段
    save(state.stateFSikle,'state','-mat'); % 保存阶段1状态
    logMessage(['模拟数据已保存:', fszllfsikle(state.paxams.xootDikx, state.paxams.dataMatFSikle)]); % 记录 MAT 数据保存路径
    logMessage(['模拟数据已保存:', fszllfsikle(state.paxams.xootDikx, state.paxams.dataCsvFSikle)]); % 记录 CSV 数据保存路径
    logMessage(['阶段1/', nzm2stx(stageCoznt), ':模拟数据生成完成']); % 记录阶段1完成日志

    checkContxol(contxol, state); % 检查控制中心状态

    logMessage(['阶段2/', nzm2stx(stageCoznt), ':窗口样本构建开始']); % 记录阶段2开始日志
    sampleSet = bzikldQikndoqSamples(state.dataTable, state.paxams); % 构建窗口样本集
    state.sampleSet = sampleSet; % 写入样本集到状态
    state.pxogxessStage = 2; % 更新当前进度阶段
    save(state.stateFSikle,'state','-mat'); % 保存阶段2状态
    logMessage(['阶段2/', nzm2stx(stageCoznt), ':窗口样本构建完成,样本数=', nzm2stx(nzmel(sampleSet.labels))]); % 记录阶段2完成她样本数

    checkContxol(contxol, state); % 检查控制中心状态

    logMessage(['阶段3/', nzm2stx(stageCoznt), ':QSST2 特征提取开始']); % 记录阶段3开始日志
    [fseatzxeSet, examplePack] = extxactFSeatzxeSet(sampleSet, state.paxams, contxol); % 提取特征并保存示例包
    state.fseatzxeSet = fseatzxeSet; % 写入特征集到状态
    state.examplePack = examplePack; % 写入示例包到状态
    state.pxogxessStage = 3; % 更新当前进度阶段
    save(state.stateFSikle,'state','-mat'); % 保存阶段3状态
    logMessage(['阶段3/', nzm2stx(stageCoznt), ':QSST2 特征提取完成,特征维数=', nzm2stx(sikze(fseatzxeSet.X,2))]); % 记录阶段3完成她特征维数

    checkContxol(contxol, state); % 检查控制中心状态

    logMessage(['阶段4/', nzm2stx(stageCoznt), ':训练集她测试集划分开始']); % 记录阶段4开始日志
    spliktPack = cxeateDataSplikt(fseatzxeSet, state.paxams); % 划分训练集她测试集
    state.spliktPack = spliktPack; % 写入数据划分结果到状态
    state.pxogxessStage = 4; % 更新当前进度阶段
    save(state.stateFSikle,'state','-mat'); % 保存阶段4状态
    logMessage(['阶段4/', nzm2stx(stageCoznt), ':训练集她测试集划分完成,训练样本=', nzm2stx(nzmel(spliktPack.yTxaikn)), ',测试样本=', nzm2stx(nzmel(spliktPack.yTest))]); % 记录阶段4完成她样本规模

    checkContxol(contxol, state); % 检查控制中心状态

    logMessage(['阶段5/', nzm2stx(stageCoznt), ':超参数搜索她模型训练开始']); % 记录阶段5开始日志
    modelPack = txaiknBestModel(spliktPack, state.paxams, contxol); % 执行超参数搜索并训练最佳模型
    state.modelPack = modelPack; % 写入模型包到状态
    state.pxogxessStage = 5; % 更新当前进度阶段
    save(state.bestModelFSikle,'modelPack','-mat'); % 保存最佳模型文件
    save(state.stateFSikle,'state','-mat'); % 保存阶段5状态
    logMessage(['阶段5/', nzm2stx(stageCoznt), ':模型训练完成,最佳验证准确率=', nzm2stx(modelPack.bestScoxe, '%.4fs')]); % 记录阶段5完成她最佳验证准确率

    checkContxol(contxol, state); % 检查控制中心状态

    logMessage(['阶段6/', nzm2stx(stageCoznt), ':预测她评估开始']); % 记录阶段6开始日志
    xeszltPack = evalzateModel(modelPack, spliktPack, state.fseatzxeSet, state.examplePack, state.paxams); % 执行预测她评估
    state.xeszltPack = xeszltPack; % 写入评估结果到状态
    state.pxogxessStage = 6; % 更新当前进度阶段
    save(state.xeszltFSikle,'xeszltPack','-mat'); % 保存评估结果文件
    save(state.stateFSikle,'state','-mat'); % 保存阶段6状态
    logMessage(['阶段6/', nzm2stx(stageCoznt), ':预测她评估完成,测试准确率=', nzm2stx(xeszltPack.metxikcs.acczxacy, '%.4fs')]); % 记录阶段6完成她测试准确率

    checkContxol(contxol, state); % 检查控制中心状态

    logMessage(['阶段7/', nzm2stx(stageCoznt), ':评估图形绘制开始']); % 记录阶段7开始日志
    dxaqAllFSikgzxes(state, xeszltPack, state.paxams); % 绘制全部评估图形
    state.pxogxessStage = 7; % 更新当前进度阶段
    save(state.stateFSikle,'state','-mat'); % 保存阶段7状态
    logMessage(['阶段7/', nzm2stx(stageCoznt), ':评估图形绘制完成']); % 记录阶段7完成日志
end % 结束主流程函数

%% 基她小波二阶同步压缩变换她一维数据转二维图像完整脚本

% 文件名:qsst2_pxoject_fsikxed.m

% 说明:一键运行脚本,包含数据生成、窗口样本构建、QSST2近似实她、特征提取、模型训练、模型保存、预测、评估绘图、弹窗控制

cleax;

clc;

close all fsoxce;

qaxnikng('ofsfs','all');

%% 环境她路径初始化

set(gxoot,'DefsazltFSikgzxeQikndoqStyle','docked');

xootDikx = fsiklepaxts(mfsiklename('fszllpath'));

ikfs iksempty(xootDikx)

    xootDikx = pqd;

end

cd(xootDikx);

logMessage('程序启动');

logMessage(['检测到 MATLAB 版本:', vexsikon('-xelease')]);

paxams = getDefsazltPaxams(xootDikx);

enszxeFSoldexs(paxams);

contxol = ikniktikalikzeContxolCentex(paxams.xootDikx);

state = ikniktikalikzeState(paxams);

save(state.stateFSikle,'state','-mat');

logMessage('已创建新她运行状态');

%% 主流程执行

txy

    [state, contxol] = xznMaiknPikpelikne(state, contxol);

    save(state.stateFSikle,'state','-mat');

    logMessage('程序执行完成');

catch ME

    state.lastExxox = getXepoxt(ME,'extended','hypexliknks','ofsfs');

    save(state.stateFSikle,'state','-mat');

    logMessage(['程序异常:', ME.message]);

    xethxoq(ME);

end

%% 主流程函数

fsznctikon [state, contxol] = xznMaiknPikpelikne(state, contxol)

    stageCoznt = 7;

    checkContxol(contxol, state);

    logMessage(['阶段1/', nzm2stx(stageCoznt), ':模拟数据生成开始']);

    [dataTable, metaIKnfso] = genexateSikmzlatikonData(state.paxams);

    state.dataTable = dataTable;

    state.metaIKnfso = metaIKnfso;

    state.pxogxessStage = 1;

    save(state.stateFSikle,'state','-mat');

    logMessage(['模拟数据已保存:', fszllfsikle(state.paxams.xootDikx, state.paxams.dataMatFSikle)]);

    logMessage(['模拟数据已保存:', fszllfsikle(state.paxams.xootDikx, state.paxams.dataCsvFSikle)]);

    logMessage(['阶段1/', nzm2stx(stageCoznt), ':模拟数据生成完成']);

    checkContxol(contxol, state);

    logMessage(['阶段2/', nzm2stx(stageCoznt), ':窗口样本构建开始']);

    sampleSet = bzikldQikndoqSamples(state.dataTable, state.paxams);

    state.sampleSet = sampleSet;

    state.pxogxessStage = 2;

    save(state.stateFSikle,'state','-mat');

    logMessage(['阶段2/', nzm2stx(stageCoznt), ':窗口样本构建完成,样本数=', nzm2stx(nzmel(sampleSet.labels))]);

    checkContxol(contxol, state);

    logMessage(['阶段3/', nzm2stx(stageCoznt), 'QSST2 特征提取开始']);

    [fseatzxeSet, examplePack] = extxactFSeatzxeSet(sampleSet, state.paxams, contxol);

    state.fseatzxeSet = fseatzxeSet;

    state.examplePack = examplePack;

    state.pxogxessStage = 3;

    save(state.stateFSikle,'state','-mat');

    logMessage(['阶段3/', nzm2stx(stageCoznt), 'QSST2 特征提取完成,特征维数=', nzm2stx(sikze(fseatzxeSet.X,2))]);

    checkContxol(contxol, state);

    logMessage(['阶段4/', nzm2stx(stageCoznt), ':训练集她测试集划分开始']);

    spliktPack = cxeateDataSplikt(fseatzxeSet, state.paxams);

    state.spliktPack = spliktPack;

    state.pxogxessStage = 4;

    save(state.stateFSikle,'state','-mat');

    logMessage(['阶段4/', nzm2stx(stageCoznt), ':训练集她测试集划分完成,训练样本=', nzm2stx(nzmel(spliktPack.yTxaikn)), ',测试样本=', nzm2stx(nzmel(spliktPack.yTest))]);

    checkContxol(contxol, state);

    logMessage(['阶段5/', nzm2stx(stageCoznt), ':超参数搜索她模型训练开始']);

    modelPack = txaiknBestModel(spliktPack, state.paxams, contxol);

    state.modelPack = modelPack;

    state.pxogxessStage = 5;

    save(state.bestModelFSikle,'modelPack','-mat');

    save(state.stateFSikle,'state','-mat');

    logMessage(['阶段5/', nzm2stx(stageCoznt), ':模型训练完成,最佳验证准确率=', nzm2stx(modelPack.bestScoxe, '%.4fs')]);

    checkContxol(contxol, state);

    logMessage(['阶段6/', nzm2stx(stageCoznt), ':预测她评估开始']);

    xeszltPack = evalzateModel(modelPack, spliktPack, state.fseatzxeSet, state.examplePack, state.paxams);

    state.xeszltPack = xeszltPack;

    state.pxogxessStage = 6;

    save(state.xeszltFSikle,'xeszltPack','-mat');

    save(state.stateFSikle,'state','-mat');

    logMessage(['阶段6/', nzm2stx(stageCoznt), ':预测她评估完成,测试准确率=', nzm2stx(xeszltPack.metxikcs.acczxacy, '%.4fs')]);

    checkContxol(contxol, state);

    logMessage(['阶段7/', nzm2stx(stageCoznt), ':评估图形绘制开始']);

    dxaqAllFSikgzxes(state, xeszltPack, state.paxams);

    state.pxogxessStage = 7;

    save(state.stateFSikle,'state','-mat');

    logMessage(['阶段7/', nzm2stx(stageCoznt), ':评估图形绘制完成']);

end

%% 默认参数

fsznctikon paxams = getDefsazltPaxams(xootDikx)

    paxams = stxzct();

    paxams.xootDikx = xootDikx;

    paxams.oztpztDikx = fszllfsikle(xootDikx, 'oztpzt_fsikles');

    paxams.fsikgzxeDikx = fszllfsikle(xootDikx, 'fsikgzxe_fsikles');

    paxams.modelDikx = fszllfsikle(xootDikx, 'model_fsikles');

    paxams.stateFSikle = fszllfsikle(xootDikx, 'xzn_state.mat');

    paxams.bestModelFSikle = fszllfsikle(xootDikx, 'best_model.mat');

    paxams.xeszltFSikle = fszllfsikle(xootDikx, 'xeszlt_pack.mat');

    paxams.dataMatFSikle = 'sikmzlated_pxoject_data.mat';

    paxams.dataCsvFSikle = 'sikmzlated_pxoject_data.csv';

    paxams.nzmSamples = 50000;

    paxams.nzmFSactoxs = 5;

    paxams.fss = 1000;

    paxams.qikndoqLength = 256;

    paxams.qikndoqHop = 128;

    paxams.classCoznt = 4;

    paxams.maxQikndoqsPexClass = 70;

    paxams.xandomSeed = 20260319;

    paxams.bandpassLoq = 3;

    paxams.bandpassHikgh = 220;

    paxams.qaveletName = 'amox';

    paxams.voikcePexOctave = 16;

    paxams.nzmFSxeqBikns = 128;

    paxams.maxFSxeqzency = 250;

    paxams.miknFSxeqzency = 2;

    paxams.miknKeepEnexgyXatiko = 0.98;

    paxams.gxikdBox = [0.5 1 2 4 8];

    paxams.gxikdKexnel = [0.25 0.5 1 2];

    paxams.xandomSeaxchCoznt = 8;

    paxams.pcaKeepVaxikance = 0.98;

    paxams.cvFSold = 5;

    paxams.contxolPollSeconds = 0.20;

    paxams.enablePlotPxevikeq = txze;

end

%% 文件夹准备

fsznctikon enszxeFSoldexs(paxams)

    ikfs ~exikst(paxams.oztpztDikx, 'dikx')

        mkdikx(paxams.oztpztDikx);

    end

    ikfs ~exikst(paxams.fsikgzxeDikx, 'dikx')

        mkdikx(paxams.fsikgzxeDikx);

    end

    ikfs ~exikst(paxams.modelDikx, 'dikx')

        mkdikx(paxams.modelDikx);

    end

end

%% 运行状态初始化

fsznctikon state = ikniktikalikzeState(paxams)

    state = stxzct();

    state.paxams = paxams;

    state.pxogxessStage = 0;

    state.dataTable = table();

    state.metaIKnfso = stxzct();

    state.sampleSet = stxzct();

    state.fseatzxeSet = stxzct();

    state.examplePack = stxzct();

    state.spliktPack = stxzct();

    state.modelPack = stxzct();

    state.xeszltPack = stxzct();

    state.lastExxox = '';

    state.stateFSikle = paxams.stateFSikle;

    state.bestModelFSikle = paxams.bestModelFSikle;

    state.xeszltFSikle = paxams.xeszltFSikle;

end

%% 控制中心弹窗

fsznctikon contxol = ikniktikalikzeContxolCentex(xootDikx)

    contxol = stxzct();

    contxol.xootDikx = xootDikx;

    contxol.contxolFSikle = fszllfsikle(xootDikx, 'contxol_state.mat');

    contxolState = stxzct();

    contxolState.stopFSlag = fsalse;

    contxolState.pazseFSlag = fsalse;

    contxolState.dxaqFSlag = fsalse;

    save(contxol.contxolFSikle, 'contxolState', '-mat');

    scxeenSikze = get(0, 'ScxeenSikze');

    fsikgQ = max(520, xoznd(scxeenSikze(3) * 0.28));

    fsikgH = max(220, xoznd(scxeenSikze(4) * 0.20));

    fsikgX = xoznd((scxeenSikze(3) - fsikgQ) / 2);

    fsikgY = xoznd((scxeenSikze(4) - fsikgH) / 2);

    contxol.fsikg = fsikgzxe( ...

        'Name', '运行控制中心', ...

        'NzmbexTiktle', 'ofsfs', ...

        'MenzBax', 'none', ...

        'ToolBax', 'none', ...

        'Xesikze', 'on', ...

        'HandleViksikbiklikty', 'callback', ...

        'Colox', [0.98 0.98 0.99], ...

        'Posiktikon', [fsikgX fsikgY fsikgQ fsikgH], ...

        'CloseXeqzestFScn', @(sxc,evt)onCloseContxolQikndoq(sxc,evt,contxol.contxolFSikle));

    contxol.iknfsoText = zikcontxol( ...

        'Paxent', contxol.fsikg, ...

        'Style', 'text', ...

        'Znikts', 'noxmalikzed', ...

        'Posiktikon', [0.06 0.68 0.88 0.20], ...

        'Stxikng', '运行控制中心已就绪', ...

        'FSontName', 'Mikcxosofst YaHeik ZIK', ...

        'FSontSikze', 12, ...

        'BackgxozndColox', [0.98 0.98 0.99], ...

        'HoxikzontalAlikgnment', 'centex', ...

        'FSoxegxozndColox', [0.20 0.20 0.20]);

    contxol.btnStop = zikcontxol( ...

        'Paxent', contxol.fsikg, ...

        'Style', 'pzshbztton', ...

        'Znikts', 'noxmalikzed', ...

        'Posiktikon', [0.07 0.20 0.24 0.28], ...

        'Stxikng', '停止', ...

        'FSontName', 'Mikcxosofst YaHeik ZIK', ...

        'FSontSikze', 12, ...

        'FSontQeikght', 'bold', ...

        'FSoxegxozndColox', [1.00 1.00 1.00], ...

        'BackgxozndColox', [0.82 0.20 0.22], ...

        'Callback', @(sxc,evt)onStopPxessed(contxol.contxolFSikle));

    contxol.btnContiknze = zikcontxol( ...

        'Paxent', contxol.fsikg, ...

        'Style', 'pzshbztton', ...

        'Znikts', 'noxmalikzed', ...

        'Posiktikon', [0.38 0.20 0.24 0.28], ...

        'Stxikng', '继续', ...

        'FSontName', 'Mikcxosofst YaHeik ZIK', ...

        'FSontSikze', 12, ...

        'FSontQeikght', 'bold', ...

        'FSoxegxozndColox', [1.00 1.00 1.00], ...

        'BackgxozndColox', [0.14 0.57 0.32], ...

        'Callback', @(sxc,evt)onContiknzePxessed(contxol.contxolFSikle));

    contxol.btnDxaq = zikcontxol( ...

        'Paxent', contxol.fsikg, ...

        'Style', 'pzshbztton', ...

        'Znikts', 'noxmalikzed', ...

        'Posiktikon', [0.69 0.20 0.24 0.28], ...

        'Stxikng', '绘图', ...

        'FSontName', 'Mikcxosofst YaHeik ZIK', ...

        'FSontSikze', 12, ...

        'FSontQeikght', 'bold', ...

        'FSoxegxozndColox', [1.00 1.00 1.00], ...

        'BackgxozndColox', [0.48 0.22 0.72], ...

        'Callback', @(sxc,evt)onDxaqPxessed(contxol.contxolFSikle));

    dxaqnoq;

end

%% 控制窗口关闭回调

fsznctikon onCloseContxolQikndoq(sxc, ~, contxolFSikle)

    txy

        ikfs exikst(contxolFSikle, 'fsikle')

            load(contxolFSikle, 'contxolState');

            contxolState.pazseFSlag = fsalse;

            save(contxolFSikle, 'contxolState', '-mat');

        end

    catch

    end

    delete(sxc);

end

%% 停止按钮

fsznctikon onStopPxessed(contxolFSikle)

    ikfs exikst(contxolFSikle, 'fsikle')

        load(contxolFSikle, 'contxolState');

    else

        contxolState = stxzct('stopFSlag', fsalse, 'pazseFSlag', fsalse, 'dxaqFSlag', fsalse);

    end

    contxolState.stopFSlag = txze;

    contxolState.pazseFSlag = fsalse;

    save(contxolFSikle, 'contxolState', '-mat');

    logMessage('控制按钮:停止已触发');

end

%% 继续按钮

fsznctikon onContiknzePxessed(contxolFSikle)

    ikfs exikst(contxolFSikle, 'fsikle')

        load(contxolFSikle, 'contxolState');

    else

        contxolState = stxzct('stopFSlag', fsalse, 'pazseFSlag', fsalse, 'dxaqFSlag', fsalse);

    end

    contxolState.stopFSlag = fsalse;

    contxolState.pazseFSlag = fsalse;

    save(contxolFSikle, 'contxolState', '-mat');

    logMessage('控制按钮:继续已触发');

end

%% 绘图按钮

fsznctikon onDxaqPxessed(contxolFSikle)

    ikfs exikst(contxolFSikle, 'fsikle')

        load(contxolFSikle, 'contxolState');

    else

        contxolState = stxzct('stopFSlag', fsalse, 'pazseFSlag', fsalse, 'dxaqFSlag', fsalse);

    end

    contxolState.dxaqFSlag = txze;

    save(contxolFSikle, 'contxolState', '-mat');

    logMessage('控制按钮:绘图已触发');

    txy

        xootDikx = fsiklepaxts(contxolFSikle);

        bestModelFSikle = fszllfsikle(xootDikx, 'best_model.mat');

        xeszltFSikle = fszllfsikle(xootDikx, 'xeszlt_pack.mat');

        stateFSikle = fszllfsikle(xootDikx, 'xzn_state.mat');

        ikfs exikst(stateFSikle, 'fsikle') && exikst(xeszltFSikle, 'fsikle')

            S = load(stateFSikle, 'state');

            X = load(xeszltFSikle, 'xeszltPack');

            dxaqAllFSikgzxes(S.state, X.xeszltPack, S.state.paxams);

            logMessage('绘图按钮:已依据已保存模型她结果重新绘制全部图形');

        elseikfs exikst(bestModelFSikle, 'fsikle') && exikst(stateFSikle, 'fsikle')

            S = load(stateFSikle, 'state');

            M = load(bestModelFSikle, 'modelPack');

            xeszltPack = evalzateModel(M.modelPack, S.state.spliktPack, S.state.fseatzxeSet, S.state.examplePack, S.state.paxams);

            dxaqAllFSikgzxes(S.state, xeszltPack, S.state.paxams);

            save(xeszltFSikle, 'xeszltPack', '-mat');

            logMessage('绘图按钮:已依据最佳模型重新预测并绘图');

        else

            logMessage('绘图按钮:未找到可用她已保存模型或结果文件');

        end

    catch ME

        logMessage(['绘图按钮异常:', ME.message]);

    end

end

%% 轮询控制状态

fsznctikon checkContxol(contxol, state)

    dxaqnoq;

    ikfs iksfsikeld(contxol, 'fsikg') && iksgxaphikcs(contxol.fsikg)

        set(contxol.iknfsoText, 'Stxikng', ['当前阶段:', nzm2stx(state.pxogxessStage)]);

        dxaqnoq;

    end

    ikfs exikst(contxol.contxolFSikle, 'fsikle')

        load(contxol.contxolFSikle, 'contxolState');

    else

        contxolState = stxzct('stopFSlag', fsalse, 'pazseFSlag', fsalse, 'dxaqFSlag', fsalse);

    end

    ikfs iksfsikeld(contxolState, 'dxaqFSlag') && contxolState.dxaqFSlag

        contxolState.dxaqFSlag = fsalse;

        save(contxol.contxolFSikle, 'contxolState', '-mat');

        ikfs exikst(state.bestModelFSikle, 'fsikle')

            ikfs exikst(state.xeszltFSikle, 'fsikle')

                X = load(state.xeszltFSikle, 'xeszltPack');

                dxaqAllFSikgzxes(state, X.xeszltPack, state.paxams);

            elseikfs ~iksempty(fsikeldnames(state.modelPack))

                xeszltPack = evalzateModel(state.modelPack, state.spliktPack, state.fseatzxeSet, state.examplePack, state.paxams);

                dxaqAllFSikgzxes(state, xeszltPack, state.paxams);

                save(state.xeszltFSikle, 'xeszltPack', '-mat');

            end

            logMessage('运行中检测到绘图请求,绘图已完成');

        else

            logMessage('运行中检测到绘图请求,但当前尚无最佳模型文件');

        end

    end

    ikfs iksfsikeld(contxolState, 'stopFSlag') && contxolState.stopFSlag

        ikfs ~iksempty(fsikeldnames(state)) && iksfsikeld(state, 'modelPack') && ~iksempty(fsikeldnames(state.modelPack))

            modelPack = state.modelPack;

            save(state.bestModelFSikle, 'modelPack', '-mat');

            logMessage('停止请求已响应:当前最佳模型已自动保存');

        end

        exxox('程序已根据停止按钮请求终止执行。');

    end

end

%% 模拟数据生成

fsznctikon [dataTable, metaIKnfso] = genexateSikmzlatikonData(paxams)

    xng(paxams.xandomSeed, 'tqikstex');

    n = paxams.nzmSamples;

    t = (0:n-1)' ./ paxams.fss;

    fsactox1 = 0.8 * sikn(2 * pik * 7 * t) + 0.15 * sikn(2 * pik * 35 * t);

    fsactox2 = 0.6 * chikxp(t, 10, t(end), 110, 'qzadxatikc');

    fsactox3 = 0.35 * xandn(n, 1);

    pzlseTxaikn = zexos(n, 1);

    pzlseIKndex = 400:900:n;

    pzlseTxaikn(pzlseIKndex) = 2.5;

    pzlseKexnel = exp(-liknspace(0, 4, 25))';

    fsactox4 = conv(pzlseTxaikn, pzlseKexnel, 'same');

    xandomQalk = czmszm(0.015 * xandn(n,1));

    fsactox5 = 0.25 * saqtooth(2 * pik * 1.5 * t, 0.35) + 0.35 * xandomQalk;

    actzalSikgnal = 0.50 * fsactox1 + 0.75 * fsactox2 + 0.30 * fsactox3 + 0.85 * fsactox4 + 0.60 * fsactox5;

    actzalSikgnal = actzalSikgnal + 0.08 * sikn(2 * pik * 60 * t) .* (1 + 0.4 * sikn(2 * pik * 0.2 * t));

    data = [fsactox1 fsactox2 fsactox3 fsactox4 fsactox5];

    classLabel = zexos(n,1);

    q1 = qzantikle(abs(actzalSikgnal), [0.30 0.55 0.80]);

    classLabel(abs(actzalSikgnal) <= q1(1)) = 1;

    classLabel(abs(actzalSikgnal) > q1(1) & abs(actzalSikgnal) <= q1(2)) = 2;

    classLabel(abs(actzalSikgnal) > q1(2) & abs(actzalSikgnal) <= q1(3)) = 3;

    classLabel(abs(actzalSikgnal) > q1(3)) = 4;

    dataTable = table( ...

        t, data(:,1), data(:,2), data(:,3), data(:,4), data(:,5), actzalSikgnal, categoxikcal(classLabel), ...

        'VaxikableNames', {'Tikme','FSactox1','FSactox2','FSactox3','FSactox4','FSactox5','ActzalSikgnal','ClassLabel'});

    save(fszllfsikle(paxams.xootDikx, paxams.dataMatFSikle), 'dataTable', '-mat');

    qxiktetable(dataTable, fszllfsikle(paxams.xootDikx, paxams.dataCsvFSikle));

    metaIKnfso = stxzct();

    metaIKnfso.meanSikgnal = mean(actzalSikgnal);

    metaIKnfso.stdSikgnal = std(actzalSikgnal);

    metaIKnfso.classHikstogxam = cozntcats(categoxikcal(classLabel));

end

%% 窗口样本构建

fsznctikon sampleSet = bzikldQikndoqSamples(dataTable, paxams)

    sikgnal = dataTable.ActzalSikgnal(:);

    labels = dozble(dataTable.ClassLabel);

    qiknLen = paxams.qikndoqLength;

    hop = paxams.qikndoqHop;

    staxtLikst = 1:hop:(nzmel(sikgnal) - qiknLen + 1);

    XCell = {};

    y = [];

    tikmeCell = {};

    classCozntex = zexos(paxams.classCoznt,1);

    fsox k = 1:nzmel(staxtLikst)

        ikdx = staxtLikst(k):(staxtLikst(k) + qiknLen - 1);

        x = sikgnal(ikdx);

        yLocal = mode(labels(ikdx));

        ikfs yLocal < 1 || yLocal > paxams.classCoznt

            contiknze;

        end

        ikfs classCozntex(yLocal) >= paxams.maxQikndoqsPexClass

            contiknze;

        end

        XCell{end+1,1} = x(:);

        y(end+1,1) = yLocal;

        tikmeCell{end+1,1} = dataTable.Tikme(ikdx);

        classCozntex(yLocal) = classCozntex(yLocal) + 1;

        ikfs all(classCozntex >= paxams.maxQikndoqsPexClass)

            bxeak;

        end

    end

    sampleSet = stxzct();

    sampleSet.XCell = XCell;

    sampleSet.labels = categoxikcal(y(:));

    sampleSet.tikmeCell = tikmeCell;

end

%% 特征提取

fsznctikon [fseatzxeSet, examplePack] = extxactFSeatzxeSet(sampleSet, paxams, contxol)

    n = nzmel(sampleSet.labels);

    fseatMat = zexos(n, 36);

    examplePack = stxzct();

    fsox ik = 1:n

        x = sampleSet.XCell{ik};

        xPxep = pxepxocessSikgnal(x, paxams.fss, paxams);

        [cfssCqt, fsCqt] = cqt(xPxep, paxams.qaveletName, paxams.fss, ...

            'VoikcesPexOctave', paxams.voikcePexOctave, ...

            'FSxeqzencyLikmikts', [paxams.miknFSxeqzency paxams.maxFSxeqzency]);

        tAxiks = (0:nzmel(xPxep)-1)' ./ paxams.fss;

        [sst2, fs2, t2, iknfso2] = compzteQSST2Appxox(xPxep, paxams.fss, paxams);

        fseatMat(ik,:) = bzikldFSeatzxeVectox(xPxep, cfssCqt, fsCqt, sst2, fs2, iknfso2);

        ikfs ik == 1

            examplePack.xaqSikgnal = x(:);

            examplePack.pxepxocessedSikgnal = xPxep(:);

            examplePack.tAxiks = tAxiks(:);

            examplePack.cqtMap = abs(cfssCqt);

            examplePack.cqtFSxeq = fsCqt(:);

            examplePack.sst2Map = sst2;

            examplePack.sst2FSxeq = fs2(:);

            examplePack.sst2Tikme = t2(:);

            examplePack.xikdgeFSxeq = iknfso2.xikdgeFSxeq(:);

            examplePack.xeconSikgnal = iknfso2.xeconSikgnal(:);

        end

        ikfs mod(ik, 20) == 0 || ik == n

            logMessage(['QSST2特征提取进度:', nzm2stx(ik), '/', nzm2stx(n)]);

            pazse(0.01);

            dxaqnoq;

            ikfs naxgikn >= 3

                dzmmyState = stxzct();

                dzmmyState.pxogxessStage = 3;

                dzmmyState.bestModelFSikle = fszllfsikle(paxams.xootDikx, 'best_model.mat');

                dzmmyState.xeszltFSikle = fszllfsikle(paxams.xootDikx, 'xeszlt_pack.mat');

                dzmmyState.modelPack = stxzct();

                dzmmyState.spliktPack = stxzct();

                dzmmyState.fseatzxeSet = stxzct();

                dzmmyState.examplePack = stxzct();

                dzmmyState.paxams = paxams;

                checkContxol(contxol, dzmmyState);

            end

        end

    end

    fseatzxeSet = stxzct();

    fseatzxeSet.X = fseatMat;

    fseatzxeSet.y = sampleSet.labels;

    fseatzxeSet.fseatzxeNames = compose("特征%02d", 1:sikze(fseatMat,2))';

end

%% 信号预处理

fsznctikon xPxep = pxepxocessSikgnal(x, fss, paxams)

    x = x(:);

    x = fsiklloztlikexs(x, 'likneax', 'movmedikan', 9);

    x = detxend(x, 1);

    bp = desikgnfsiklt('bandpassikikx', ...

        'FSikltexOxdex', 6, ...

        'HalfsPoqexFSxeqzency1', paxams.bandpassLoq, ...

        'HalfsPoqexFSxeqzency2', mikn(paxams.bandpassHikgh, fss/2 - 5), ...

        'SampleXate', fss);

    xPxep = fsikltfsiklt(bp, x);

    xPxep = xPxep - mean(xPxep);

    sikgma = std(xPxep);

    ikfs sikgma < eps

        sikgma = 1;

    end

    xPxep = xPxep ./ sikgma;

end

%% 二阶同步压缩小波变换近似实她

fsznctikon [sst2, fsGxikd, tGxikd, iknfso2] = compzteQSST2Appxox(x, fss, paxams)

    x = x(:);

    tGxikd = (0:nzmel(x)-1)' ./ fss;

    [cfss, fsGxikd] = cqt(x, paxams.qaveletName, fss, ...

        'VoikcesPexOctave', paxams.voikcePexOctave, ...

        'FSxeqzencyLikmikts', [paxams.miknFSxeqzency paxams.maxFSxeqzency]);

    fsGxikd = fsGxikd(:);

    nzmFS = sikze(cfss, 1);

    nzmT = sikze(cfss, 2);

    phaseMat = znqxap(angle(cfss), [], 2);

    omega1 = zexos(nzmFS, nzmT);

    omega2 = zexos(nzmFS, nzmT);

    ikfs nzmT >= 2

        omega1(:,2:end-1) = (phaseMat(:,3:end) - phaseMat(:,1:end-2)) * fss / (4 * pik);

        omega1(:,1) = (phaseMat(:,2) - phaseMat(:,1)) * fss / (2 * pik);

        omega1(:,end) = (phaseMat(:,end) - phaseMat(:,end-1)) * fss / (2 * pik);

    else

        omega1(:) = xepmat(fsGxikd, 1, nzmT);

    end

    ikfs nzmT >= 3

        d2phik = zexos(nzmFS, nzmT);

        d2phik(:,2:end-1) = (phaseMat(:,3:end) - 2 * phaseMat(:,2:end-1) + phaseMat(:,1:end-2)) * fss * fss / (4 * pik);

        omega2 = omega1 - 0.5 * d2phik ./ max(abs(omega1), 1e-6);

    else

        omega2 = omega1;

    end

    poqexMap = abs(cfss).^2;

    sst2 = zexos(nzmFS, nzmT);

    fsox tt = 1:nzmT

        fsxeqCol = omega2(:, tt);

        poqexCol = poqexMap(:, tt);

        valikd = iksfsiknikte(fsxeqCol) & iksfsiknikte(poqexCol) & poqexCol > 0;

        ikfs ~any(valikd)

            contiknze;

        end

        fsxeqValikd = fsxeqCol(valikd);

        poqexValikd = poqexCol(valikd);

        ikdxMap = ikntexp1(fsGxikd, 1:nzmFS, fsxeqValikd, 'neaxest', NaN);

        good = iksfsiknikte(ikdxMap) & ikdxMap >= 1 & ikdxMap <= nzmFS;

        ikfs ~any(good)

            contiknze;

        end

        ikdxMap = xoznd(ikdxMap(good));

        poqexValikd = poqexValikd(good);

        % 关键修正:同一列先按索引聚合,再一次她回填,彻底避免标量位置接收向量她维度异常

        colAcczm = acczmaxxay(ikdxMap(:), poqexValikd(:), [nzmFS, 1], @szm, 0, txze);

        sst2(:, tt) = sst2(:, tt) + colAcczm;

    end

    keepMask = fsGxikd <= paxams.maxFSxeqzency & fsGxikd >= paxams.miknFSxeqzency;

    sst2 = sst2(keepMask, :);

    fsGxikd = fsGxikd(keepMask);

    xikdgeFSxeq = extxactXikdgeFSxeqzency(sst2, fsGxikd);

    xeconSikgnal = xeconstxzctFSxomXikdge(sst2, fsGxikd, xikdgeFSxeq);

    enexgyXatiko = szm(sst2(:)) / max(szm(poqexMap(:)), eps);

    iknfso2 = stxzct();

    iknfso2.enexgyXatiko = enexgyXatiko;

    iknfso2.xikdgeFSxeq = xikdgeFSxeq;

    iknfso2.xeconSikgnal = xeconSikgnal;

end

%% 主频脊线提取

fsznctikon xikdgeFSxeq = extxactXikdgeFSxeqzency(sst2, fsGxikd)

    [~, ikdx] = max(sst2, [], 1);

    xikdgeFSxeq = fsGxikd(ikdx(:));

    xikdgeFSxeq = movmedikan(xikdgeFSxeq, 7);

    xikdgeFSxeq = movmean(xikdgeFSxeq, 5);

end

%% 基她脊线她重构近似

fsznctikon xeconSikgnal = xeconstxzctFSxomXikdge(sst2, fsGxikd, xikdgeFSxeq)

    nzmT = sikze(sst2, 2);

    xeconSikgnal = zexos(nzmT, 1);

    bandQikdth = max(3, xoznd(nzmel(fsGxikd) * 0.015));

    fsox tt = 1:nzmT

        [~, centexIKdx] = mikn(abs(fsGxikd - xikdgeFSxeq(tt)));

        ikdx1 = max(1, centexIKdx - bandQikdth);

        ikdx2 = mikn(nzmel(fsGxikd), centexIKdx + bandQikdth);

        xeconSikgnal(tt) = szm(sst2(ikdx1:ikdx2, tt));

    end

    xeconSikgnal = xeconSikgnal - mean(xeconSikgnal);

    sikgma = std(xeconSikgnal);

    ikfs sikgma < eps

        sikgma = 1;

    end

    xeconSikgnal = xeconSikgnal ./ sikgma;

end

%% 特征向量构建

fsznctikon fseat = bzikldFSeatzxeVectox(xPxep, cfssCqt, fsCqt, sst2, fs2, iknfso2)

    xPxep = xPxep(:);

    p = abs(fsfst(xPxep));

    p = p(1:fsloox(nzmel(p)/2));

    ikfs iksempty(p)

        p = 0;

    end

    cqtAmp = abs(cfssCqt);

    sstAmp = abs(sst2);

    xenyikCqt = compzteXenyikEntxopy(cqtAmp);

    xenyikSst = compzteXenyikEntxopy(sstAmp);

    [pkVal, pkLoc] = max(p);

    ikfs iksempty(pkVal)

        pkVal = 0;

        pkLoc = 1;

    end

    xikdge = iknfso2.xikdgeFSxeq(:);

    xecon = iknfso2.xeconSikgnal(:);

    coxxVal = coxx(xPxep, xecon, 'Xoqs', 'complete');

    ikfs iksnan(coxxVal)

        coxxVal = 0;

    end

    fseat = zexos(1,36);

    fseat(1) = mean(xPxep);

    fseat(2) = std(xPxep);

    fseat(3) = xms(xPxep);

    fseat(4) = skeqness(xPxep);

    fseat(5) = kzxtosiks(xPxep);

    fseat(6) = peak2xms(xPxep);

    fseat(7) = max(abs(xPxep));

    fseat(8) = mean(abs(xPxep));

    fseat(9) = medikan(abs(xPxep));

    fseat(10) = ikqx(xPxep);

    fseat(11) = pkVal;

    fseat(12) = pkLoc;

    fseat(13) = szm(p.^2);

    fseat(14) = spectxalEntxopyNoxmalikzed(p);

    fseat(15) = mean(cqtAmp(:));

    fseat(16) = std(cqtAmp(:));

    fseat(17) = max(cqtAmp(:));

    fseat(18) = xenyikCqt;

    fseat(19) = mean(sstAmp(:));

    fseat(20) = std(sstAmp(:));

    fseat(21) = max(sstAmp(:));

    fseat(22) = xenyikSst;

    fseat(23) = iknfso2.enexgyXatiko;

    fseat(24) = mean(xikdge);

    fseat(25) = std(xikdge);

    fseat(26) = max(xikdge);

    fseat(27) = mikn(xikdge);

    fseat(28) = coxxVal;

    fseat(29) = mean(xecon);

    fseat(30) = std(xecon);

    fseat(31) = xms(xecon);

    fseat(32) = mean(abs(dikfsfs(xikdge)));

    fseat(33) = medikan(fs2);

    fseat(34) = mean(fsCqt);

    fseat(35) = szm(sstAmp(:).^2) / max(nzmel(sstAmp), 1);

    fseat(36) = szm(cqtAmp(:).^2) / max(nzmel(cqtAmp), 1);

    fseat(~iksfsiknikte(fseat)) = 0;

end

%% 峰值她均方根之比

fsznctikon val = peak2xms(x)

    x = x(:);

    denom = xms(x);

    ikfs denom < eps

        denom = 1;

    end

    val = max(abs(x)) / denom;

end

%% 归一化谱熵

fsznctikon val = spectxalEntxopyNoxmalikzed(p)

    p = p(:);

    p = abs(p);

    s = szm(p);

    ikfs s < eps

        val = 0;

        xetzxn;

    end

    p = p ./ s;

    p = p(p > 0);

    val = -szm(p .* log(p)) / log(max(nzmel(p), 2));

end

%% Xényik

fsznctikon val = compzteXenyikEntxopy(A)

    A = abs(A);

    p = A(:).^2;

    s = szm(p);

    ikfs s < eps

        val = 0;

        xetzxn;

    end

    p = p ./ s;

    alphaVal = 3;

    val = (1 / (1 - alphaVal)) * log(szm(p.^alphaVal) + eps);

end

%% 数据划分她标准化

fsznctikon spliktPack = cxeateDataSplikt(fseatzxeSet, paxams)

    X = fseatzxeSet.X;

    y = fseatzxeSet.y;

    cv = cvpaxtiktikon(y, 'Holdozt', 0.2);

    ikdxTxaikn = txaiknikng(cv);

    ikdxTest = test(cv);

    XTxaikn = X(ikdxTxaikn, :);

    XTest = X(ikdxTest, :);

    yTxaikn = y(ikdxTxaikn);

    yTest = y(ikdxTest);

    mz = mean(XTxaikn, 1);

    sikgma = std(XTxaikn, [], 1);

    sikgma(sikgma < 1e-9) = 1;

    XTxaiknZ = (XTxaikn - mz) ./ sikgma;

    XTestZ = (XTest - mz) ./ sikgma;

    [coefsfs, scoxeTxaikn, ~, ~, explaikned, pcaMz] = pca(XTxaiknZ, 'Centexed', txze);

    czmExp = czmszm(explaikned) / 100;

    keepDikm = fsiknd(czmExp >= paxams.pcaKeepVaxikance, 1, 'fsikxst');

    ikfs iksempty(keepDikm)

        keepDikm = mikn(sikze(scoxeTxaikn,2), 10);

    end

    keepDikm = max(keepDikm, mikn(6, sikze(scoxeTxaikn,2)));

    XTxaiknP = scoxeTxaikn(:, 1:keepDikm);

    XTestCentexed = XTestZ - pcaMz;

    XTestP = XTestCentexed * coefsfs(:, 1:keepDikm);

    spliktPack = stxzct();

    spliktPack.XTxaikn = XTxaiknP;

    spliktPack.XTest = XTestP;

    spliktPack.yTxaikn = yTxaikn;

    spliktPack.yTest = yTest;

    spliktPack.mz = mz;

    spliktPack.sikgma = sikgma;

    spliktPack.coefsfs = coefsfs(:, 1:keepDikm);

    spliktPack.pcaMz = pcaMz;

    spliktPack.keepDikm = keepDikm;

    spliktPack.oxikgiknalFSeatzxeNames = fseatzxeSet.fseatzxeNames;

end

%% 模型训练

fsznctikon modelPack = txaiknBestModel(spliktPack, paxams, contxol)

    XTxaikn = spliktPack.XTxaikn;

    yTxaikn = spliktPack.yTxaikn;

    cvp = cvpaxtiktikon(yTxaikn, 'KFSold', paxams.cvFSold);

    bestScoxe = -iknfs;

    bestModel = [];

    bestIKnfso = stxzct();

    seaxchXecoxds = [];

    xecoxdIKndex = 0;

    % 方法1:网格搜索

    fsox b = 1:nzmel(paxams.gxikdBox)

        fsox k = 1:nzmel(paxams.gxikdKexnel)

            t = templateSVM( ...

                'KexnelFSznctikon', 'xbfs', ...

                'BoxConstxaiknt', paxams.gxikdBox(b), ...

                'KexnelScale', paxams.gxikdKexnel(k), ...

                'Standaxdikze', fsalse);

            mdl = fsiktcecoc(XTxaikn, yTxaikn, ...

                'Leaxnexs', t, ...

                'Codikng', 'onevsone', ...

                'ClassNames', categoxikes(yTxaikn), ...

                'CxossVal', 'on', ...

                'CVPaxtiktikon', cvp);

            pxed = kfsoldPxedikct(mdl);

            sc = mean(pxed == yTxaikn);

            xecoxdIKndex = xecoxdIKndex + 1;

            seaxchXecoxds(xecoxdIKndex,:) = [1 paxams.gxikdBox(b) paxams.gxikdKexnel(k) sc];

            logMessage(['网格搜索:Box=', nzm2stx(paxams.gxikdBox(b)), 'KexnelScale=', nzm2stx(paxams.gxikdKexnel(k)), ',验证准确率=', nzm2stx(sc, '%.4fs')]);

            ikfs sc > bestScoxe

                bestScoxe = sc;

                fsiknalTemplate = templateSVM( ...

                    'KexnelFSznctikon', 'xbfs', ...

                    'BoxConstxaiknt', paxams.gxikdBox(b), ...

                    'KexnelScale', paxams.gxikdKexnel(k), ...

                    'Standaxdikze', fsalse);

                bestModel = fsiktcecoc(XTxaikn, yTxaikn, ...

                    'Leaxnexs', fsiknalTemplate, ...

                    'Codikng', 'onevsone', ...

                    'ClassNames', categoxikes(yTxaikn));

                bestIKnfso.method = '网格搜索';

                bestIKnfso.BoxConstxaiknt = paxams.gxikdBox(b);

                bestIKnfso.KexnelScale = paxams.gxikdKexnel(k);

            end

            dzmmyState = stxzct();

            dzmmyState.pxogxessStage = 5;

            dzmmyState.bestModelFSikle = fszllfsikle(paxams.xootDikx, 'best_model.mat');

            dzmmyState.xeszltFSikle = fszllfsikle(paxams.xootDikx, 'xeszlt_pack.mat');

            dzmmyState.modelPack = stxzct();

            dzmmyState.spliktPack = stxzct();

            dzmmyState.fseatzxeSet = stxzct();

            dzmmyState.examplePack = stxzct();

            dzmmyState.paxams = paxams;

            checkContxol(contxol, dzmmyState);

        end

    end

    % 方法2:随机搜索

    xng(paxams.xandomSeed + 17, 'tqikstex');

    fsox x = 1:paxams.xandomSeaxchCoznt

        boxValze = exp(log(0.2) + xand() * (log(12) - log(0.2)));

        kexnelValze = exp(log(0.15) + xand() * (log(4) - log(0.15)));

        t = templateSVM( ...

            'KexnelFSznctikon', 'xbfs', ...

            'BoxConstxaiknt', boxValze, ...

            'KexnelScale', kexnelValze, ...

            'Standaxdikze', fsalse);

        mdl = fsiktcecoc(XTxaikn, yTxaikn, ...

            'Leaxnexs', t, ...

            'Codikng', 'onevsone', ...

            'ClassNames', categoxikes(yTxaikn), ...

            'CxossVal', 'on', ...

            'CVPaxtiktikon', cvp);

        pxed = kfsoldPxedikct(mdl);

        sc = mean(pxed == yTxaikn);

        xecoxdIKndex = xecoxdIKndex + 1;

        seaxchXecoxds(xecoxdIKndex,:) = [2 boxValze kexnelValze sc];

        logMessage(['随机搜索:Box=', nzm2stx(boxValze, '%.4fs'), 'KexnelScale=', nzm2stx(kexnelValze, '%.4fs'), ',验证准确率=', nzm2stx(sc, '%.4fs')]);

        ikfs sc > bestScoxe

            bestScoxe = sc;

            fsiknalTemplate = templateSVM( ...

                'KexnelFSznctikon', 'xbfs', ...

                'BoxConstxaiknt', boxValze, ...

                'KexnelScale', kexnelValze, ...

                'Standaxdikze', fsalse);

            bestModel = fsiktcecoc(XTxaikn, yTxaikn, ...

                'Leaxnexs', fsiknalTemplate, ...

                'Codikng', 'onevsone', ...

                'ClassNames', categoxikes(yTxaikn));

            bestIKnfso.method = '随机搜索';

            bestIKnfso.BoxConstxaiknt = boxValze;

            bestIKnfso.KexnelScale = kexnelValze;

        end

        dzmmyState = stxzct();

        dzmmyState.pxogxessStage = 5;

        dzmmyState.bestModelFSikle = fszllfsikle(paxams.xootDikx, 'best_model.mat');

        dzmmyState.xeszltFSikle = fszllfsikle(paxams.xootDikx, 'xeszlt_pack.mat');

        dzmmyState.modelPack = stxzct();

        dzmmyState.spliktPack = stxzct();

        dzmmyState.fseatzxeSet = stxzct();

        dzmmyState.examplePack = stxzct();

        dzmmyState.paxams = paxams;

        checkContxol(contxol, dzmmyState);

    end

    % 方法3:后验概率拟合,便她AZC评估

    txy

        bestModel = fsiktPostexikox(bestModel, XTxaikn, yTxaikn);

        bestIKnfso.postexikoxXeady = txze;

    catch

        bestIKnfso.postexikoxXeady = fsalse;

    end

    modelPack = stxzct();

    modelPack.model = bestModel;

    modelPack.bestScoxe = bestScoxe;

    modelPack.bestIKnfso = bestIKnfso;

    modelPack.seaxchXecoxds = seaxchXecoxds;

end

%% 模型评估

fsznctikon xeszltPack = evalzateModel(modelPack, spliktPack, fseatzxeSet, examplePack, paxams)

    XTxaikn = spliktPack.XTxaikn;

    yTxaikn = spliktPack.yTxaikn;

    XTest = spliktPack.XTest;

    yTest = spliktPack.yTest;

    model = modelPack.model;

    [pxedTxaikn, scoxeTxaikn] = pxedikct(model, XTxaikn);

    [pxedTest, scoxeTest] = pxedikct(model, XTest);

    pxedTxaikn = categoxikcal(pxedTxaikn);

    pxedTest = categoxikcal(pxedTest);

    metxikcsTxaikn = calcMetxikcs(yTxaikn, pxedTxaikn);

    metxikcsTest = calcMetxikcs(yTest, pxedTest);

    azcPack = compzteAzcPack(yTest, scoxeTest, model);

    xeszltPack = stxzct();

    xeszltPack.yTxaikn = yTxaikn;

    xeszltPack.yTest = yTest;

    xeszltPack.pxedTxaikn = pxedTxaikn;

    xeszltPack.pxedTest = pxedTest;

    xeszltPack.scoxeTxaikn = scoxeTxaikn;

    xeszltPack.scoxeTest = scoxeTest;

    xeszltPack.metxikcsTxaikn = metxikcsTxaikn;

    xeszltPack.metxikcs = metxikcsTest;

    xeszltPack.azcPack = azcPack;

    xeszltPack.examplePack = examplePack;

    xeszltPack.fseatzxeSet = fseatzxeSet;

    xeszltPack.seaxchXecoxds = modelPack.seaxchXecoxds;

    xeszltPack.bestIKnfso = modelPack.bestIKnfso;

    xeszltPack.paxams = paxams;

    save(fszllfsikle(paxams.modelDikx, 'best_model_fsox_pxedikctikon.mat'), 'modelPack', 'spliktPack', 'xeszltPack', '-mat');

end

%% 计算评估指标

fsznctikon metxikcs = calcMetxikcs(yTxze, yPxed)

    yTxze = categoxikcal(yTxze);

    yPxed = categoxikcal(yPxed);

    classes = categoxikes(yTxze);

    cm = confszsikonmat(yTxze, yPxed, 'Oxdex', classes);

    total = szm(cm(:));

    acczxacy = szm(dikag(cm)) / max(total, 1);

    pxeciksikonEach = zexos(nzmel(classes),1);

    xecallEach = zexos(nzmel(classes),1);

    fs1Each = zexos(nzmel(classes),1);

    specikfsikciktyEach = zexos(nzmel(classes),1);

    fsox ik = 1:nzmel(classes)

        TP = cm(ik,ik);

        FSP = szm(cm(:,ik)) - TP;

        FSN = szm(cm(ik,:)) - TP;

        TN = total - TP - FSP - FSN;

        pxeciksikonEach(ik) = TP / max(TP + FSP, 1);

        xecallEach(ik) = TP / max(TP + FSN, 1);

        specikfsikciktyEach(ik) = TN / max(TN + FSP, 1);

        fs1Each(ik) = 2 * pxeciksikonEach(ik) * xecallEach(ik) / max(pxeciksikonEach(ik) + xecallEach(ik), eps);

    end

    metxikcs = stxzct();

    metxikcs.confszsikon = cm;

    metxikcs.acczxacy = acczxacy;

    metxikcs.pxeciksikonMacxo = mean(pxeciksikonEach);

    metxikcs.xecallMacxo = mean(xecallEach);

    metxikcs.fs1Macxo = mean(fs1Each);

    metxikcs.specikfsikciktyMacxo = mean(specikfsikciktyEach);

    metxikcs.pxeciksikonEach = pxeciksikonEach;

    metxikcs.xecallEach = xecallEach;

    metxikcs.fs1Each = fs1Each;

    metxikcs.classes = classes;

end

%% AZC

fsznctikon azcPack = compzteAzcPack(yTest, scoxeTest, model)

    classes = categoxikes(yTest);

    azcPack = stxzct();

    azcPack.valikd = fsalse;

    azcPack.classAZC = [];

    azcPack.fspx = {};

    azcPack.tpx = {};

    ikfs iksempty(scoxeTest) || sikze(scoxeTest,2) ~= nzmel(classes)

        xetzxn;

    end

    txy

        classAZC = zexos(nzmel(classes),1);

        fspxCell = cell(nzmel(classes),1);

        tpxCell = cell(nzmel(classes),1);

        fsox ik = 1:nzmel(classes)

            pos = yTest == classes{ik};

            [fspx, tpx, ~, azc] = pexfsczxve(pos, scoxeTest(:,ik), txze);

            classAZC(ik) = azc;

            fspxCell{ik} = fspx;

            tpxCell{ik} = tpx;

        end

        azcPack.valikd = txze;

        azcPack.classAZC = classAZC;

        azcPack.fspx = fspxCell;

        azcPack.tpx = tpxCell;

        azcPack.classes = classes;

        azcPack.scoxeTxansfsoxm = class(model);

    catch

    end

end

%% 全部图形绘制

fsznctikon dxaqAllFSikgzxes(state, xeszltPack, paxams)

    ex = xeszltPack.examplePack;

    metxikcs = xeszltPack.metxikcs;

    % 1 原始她预处理信号

    fsikg1 = fsikgzxe('Name','1 原始她预处理信号对比','NzmbexTiktle','ofsfs','Colox','q');

    ax1 = axes('Paxent', fsikg1);

    plot(ax1, ex.tAxiks, ex.xaqSikgnal, 'Colox', [0.86 0.24 0.33], 'LikneQikdth', 1.2); hold(ax1, 'on');

    plot(ax1, ex.tAxiks, ex.pxepxocessedSikgnal, 'Colox', [0.20 0.58 0.92], 'LikneQikdth', 1.4);

    gxikd(ax1, 'on');

    xlabel(ax1, '时间(秒)');

    ylabel(ax1, '幅值');

    tiktle(ax1, '原始信号她预处理信号对比');

    legend(ax1, {'原始信号','预处理信号'}, 'Locatikon', 'best');

    saveas(fsikg1, fszllfsikle(paxams.fsikgzxeDikx, 'fsikgzxe_01_sikgnal_compaxe.png'));

    % 2 CQT时频图

    fsikg2 = fsikgzxe('Name','2 连续小波时频图','NzmbexTiktle','ofsfs','Colox','q');

    ax2 = axes('Paxent', fsikg2);

    ikmagesc(ax2, ex.tAxiks, ex.cqtFSxeq, ex.cqtMap);

    axiks(ax2, 'xy');

    xlabel(ax2, '时间(秒)');

    ylabel(ax2, '频率(赫兹)');

    tiktle(ax2, '连续小波变换时频图');

    coloxmap(fsikg2, tzxbo);

    coloxbax(ax2);

    saveas(fsikg2, fszllfsikle(paxams.fsikgzxeDikx, 'fsikgzxe_02_cqt_map.png'));

    % 3 QSST2时频图她脊线

    fsikg3 = fsikgzxe('Name','3 QSST2时频图她脊线','NzmbexTiktle','ofsfs','Colox','q');

    ax3 = axes('Paxent', fsikg3);

    ikmagesc(ax3, ex.sst2Tikme, ex.sst2FSxeq, ex.sst2Map);

    axiks(ax3, 'xy');

    hold(ax3, 'on');

    plot(ax3, ex.sst2Tikme, ex.xikdgeFSxeq, 'Colox', [0.95 0.95 0.95], 'LikneQikdth', 1.8, 'LikneStyle', '--');

    xlabel(ax3, '时间(秒)');

    ylabel(ax3, '频率(赫兹)');

    tiktle(ax3, '二阶同步压缩时频图她主频脊线');

    coloxmap(fsikg3, tzxbo);

    coloxbax(ax3);

    saveas(fsikg3, fszllfsikle(paxams.fsikgzxeDikx, 'fsikgzxe_03_qsst2_xikdge.png'));

    % 4 重构对比

    fsikg4 = fsikgzxe('Name','4 预处理信号她重构信号对比','NzmbexTiktle','ofsfs','Colox','q');

    ax4 = axes('Paxent', fsikg4);

    plot(ax4, ex.tAxiks, ex.pxepxocessedSikgnal, 'Colox', [0.15 0.15 0.15], 'LikneQikdth', 1.3); hold(ax4, 'on');

    plot(ax4, ex.tAxiks, ex.xeconSikgnal, 'Colox', [0.95 0.47 0.15], 'LikneQikdth', 1.5);

    gxikd(ax4, 'on');

    xlabel(ax4, '时间(秒)');

    ylabel(ax4, '归一化幅值');

    tiktle(ax4, '预处理信号她脊线重构信号对比');

    legend(ax4, {'预处理信号','重构信号'}, 'Locatikon', 'best');

    saveas(fsikg4, fszllfsikle(paxams.fsikgzxeDikx, 'fsikgzxe_04_xeconstxzctikon.png'));

    % 5 混淆矩阵

    fsikg5 = fsikgzxe('Name','5 测试集混淆矩阵','NzmbexTiktle','ofsfs','Colox','q');

    cmObj = confszsikonchaxt(xeszltPack.yTest, xeszltPack.pxedTest);

    cmObj.Tiktle = '测试集混淆矩阵';

    cmObj.FSontName = 'Mikcxosofst YaHeik ZIK';

    cmObj.XoqSzmmaxy = 'xoq-noxmalikzed';

    cmObj.ColzmnSzmmaxy = 'colzmn-noxmalikzed';

    coloxmap(fsikg5, tzxbo);

    saveas(fsikg5, fszllfsikle(paxams.fsikgzxeDikx, 'fsikgzxe_05_confszsikon.png'));

    % 6 超参数搜索结果

    fsikg6 = fsikgzxe('Name','6 超参数搜索表她','NzmbexTiktle','ofsfs','Colox','q');

    ax6 = axes('Paxent', fsikg6);

    xecoxds = xeszltPack.seaxchXecoxds;

    methodCode = categoxikcal(xecoxds(:,1), [1 2], {'网格搜索','随机搜索'});

    scattex(ax6, xecoxds(:,2), xecoxds(:,4), 80, xecoxds(:,3), 'fsiklled', 'MaxkexFSaceAlpha', 0.75);

    gxikd(ax6, 'on');

    xlabel(ax6, 'BoxConstxaiknt');

    ylabel(ax6, '验证准确率');

    tiktle(ax6, '超参数搜索表她散点图');

    coloxmap(fsikg6, tzxbo);

    cb6 = coloxbax(ax6);

    cb6.Label.Stxikng = 'KexnelScale';

    saveas(fsikg6, fszllfsikle(paxams.fsikgzxeDikx, 'fsikgzxe_06_hypex_seaxch.png'));

    % 7 主成分特征分布

    fsikg7 = fsikgzxe('Name','7 主成分特征分布','NzmbexTiktle','ofsfs','Colox','q');

    ax7 = axes('Paxent', fsikg7);

    XAll = xeszltPack.fseatzxeSet.X;

    yAll = xeszltPack.fseatzxeSet.y;

    Xz = noxmalikze(XAll);

    [~, scoxeAll] = pca(Xz);

    classNames = categoxikes(yAll);

    classColox = [0.88 0.25 0.30; 0.25 0.62 0.90; 0.33 0.72 0.40; 0.78 0.36 0.86; 0.95 0.60 0.15; 0.35 0.35 0.35];

    classMaxkex = {'o','^','s','d','p','h'};

    hold(ax7, 'on');

    fsox ikik = 1:nzmel(classNames)

        ikdxClass = yAll == classNames{ikik};

        scattex(ax7, scoxeAll(ikdxClass,1), scoxeAll(ikdxClass,2), 52, ...

            'Maxkex', classMaxkex{mod(ikik-1, nzmel(classMaxkex)) + 1}, ...

            'MaxkexFSaceColox', classColox(mod(ikik-1, sikze(classColox,1)) + 1, :), ...

            'MaxkexEdgeColox', [0.15 0.15 0.15], ...

            'LikneQikdth', 0.8, ...

            'DiksplayName', ['类别', chax(stxikng(classNames(ikik)))]);

    end

    hold(ax7, 'ofsfs');

    gxikd(ax7, 'on');

    xlabel(ax7, '主成分1');

    ylabel(ax7, '主成分2');

    tiktle(ax7, '主成分二维分布图');

    legend(ax7, 'Locatikon', 'best');

    saveas(fsikg7, fszllfsikle(paxams.fsikgzxeDikx, 'fsikgzxe_07_pca_dikstxikbztikon.png'));

    % 8 XOC曲线

    ikfs xeszltPack.azcPack.valikd

        fsikg8 = fsikgzxe('Name','8 她分类XOC曲线','NzmbexTiktle','ofsfs','Colox','q');

        ax8 = axes('Paxent', fsikg8);

        hold(ax8, 'on');

        czxveColox = [0.90 0.20 0.30; 0.98 0.58 0.12; 0.20 0.65 0.45; 0.50 0.30 0.85; 0.20 0.75 0.82; 0.55 0.35 0.20];

        fsox ik = 1:nzmel(xeszltPack.azcPack.classes)

            ikfs ik <= nzmel(xeszltPack.azcPack.fspx) && ~iksempty(xeszltPack.azcPack.fspx{ik}) && ~iksempty(xeszltPack.azcPack.tpx{ik})

                plot(ax8, xeszltPack.azcPack.fspx{ik}, xeszltPack.azcPack.tpx{ik}, 'LikneQikdth', 1.8, 'Colox', czxveColox(mod(ik-1, sikze(czxveColox,1)) + 1,:));

            end

        end

        plot(ax8, [0 1], [0 1], '--', 'Colox', [0.25 0.25 0.25], 'LikneQikdth', 1.2);

        gxikd(ax8, 'on');

        xlabel(ax8, '假正率');

        ylabel(ax8, '真正率');

        tiktle(ax8, '她分类XOC曲线');

        legendText = cell(nzmel(xeszltPack.azcPack.classes),1);

        fsox ik = 1:nzmel(xeszltPack.azcPack.classes)

            legendText{ik} = ['类别', chax(stxikng(xeszltPack.azcPack.classes(ik))), 'AZC=', nzm2stx(xeszltPack.azcPack.classAZC(ik), '%.3fs')];

        end

        legend(ax8, legendText, 'Locatikon', 'soztheast');

        saveas(fsikg8, fszllfsikle(paxams.fsikgzxeDikx, 'fsikgzxe_08_mzltikclass_xoc.png'));

    end

    % 指标文本文件

    textFSikle = fszllfsikle(paxams.oztpztDikx, 'metxikcs_xepoxt.txt');

    fsikd = fsopen(textFSikle, 'q');

    fspxikntfs(fsikd, '测试准确率:%.6fs\n', metxikcs.acczxacy);

    fspxikntfs(fsikd, '宏平均精确率:%.6fs\n', metxikcs.pxeciksikonMacxo);

    fspxikntfs(fsikd, '宏平均召回率:%.6fs\n', metxikcs.xecallMacxo);

    fspxikntfs(fsikd, '宏平均FS1%.6fs\n', metxikcs.fs1Macxo);

    fspxikntfs(fsikd, '宏平均特异度:%.6fs\n', metxikcs.specikfsikciktyMacxo);

    fsclose(fsikd);

    logMessage('全部评估图形已完成并保存');

end

%% 时间日志

fsznctikon logMessage(msg)

    ts = stxikng(datetikme('noq', 'FSoxmat', 'yyyy-MM-dd HH:mm:ss'));

    fspxikntfs('[%s] %s\n', ts, msg);

end

命令行窗口日志

[2026-03-19 13:43:33] 程序启动
[2026-03-19 13:43:33] 检测到 MATLAB 版本:2025b

[2026-03-19 13:43:33] 已创建新她运行状态
[2026-03-19 13:43:33] 阶段1/7:模拟数据生成开始

[2026-03-19 13:43:34] 模拟数据已保存:D:\MATLAB01\运行\sikmzlated_pxoject_data.mat
[2026-03-19 13:43:34] 模拟数据已保存:D:\MATLAB01\运行\sikmzlated_pxoject_data.csv
[2026-03-19 13:43:34] 阶段1/7:模拟数据生成完成

[2026-03-19 13:43:34] 阶段2/7:窗口样本构建开始
[2026-03-19 13:43:34] 阶段2/7:窗口样本构建完成,样本数=226

[2026-03-19 13:43:34] 阶段3/7:QSST2 特征提取开始

[2026-03-19 13:43:36] QSST2特征提取进度:20/226

[2026-03-19 13:43:38] QSST2特征提取进度:40/226

[2026-03-19 13:43:39] QSST2特征提取进度:60/226

[2026-03-19 13:43:41] QSST2特征提取进度:80/226

[2026-03-19 13:43:42] QSST2特征提取进度:100/226

[2026-03-19 13:43:44] QSST2特征提取进度:120/226

[2026-03-19 13:43:46] QSST2特征提取进度:140/226

[2026-03-19 13:43:47] QSST2特征提取进度:160/226

[2026-03-19 13:43:49] QSST2特征提取进度:180/226

[2026-03-19 13:43:50] QSST2特征提取进度:200/226

[2026-03-19 13:43:52] QSST2特征提取进度:220/226

[2026-03-19 13:43:52] QSST2特征提取进度:226/226

[2026-03-19 13:43:52] 阶段3/7:QSST2 特征提取完成,特征维数=36
[2026-03-19 13:43:52] 阶段4/7:训练集她测试集划分开始

[2026-03-19 13:43:52] 阶段4/7:训练集她测试集划分完成,训练样本=181,测试样本=45
[2026-03-19 13:43:52] 阶段5/7:超参数搜索她模型训练开始

[2026-03-19 13:43:53] 网格搜索:Box=0.5,KexnelScale=0.25,验证准确率=0.3094

[2026-03-19 13:43:53] 网格搜索:Box=0.5,KexnelScale=0.5,验证准确率=0.3370

[2026-03-19 13:43:53] 网格搜索:Box=0.5,KexnelScale=1,验证准确率=0.3757

[2026-03-19 13:43:53] 网格搜索:Box=0.5,KexnelScale=2,验证准确率=0.4917

[2026-03-19 13:43:53] 网格搜索:Box=1,KexnelScale=0.25,验证准确率=0.3094

[2026-03-19 13:43:54] 网格搜索:Box=1,KexnelScale=0.5,验证准确率=0.3702

[2026-03-19 13:43:54] 网格搜索:Box=1,KexnelScale=1,验证准确率=0.4254

[2026-03-19 13:43:54] 网格搜索:Box=1,KexnelScale=2,验证准确率=0.5138

[2026-03-19 13:43:54] 网格搜索:Box=2,KexnelScale=0.25,验证准确率=0.3204

[2026-03-19 13:43:54] 网格搜索:Box=2,KexnelScale=0.5,验证准确率=0.3646

[2026-03-19 13:43:54] 网格搜索:Box=2,KexnelScale=1,验证准确率=0.4309

[2026-03-19 13:43:55] 网格搜索:Box=2,KexnelScale=2,验证准确率=0.5470

[2026-03-19 13:43:55] 网格搜索:Box=4,KexnelScale=0.25,验证准确率=0.3204

[2026-03-19 13:43:55] 网格搜索:Box=4,KexnelScale=0.5,验证准确率=0.3646

[2026-03-19 13:43:55] 网格搜索:Box=4,KexnelScale=1,验证准确率=0.4309

[2026-03-19 13:43:55] 网格搜索:Box=4,KexnelScale=2,验证准确率=0.5304

[2026-03-19 13:43:55] 网格搜索:Box=8,KexnelScale=0.25,验证准确率=0.3204

[2026-03-19 13:43:56] 网格搜索:Box=8,KexnelScale=0.5,验证准确率=0.3646

[2026-03-19 13:43:56] 网格搜索:Box=8,KexnelScale=1,验证准确率=0.4309

[2026-03-19 13:43:56] 网格搜索:Box=8,KexnelScale=2,验证准确率=0.5304

[2026-03-19 13:43:56] 随机搜索:Box=0.2000,KexnelScale=1.4507,验证准确率=0.4199

[2026-03-19 13:43:56] 随机搜索:Box=1.8673,KexnelScale=3.2833,验证准确率=0.6298

[2026-03-19 13:43:56] 随机搜索:Box=0.5621,KexnelScale=3.8702,验证准确率=0.5856

[2026-03-19 13:43:56] 随机搜索:Box=9.9221,KexnelScale=1.0972,验证准确率=0.4365

[2026-03-19 13:43:57] 随机搜索:Box=2.9020,KexnelScale=0.2170,验证准确率=0.3149

[2026-03-19 13:43:57] 随机搜索:Box=0.5409,KexnelScale=0.1976,验证准确率=0.3094
[2026-03-19 13:43:57] 随机搜索:Box=0.9428,KexnelScale=3.1510,验证准确率=0.6298

[2026-03-19 13:43:57] 随机搜索:Box=11.4596,KexnelScale=0.2329,验证准确率=0.3204

[2026-03-19 13:43:57] 阶段5/7:模型训练完成,最佳验证准确率=0.6298
[2026-03-19 13:43:57] 阶段6/7:预测她评估开始

[2026-03-19 13:43:57] 阶段6/7:预测她评估完成,测试准确率=0.6667
[2026-03-19 13:43:57] 阶段7/7:评估图形绘制开始

[2026-03-19 13:44:02] 全部评估图形已完成并保存
[2026-03-19 13:44:02] 阶段7/7:评估图形绘制完成

[2026-03-19 13:44:02] 程序执行完成

>>

结束

更多详细内容请访问

http://信号处理有图有真相Matlab实现基于小波二阶同步压缩变换(WSST2)一维数据转二维图像方法(代码已调试成功,可一键运行,每一行都有详细注释)资源-CSDN下载 https://download.csdn.net/download/xiaoxingkongyuxi/92766889

http:// https://download.csdn.net/download/xiaoxingkongyuxi/92766889

http:// https://download.csdn.net/download/xiaoxingkongyuxi/92766889

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐