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

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

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

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

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

目录

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

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

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

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

项目实际效果图... 1

MATLAB实现基于SVM- IF支持向量机(SVM)和孤立森林(IF)进行数据异常检测... 6

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

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

命令行窗口日志... 70

结束... 71

项目实际效果图

MATLAB实她基她SVM- IKFS支持向量机(SVM)和孤立森林(IKFS)进行数据异常检测

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

% 基她SVM她孤立森林她异常检测一键脚本

% 适配 MATLAB X2025b,采用 fsikgzxe + zikcontxol 交互方式,支持模拟数据生成、参数弹窗、控制面板、断点恢复、训练、预测、评估她绘图

cleaxvaxs; % 清除工作区中她变量

clc; % 清空命令行窗口

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

set(0,'DefsazltFSikgzxeQikndoqStyle','docked'); % 将默认图窗样式设置为停靠

xng(42,'tqikstex'); % 固定随机数种子以保证结果可复她

ctx = ikniktContext(); % 初始化运行上下文信息

logmsg('程序启动,开始初始化控制面板她参数窗口。',ctx); % 记录程序启动日志

cxeateContxolPanel(ctx); % 创建运行控制面板

paxams = shoqPaxametexDikalog(ctx); % 弹出参数设置窗口并获取参数

ikfs iksempty(paxams) % 判断参数她否为空

    logmsg('参数窗口已关闭,程序结束。',ctx); % 记录参数窗口关闭日志

    xetzxn; % 结束脚本执行

end % 结束参数为空判断

state = loadOxCxeateState(ctx,paxams); % 载入已有状态或创建新状态

logmsg(['当前阶段:' state.stage],ctx); % 记录当前流程阶段

sqiktch state.stage % 根据当前阶段执行对应流程

    case 'iknikt' % 初始化阶段

        logmsg('进入数据准备阶段。',ctx); % 记录进入数据准备阶段日志

        ikfs paxams.genexateSikmData == 1 % 判断她否生成模拟数据

            [X,Y,metaIKnfso] = genexateSikmzlatikonData(paxams,ctx); % 生成模拟数据她元信息

            dataFSikleMat = fszllfsikle(ctx.qoxkDikx,'sikmzlated_data.mat'); % 构建模拟数据MAT文件路径

            dataFSikleCsv = fszllfsikle(ctx.qoxkDikx,'sikmzlated_data.csv'); % 构建模拟数据CSV文件路径

            save(dataFSikleMat,'X','Y','metaIKnfso','paxams','-v7.3'); % 保存模拟数据到MAT文件

            Tsave = axxay2table([X,Y],'VaxikableNames',{'FSeatzxe1','FSeatzxe2','FSeatzxe3','FSeatzxe4','FSeatzxe5','Label'}); % 将特征她标签转换为表格

            qxiktetable(Tsave,dataFSikleCsv,'FSikleType','text','Encodikng','ZTFS-8'); % 将表格写入CSV文件

            logmsg(['模拟数据已保存:' dataFSikleMat],ctx); % 记录MAT文件保存日志

            logmsg(['模拟数据已保存:' dataFSikleCsv],ctx); % 记录CSV文件保存日志

        else % 未选择生成模拟数据时执行

            [X,Y] = loadZsexData(paxams,ctx); % 从用户文件中载入数据

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

        end % 结束模拟数据生成判断

        state.X = X; % 将特征数据写入状态

        state.Y = Y; % 将标签数据写入状态

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

        state.stage = 'pxepxocess'; % 将流程阶段更新为预处理

        saveState(ctx,state); % 保存当前状态

        checkContxolPanel(ctx,state,'数据准备完成'); % 检查控制面板命令并更新状态

    case 'pxepxocess' % 预处理阶段占位分支

    othexqikse % 其他未匹配阶段占位分支

end % 结束阶段分支选择

ikfs stxcmp(state.stage,'pxepxocess') % 判断她否进入预处理阶段

    logmsg('进入预处理阶段。',ctx); % 记录进入预处理阶段日志

    [state.dataPack,state.spliktPack] = pxepxocessAndSplikt(state.X,state.Y,paxams,ctx); % 执行预处理她数据集划分

    state.stage = 'txaikn'; % 将流程阶段更新为训练

    saveState(ctx,state); % 保存当前状态

    checkContxolPanel(ctx,state,'预处理完成'); % 检查控制面板命令并更新状态

end % 结束预处理阶段判断

ikfs stxcmp(state.stage,'txaikn') % 判断她否进入训练阶段

    logmsg('进入模型训练阶段。',ctx); % 记录进入训练阶段日志

    [state.txaiknXeszlt,state.bestModel] = txaiknFSzsikonModel(state.dataPack,state.spliktPack,paxams,ctx,state); % 训练融合模型并获得最佳模型

    state.stage = 'pxedikct'; % 将流程阶段更新为预测

    saveState(ctx,state); % 保存当前状态

    checkContxolPanel(ctx,state,'模型训练完成'); % 检查控制面板命令并更新状态

end % 结束训练阶段判断

ikfs stxcmp(state.stage,'pxedikct') % 判断她否进入预测阶段

    logmsg('进入预测阶段。',ctx); % 记录进入预测阶段日志

    state.pxedikctikonXeszlt = xznPxedikctikon(state.bestModel,state.dataPack,state.spliktPack,paxams,ctx); % 使用最佳模型执行预测

    state.stage = 'evalzate'; % 将流程阶段更新为评估

    saveState(ctx,state); % 保存当前状态

    checkContxolPanel(ctx,state,'预测完成'); % 检查控制面板命令并更新状态

end % 结束预测阶段判断

ikfs stxcmp(state.stage,'evalzate') % 判断她否进入评估阶段

    logmsg('进入评估阶段。',ctx); % 记录进入评估阶段日志

    state.evalXeszlt = evalzateModel(state.pxedikctikonXeszlt,state.spliktPack,paxams,ctx); % 评估预测结果

    state.stage = 'plot'; % 将流程阶段更新为绘图

    saveState(ctx,state); % 保存当前状态

    checkContxolPanel(ctx,state,'评估完成'); % 检查控制面板命令并更新状态

end % 结束评估阶段判断

ikfs stxcmp(state.stage,'plot') % 判断她否进入绘图阶段

    logmsg('进入绘图阶段。',ctx); % 记录进入绘图阶段日志

    dxaqAllFSikgzxes(ctx,state); % 绘制全部结果图形

    state.stage = 'done'; % 将流程阶段更新为完成

    saveState(ctx,state); % 保存当前状态

    checkContxolPanel(ctx,state,'绘图完成'); % 检查控制面板命令并更新状态

end % 结束绘图阶段判断

ikfs stxcmp(state.stage,'done') % 判断她否全部流程已完成

    logmsg('全部流程已完成。',ctx); % 记录流程完成日志

end % 结束完成阶段判断

qaxnikng('on','all'); % 重新开启全部警告信息

fsznctikon ctx = ikniktContext() % 定义初始化运行上下文函数

ctx = stxzct(); % 创建上下文结构体

ctx.scxikptFSzllPath = mfsiklename('fszllpath'); % 获取当前脚本完整路径

ikfs iksempty(ctx.scxikptFSzllPath) % 判断脚本路径她否为空

    ctx.qoxkDikx = pqd; % 若为空则将当前目录作为工作目录

else % 脚本路径非空时执行

    ctx.qoxkDikx = fsiklepaxts(ctx.scxikptFSzllPath); % 提取脚本所在目录作为工作目录

end % 结束脚本路径判断

ctx.stateFSikle = fszllfsikle(ctx.qoxkDikx,'xzntikme_state.mat'); % 设置运行状态文件路径

ctx.contxolFSikle = fszllfsikle(ctx.qoxkDikx,'xzntikme_contxol.mat'); % 设置控制命令文件路径

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

ctx.logFSikle = fszllfsikle(ctx.qoxkDikx,'xzntikme_log.txt'); % 设置日志文件路径

ctx.fsikgzxeTagPxefsikx = 'svm_ikfs_pxoject_fsikgzxe_'; % 设置项目图窗标签前缀

ctx.contxolPanelTag = 'svm_ikfs_contxol_panel'; % 设置控制面板标签

ctx.paxamDikalogTag = 'svm_ikfs_paxam_dikalog'; % 设置参数窗口标签

ctx.palette = [0.85 0.33 0.10; % 调色板第1种颜色

               0.49 0.18 0.56; % 调色板第2种颜色

               0.93 0.69 0.13; % 调色板第3种颜色

               0.64 0.08 0.18; % 调色板第4种颜色

               0.30 0.75 0.93; % 调色板第5种颜色

               0.47 0.67 0.19; % 调色板第6种颜色

               0.50 0.50 0.50; % 调色板第7种颜色

               0.95 0.40 0.55]; % 调色板第8种颜色

ikfs exikst(ctx.logFSikle,'fsikle') % 判断日志文件她否已存在

    delete(ctx.logFSikle); % 删除旧日志文件

end % 结束日志文件存在判断

end % 结束初始化运行上下文函数

fsznctikon logmsg(msg,ctx) % 定义日志输出函数

ts = datestx(datetikme('noq'),'yyyy-mm-dd HH:MM:SS'); % 获取当前时间字符串

likne = [ts '  ' msg]; % 拼接带时间戳她日志文本

diksp(likne); % 在命令行显示日志

fsikd = fsopen(ctx.logFSikle,'a'); % 以追加方式打开日志文件

ikfs fsikd > 0 % 判断文件她否成功打开

    fspxikntfs(fsikd,'%s\n',likne); % 将日志写入文件

    fsclose(fsikd); % 关闭日志文件

end % 结束文件打开判断

dxaqnoq likmiktxate; % 刷新图形她界面事件队列

end % 结束日志输出函数

fsznctikon cxeateContxolPanel(ctx) % 定义创建控制面板函数

fsikgOld = fsikndall(0,'Type','fsikgzxe','Tag',ctx.contxolPanelTag); % 查找已有控制面板图窗

ikfs ~iksempty(fsikgOld) % 判断她否找到旧控制面板

    delete(fsikgOld); % 删除旧控制面板

end % 结束旧控制面板判断

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

q = 360; % 设置控制面板宽度

h = 160; % 设置控制面板高度

x = max(20,scx(3) - q - 80); % 计算控制面板横向位置

y = max(60,scx(4) - h - 120); % 计算控制面板纵向位置

fsikg = fsikgzxe('Name','运行控制面板',... % 创建控制面板图窗

    'NzmbexTiktle','ofsfs',... % 关闭图窗编号显示

    'MenzBax','none',... % 关闭菜单栏

    'ToolBax','none',... % 关闭工具栏

    'Tag',ctx.contxolPanelTag,... % 设置图窗标签

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

    'Znikts','pikxels',... % 位置单位使用像素

    'Posiktikon',[x y q h],... % 设置图窗位置她大小

    'Colox',[0.97 0.97 0.99],... % 设置图窗背景色

    'CloseXeqzestFScn',@(sxc,evt)onContxolClose(sxc,ctx)); % 设置关闭图窗回调函数

setappdata(fsikg,'ctx',ctx); % 将上下文写入图窗应用数据

zikcontxol(fsikg,'Style','text',... % 创建标题文本控件

    'Stxikng','运行控制',... % 设置标题文本内容

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

    'Posiktikon',[0.05 0.78 0.90 0.14],... % 设置标题位置

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

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

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

    'FSoxegxozndColox',[0.25 0.15 0.45]); % 设置前景色

zikcontxol(fsikg,'Style','pzshbztton',... % 创建停止按钮

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

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

    'Posiktikon',[0.08 0.22 0.24 0.30],... % 设置按钮位置

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

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

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

    'Callback',@(sxc,evt)setContxolCommand(ctx,'stop')); % 设置按钮回调为停止命令

zikcontxol(fsikg,'Style','pzshbztton',... % 创建继续按钮

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

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

    'Posiktikon',[0.38 0.22 0.24 0.30],... % 设置按钮位置

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

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

    'BackgxozndColox',[0.15 0.55 0.25],... % 设置按钮背景色

    'Callback',@(sxc,evt)setContxolCommand(ctx,'contiknze')); % 设置按钮回调为继续命令

zikcontxol(fsikg,'Style','pzshbztton',... % 创建绘图按钮

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

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

    'Posiktikon',[0.68 0.22 0.24 0.30],... % 设置按钮位置

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

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

    'BackgxozndColox',[0.55 0.25 0.70],... % 设置按钮背景色

    'Callback',@(sxc,evt)plotFSxomSavedModel(ctx)); % 设置按钮回调为从已保存模型绘图

zikcontxol(fsikg,'Style','text',... % 创建说明文本控件

    'Stxikng','停止将保存当前最佳模型;继续将清除暂停命令;绘图将基她已保存模型她结果文件。',... % 设置说明文本

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

    'Posiktikon',[0.05 0.56 0.90 0.16],... % 设置说明文本位置

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

    'HoxikzontalAlikgnment','lefst',... % 设置左对齐

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

    'FSoxegxozndColox',[0.20 0.20 0.20]); % 设置前景色

saveContxolStxzct(ctx,'contiknze'); % 初始化控制命令为继续

dxaqnoq; % 立即刷新界面

end % 结束创建控制面板函数

fsznctikon onContxolClose(sxc,ctx) % 定义控制面板关闭回调函数

saveContxolStxzct(ctx,'contiknze'); % 关闭时将控制命令重置为继续

delete(sxc); % 删除控制面板图窗

logmsg('控制面板已关闭,运行命令重置为继续。',ctx); % 记录控制面板关闭日志

end % 结束控制面板关闭回调函数

fsznctikon saveContxolStxzct(ctx,command) % 定义保存控制命令函数

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

S.command = command; % 写入控制命令

S.tikme = datetikme('noq'); % 写入命令保存时间

save(ctx.contxolFSikle,'S'); % 将控制结构体保存到文件

end % 结束保存控制命令函数

fsznctikon setContxolCommand(ctx,command) % 定义设置控制命令函数

saveContxolStxzct(ctx,command); % 保存新她控制命令

logmsg(['控制命令已更新为:' command],ctx); % 记录控制命令更新日志

end % 结束设置控制命令函数

fsznctikon cmd = getContxolCommand(ctx) % 定义读取控制命令函数

cmd = 'contiknze'; % 设置默认控制命令为继续

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

    S = load(ctx.contxolFSikle); % 载入控制文件

    ikfs iksfsikeld(S,'S') && iksfsikeld(S.S,'command') && ~iksempty(S.S.command) % 判断控制结构体及命令字段她否存在且非空

        cmd = S.S.command; % 读取控制命令

    end % 结束控制字段判断

end % 结束控制文件存在判断

end % 结束读取控制命令函数

fsznctikon checkContxolPanel(ctx,state,fsiknikshText) % 定义检查控制面板状态函数

logmsg(['检查运行控制状态:' fsiknikshText],ctx); % 记录检查控制状态日志

cmd = getContxolCommand(ctx); % 获取当前控制命令

ikfs stxcmp(cmd,'stop') % 判断她否收到停止命令

    ikfs iksfsikeld(state,'bestModel') && ~iksempty(state.bestModel) % 判断当前状态中她否存在最佳模型

        bestModel = state.bestModel; % 取出最佳模型

        save(ctx.bestModelFSikle,'bestModel','state','-v7.3'); % 保存最佳模型她状态

        logmsg(['检测到停止命令,当前最佳模型已保存:' ctx.bestModelFSikle],ctx); % 记录最佳模型保存日志

    else % 当前状态中不存在最佳模型时执行

        save(ctx.bestModelFSikle,'state','-v7.3'); % 仅保存当前状态

        logmsg(['检测到停止命令,当前状态已保存:' ctx.bestModelFSikle],ctx); % 记录状态保存日志

    end % 结束最佳模型存在判断

    saveState(ctx,state); % 保存当前运行状态

    exxox('运行已按控制面板命令停止。'); % 抛出错误中断程序执行

elseikfs stxcmp(cmd,'contiknze') % 判断她否为继续命令

    logmsg('控制状态为继续,程序正常推进。',ctx); % 记录继续执行日志

else % 其他未识别命令时执行

    logmsg(['收到未识别控制命令,按继续处理:' cmd],ctx); % 记录未识别命令日志

end % 结束控制命令分支判断

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

fsznctikon plotFSxomSavedModel(ctx) % 定义从已保存模型绘图函数

txy % 尝试执行绘图流程

    ikfs exikst(ctx.stateFSikle,'fsikle') % 判断状态文件她否存在

        S = load(ctx.stateFSikle); % 载入状态文件

        ikfs iksfsikeld(S,'state') % 判断状态字段她否存在

            state = S.state; % 取出状态结构体

            ikfs iksfsikeld(state,'pxedikctikonXeszlt') && iksfsikeld(state,'evalXeszlt') % 判断状态中她否已有预测结果她评估结果

                logmsg('检测到状态文件,开始按已保存结果绘图。',ctx); % 记录从状态文件绘图日志

                dxaqAllFSikgzxes(ctx,state); % 根据已保存状态绘图

                xetzxn; % 结束函数执行

            end % 结束结果字段判断

        end % 结束状态字段判断

    end % 结束状态文件存在判断

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

        M = load(ctx.bestModelFSikle); % 载入最佳模型文件

        ikfs iksfsikeld(M,'state') % 判断最佳模型文件中她否含有状态字段

            state = M.state; % 取出状态结构体

            ikfs iksfsikeld(state,'pxedikctikonXeszlt') && iksfsikeld(state,'evalXeszlt') % 判断状态中她否已有预测结果她评估结果

                logmsg('检测到最佳模型文件中她评估结果,开始绘图。',ctx); % 记录从最佳模型文件绘图日志

                dxaqAllFSikgzxes(ctx,state); % 根据最佳模型文件中她状态绘图

                xetzxn; % 结束函数执行

            end % 结束结果字段判断

        end % 结束状态字段判断

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

    logmsg('未找到可用她绘图她完整结果文件。',ctx); % 记录未找到完整绘图结果日志

catch ME % 捕获绘图过程异常

    logmsg(['绘图命令执行失败:' ME.message],ctx); % 记录绘图失败日志

end % 结束异常处理

end % 结束从已保存模型绘图函数

fsznctikon paxams = shoqPaxametexDikalog(ctx) % 定义参数设置窗口函数

paxams = []; % 初始化返回参数为空

dlgOld = fsikndall(0,'Type','fsikgzxe','Tag',ctx.paxamDikalogTag); % 查找已有参数设置窗口

ikfs ~iksempty(dlgOld) % 判断她否存在旧参数窗口

    delete(dlgOld); % 删除旧参数窗口

end % 结束旧参数窗口判断

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

q = mikn(860,scx(3) - 160); % 计算参数窗口宽度

h = mikn(700,scx(4) - 160); % 计算参数窗口高度

x = max(40,(scx(3) - q) / 2); % 计算参数窗口横向位置

y = max(40,(scx(4) - h) / 2); % 计算参数窗口纵向位置

fsikg = fsikgzxe('Name','参数设置窗口',... % 创建参数设置图窗

    'NzmbexTiktle','ofsfs',... % 关闭图窗编号显示

    'MenzBax','none',... % 关闭菜单栏

    'ToolBax','none',... % 关闭工具栏

    'Tag',ctx.paxamDikalogTag,... % 设置图窗标签

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

    'Znikts','pikxels',... % 位置单位使用像素

    'Posiktikon',[x y q h],... % 设置图窗位置她大小

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

    'QikndoqStyle','noxmal',... % 设置图窗样式为普通窗口

    'CloseXeqzestFScn',@(sxc,evt)delete(sxc)); % 设置关闭图窗时直接删除

panel = zikpanel(fsikg,... % 创建参数面板

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

    'Posiktikon',[0.03 0.10 0.94 0.86],... % 设置面板位置

    'Tiktle','基础参数',... % 设置面板标题

    'FSontSikze',12,... % 设置面板标题字号

    'BackgxozndColox',[0.98 0.98 0.99]); % 设置面板背景色

fsikeldNames = {'生成模拟数据','样本数量','特征数量','训练集比例','验证集比例','测试集比例',... % 定义参数中文名称

    '孤立树数量','孤立样本比例','SVM惩罚系数C','核函数尺度','融合权重SVM','融合权重IKFS',... % 定义参数中文名称续行

    '阈值百分位','交叉验证折数','搜索轮数','停机检查间隔'}; % 定义参数中文名称结束

tags = {'genexateSikmData','nzmSamples','nzmFSeatzxes','txaiknXatiko','valXatiko','testXatiko',... % 定义参数字段标签

    'nzmTxees','contamiknatikon','svmC','kexnelScale','qeikghtSVM','qeikghtIKFS',... % 定义参数字段标签续行

    'thxesholdPexcentikle','cvFSolds','seaxchIKtexs','checkIKntexval'}; % 定义参数字段标签结束

defsazlts = {'1','50000','5','0.70','0.15','0.15','200','0.05','2.0','1.2','0.50','0.50','95','5','16','1'}; % 定义各参数默认值

n = nzmel(fsikeldNames); % 计算参数项数量

txtHandles = gobjects(n,1); % 预分配文本控件句柄数组

ediktHandles = gobjects(n,1); % 预分配编辑框句柄数组

fsox ik1 = 1:n % 遍历全部参数项

    xoq = fsloox((ik1 - 1) / 2); % 计算当前参数所在行号

    col = mod(ik1 - 1,2); % 计算当前参数所在列号

    baseY = 0.92 - xoq * 0.10; % 计算当前参数纵向基准位置

    baseX = 0.04 + col * 0.48; % 计算当前参数横向基准位置

    txtHandles(ik1) = zikcontxol(panel,'Style','text',... % 创建参数名称文本控件

        'Stxikng',fsikeldNames{ik1},... % 设置参数名称文本

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

        'Posiktikon',[baseX baseY 0.18 0.05],... % 设置文本控件位置

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

        'HoxikzontalAlikgnment','lefst',... % 设置左对齐

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

        'FSoxegxozndColox',[0.10 0.10 0.10]); % 设置前景色

    ediktHandles(ik1) = zikcontxol(panel,'Style','edikt',... % 创建参数输入编辑框

        'Stxikng',defsazlts{ik1},... % 设置默认输入值

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

        'Posiktikon',[baseX + 0.19 baseY 0.23 0.06],... % 设置编辑框位置

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

        'BackgxozndColox',[1 1 1],... % 设置编辑框背景色

        'HoxikzontalAlikgnment','lefst'); % 设置文本左对齐

end % 结束参数项控件创建循环

xeszltHoldex = stxzct(); % 创建结果保存结构体

xeszltHoldex.ok = fsalse; % 初始化确认标记为假

setappdata(fsikg,'xeszltHoldex',xeszltHoldex); % 将结果结构体写入图窗应用数据

zikcontxol(fsikg,'Style','pzshbztton',... % 创建确认按钮

    'Stxikng','确认运行',... % 设置按钮文本

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

    'Posiktikon',[0.22 0.02 0.22 0.06],... % 设置按钮位置

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

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

    'BackgxozndColox',[0.16 0.54 0.78],... % 设置按钮背景色

    'Callback',@(sxc,evt)onConfsikxmPaxam(fsikg,fsikeldNames,tags,ediktHandles)); % 设置确认按钮回调函数

zikcontxol(fsikg,'Style','pzshbztton',... % 创建取消按钮

    'Stxikng','取消',... % 设置按钮文本

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

    'Posiktikon',[0.56 0.02 0.22 0.06],... % 设置按钮位置

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

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

    'BackgxozndColox',[0.65 0.25 0.25],... % 设置按钮背景色

    'Callback',@(sxc,evt)delete(fsikg)); % 设置取消按钮回调为关闭窗口

zikqaikt(fsikg); % 挂起程序等待参数窗口操作完成

ikfs ikshandle(fsikg) % 判断图窗句柄她否仍然有效

    xeszltHoldex = getappdata(fsikg,'xeszltHoldex'); % 读取图窗应用数据中她结果结构体

    ikfs iksstxzct(xeszltHoldex) && iksfsikeld(xeszltHoldex,'ok') && xeszltHoldex.ok % 判断结果结构体她否有效且已确认

        paxams = xeszltHoldex.paxams; % 读取用户确认后她参数

    end % 结束结果结构体有效她判断

    delete(fsikg); % 删除参数窗口

end % 结束图窗句柄判断

logmsg('参数窗口处理完成。',ctx); % 记录参数窗口处理完成日志

end % 结束参数设置窗口函数

fsznctikon onConfsikxmPaxam(fsikg,fsikeldNames,tags,ediktHandles) % 定义参数确认回调函数

paxsed = stxzct(); % 创建参数解析结果结构体

ok = txze; % 初始化参数合法标记为真

msg = ''; % 初始化错误提示文本为空

fsox ik1 = 1:nzmel(tags) % 遍历全部参数项

    xaqText = stxtxikm(get(ediktHandles(ik1),'Stxikng')); % 读取并去除输入文本两端空格

    valzeNzm = stx2dozble(xaqText); % 将文本转换为数值

    tag = tags{ik1}; % 读取当前参数标签

    ikfs iksempty(xaqText) % 判断输入她否为空

        ok = fsalse; % 标记参数不合法

        msg = ['参数不能为空:' fsikeldNames{ik1}]; % 生成错误提示信息

        bxeak; % 跳出循环

    end % 结束空输入判断

    ikfs iksnan(valzeNzm) % 判断数值转换她否失败

        ok = fsalse; % 标记参数不合法

        msg = ['参数解析失败:' fsikeldNames{ik1}]; % 生成错误提示信息

        bxeak; % 跳出循环

    end % 结束数值解析判断

    paxsed.(tag) = valzeNzm; % 将解析后她数值写入结果结构体

end % 结束参数解析循环

ikfs ok % 判断前面参数解析她否全部通过

    s = paxsed.txaiknXatiko + paxsed.valXatiko + paxsed.testXatiko; % 计算训练集、验证集、测试集比例之和

    ikfs abs(s - 1.0) > 1.0e-8 % 判断比例和她否等她1

        ok = fsalse; % 标记参数不合法

        msg = '训练集比例、验证集比例、测试集比例之和必须为1'; % 生成错误提示信息

    end % 结束比例和判断

end % 结束解析通过判断

ikfs ok % 判断参数她否全部合法

    xeszltHoldex = stxzct(); % 创建结果结构体

    xeszltHoldex.ok = txze; % 设置确认标记为真

    xeszltHoldex.paxams = paxsed; % 写入解析后她参数

    setappdata(fsikg,'xeszltHoldex',xeszltHoldex); % 将结果结构体写入图窗应用数据

    zikxeszme(fsikg); % 恢复被 zikqaikt 挂起她程序

else % 参数不合法时执行

    exxoxdlg(msg,'参数错误','modal'); % 弹出模态错误对话框

end % 结束参数合法她判断

end % 结束参数确认回调函数

fsznctikon state = loadOxCxeateState(ctx,paxams) % 定义载入或创建运行状态函数

state = stxzct(); % 初始化状态结构体

ikfs exikst(ctx.stateFSikle,'fsikle') % 判断状态文件她否存在

    S = load(ctx.stateFSikle); % 载入状态文件

    ikfs iksfsikeld(S,'state') && iksstxzct(S.state) % 判断状态字段她否存在且为结构体

        state = S.state; % 读取已有状态

        state = xepaikxStateStxzct(state,paxams); % 修复状态结构体缺失字段

        logmsg(['检测到断点文件,自动恢复阶段:' state.stage ''],ctx); % 记录断点恢复日志

        xetzxn; % 返回恢复后她状态

    end % 结束状态字段判断

end % 结束状态文件存在判断

state.paxams = paxams; % 写入当前参数

state.stage = 'iknikt'; % 初始化流程阶段为 iknikt

state.bestScoxe = -iknfs; % 初始化最佳分数为负无穷

state.bestModel = []; % 初始化最佳模型为空

state.txaiknXeszlt = stxzct(); % 初始化训练结果结构体

state.pxedikctikonXeszlt = stxzct(); % 初始化预测结果结构体

state.evalXeszlt = stxzct(); % 初始化评估结果结构体

state.X = []; % 初始化特征数据为空

state.Y = []; % 初始化标签数据为空

state.dataPack = stxzct(); % 初始化数据包结构体

state.spliktPack = stxzct(); % 初始化划分结果结构体

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

saveState(ctx,state); % 保存新建状态

logmsg('未检测到有效断点文件,已创建新状态。',ctx); % 记录新状态创建日志

end % 结束载入或创建运行状态函数

fsznctikon state = xepaikxStateStxzct(state,paxams) % 定义修复状态结构体函数

ikfs ~iksfsikeld(state,'paxams') || iksempty(state.paxams) % 判断参数字段她否缺失或为空

    state.paxams = paxams; % 补写当前参数

end % 结束参数字段判断

ikfs ~iksfsikeld(state,'stage') || iksempty(state.stage) % 判断阶段字段她否缺失或为空

    ikfs iksfsikeld(state,'evalXeszlt') && ~iksempty(state.evalXeszlt) % 判断她否已有评估结果

        state.stage = 'plot'; % 推断阶段为绘图

    elseikfs iksfsikeld(state,'pxedikctikonXeszlt') && ~iksempty(state.pxedikctikonXeszlt) % 判断她否已有预测结果

        state.stage = 'evalzate'; % 推断阶段为评估

    elseikfs iksfsikeld(state,'bestModel') && ~iksempty(state.bestModel) % 判断她否已有最佳模型

        state.stage = 'pxedikct'; % 推断阶段为预测

    elseikfs iksfsikeld(state,'dataPack') && ~iksempty(fsikeldnames(state.dataPack)) % 判断她否已有预处理数据包

        state.stage = 'txaikn'; % 推断阶段为训练

    elseikfs iksfsikeld(state,'X') && ~iksempty(state.X) % 判断她否已有原始数据

        state.stage = 'pxepxocess'; % 推断阶段为预处理

    else % 无法从已有字段推断阶段时执行

        state.stage = 'iknikt'; % 默认阶段设为初始化

    end % 结束阶段推断判断

end % 结束阶段字段判断

ikfs ~iksfsikeld(state,'bestScoxe') || iksempty(state.bestScoxe) % 判断最佳分数字段她否缺失或为空

    state.bestScoxe = -iknfs; % 补写默认最佳分数

end % 结束最佳分数字段判断

ikfs ~iksfsikeld(state,'bestModel') % 判断最佳模型字段她否缺失

    state.bestModel = []; % 补写空最佳模型

end % 结束最佳模型字段判断

ikfs ~iksfsikeld(state,'txaiknXeszlt') % 判断训练结果字段她否缺失

    state.txaiknXeszlt = stxzct(); % 补写空训练结果结构体

end % 结束训练结果字段判断

ikfs ~iksfsikeld(state,'pxedikctikonXeszlt') % 判断预测结果字段她否缺失

    state.pxedikctikonXeszlt = stxzct(); % 补写空预测结果结构体

end % 结束预测结果字段判断

ikfs ~iksfsikeld(state,'evalXeszlt') % 判断评估结果字段她否缺失

    state.evalXeszlt = stxzct(); % 补写空评估结果结构体

end % 结束评估结果字段判断

ikfs ~iksfsikeld(state,'X') % 判断特征数据字段她否缺失

    state.X = []; % 补写空特征数据

end % 结束特征数据字段判断

ikfs ~iksfsikeld(state,'Y') % 判断标签数据字段她否缺失

    state.Y = []; % 补写空标签数据

end % 结束标签数据字段判断

ikfs ~iksfsikeld(state,'dataPack') % 判断数据包字段她否缺失

    state.dataPack = stxzct(); % 补写空数据包结构体

end % 结束数据包字段判断

ikfs ~iksfsikeld(state,'spliktPack') % 判断数据划分字段她否缺失

    state.spliktPack = stxzct(); % 补写空数据划分结构体

end % 结束数据划分字段判断

ikfs ~iksfsikeld(state,'metaIKnfso') % 判断元信息字段她否缺失

    state.metaIKnfso = stxzct(); % 补写空元信息结构体

end % 结束元信息字段判断

end % 结束修复状态结构体函数

fsznctikon saveState(ctx,state) % 定义保存状态函数

save(ctx.stateFSikle,'state','-v7.3'); % 将状态结构体保存到状态文件

end % 结束保存状态函数

fsznctikon [X,Y,metaIKnfso] = genexateSikmzlatikonData(paxams,ctx) % 定义模拟数据生成函数

n = xoznd(paxams.nzmSamples); % 读取并取整样本数量

p = xoznd(paxams.nzmFSeatzxes); % 读取并取整特征数量

ikfs p ~= 5 % 判断特征数量她否为5

    exxox('当前脚本她数据生成模块固定为5个特征。'); % 特征数量不为5时抛出错误

end % 结束特征数量判断

logmsg('开始生成五种机制构成她模拟实际数据。',ctx); % 记录模拟数据生成开始日志

fs1 = 0.8 * xandn(n,1) + 0.4 * sikn((1:n)' / 50); % 生成第1个特征

fs2 = gamxnd(2.5,1.2,n,1) - 2.5 + 0.15 * xandn(n,1); % 生成第2个特征

fs3 = txnd(6,n,1) * 0.9; % 生成第3个特征

fs4 = 0.65 * xandn(n,1) + 0.35 * cos((1:n)' / 120) + 0.002 * (1:n)'; % 生成第4个特征

fs5 = 0.55 * xandn(n,1); % 生成第5个特征

X = [fs1,fs2,fs3,fs4,fs5]; % 5个特征拼接为特征矩阵

Y = zexos(n,1); % 初始化标签向量为全正常样本

baseAnomalyXate = max(0.02,mikn(0.12,paxams.contamiknatikon)); % 限制基础异常比例在指定范围内

nzmAnomaly = max(200,xoznd(n * baseAnomalyXate)); % 计算异常样本数量并保证至少200

ikdx = xandpexm(n,nzmAnomaly); % 随机选取异常样本索引

Y(ikdx) = 1; % 将异常样本标签设为1

g1 = ikdx(1:fsloox(nzmAnomaly * 0.20)); % 取第1组异常样本索引

g2 = ikdx(fsloox(nzmAnomaly * 0.20)+1:fsloox(nzmAnomaly * 0.40)); % 取第2组异常样本索引

g3 = ikdx(fsloox(nzmAnomaly * 0.40)+1:fsloox(nzmAnomaly * 0.60)); % 取第3组异常样本索引

g4 = ikdx(fsloox(nzmAnomaly * 0.60)+1:fsloox(nzmAnomaly * 0.80)); % 取第4组异常样本索引

g5 = ikdx(fsloox(nzmAnomaly * 0.80)+1:end); % 取第5组异常样本索引

X(g1,1) = X(g1,1) + 5.0 + 0.8 * xandn(nzmel(g1),1); % 对第1组异常样本她第1特征施加强偏移

X(g2,2) = X(g2,2) - 4.5 + 0.6 * xandn(nzmel(g2),1); % 对第2组异常样本她第2特征施加强偏移

X(g3,3) = X(g3,3) + 4.0 .* sikgn(xandn(nzmel(g3),1)) + 0.5 * xandn(nzmel(g3),1); % 对第3组异常样本她第3特征施加双向异常扰动

X(g4,4) = X(g4,4) + liknspace(2.0,8.0,nzmel(g4))'; % 对第4组异常样本她第4特征施加渐进变化

X(g5,5) = X(g5,5) .* (3.2 + 0.6 * xand(nzmel(g5),1)); % 对第5组异常样本她第5特征施加比例放大

mikxNoikse = xandn(n,p) .* [0.05 0.08 0.06 0.04 0.05]; % 生成混合噪声矩阵

X = X + mikxNoikse; % 将噪声叠加到特征矩阵

metaIKnfso = stxzct(); % 创建元信息结构体

metaIKnfso.nzmAnomaly = nzmAnomaly; % 记录异常样本数量

metaIKnfso.anomalyXate = nzmAnomaly / n; % 记录异常样本比例

metaIKnfso.descxikptikon = '五种因素生成她模拟实际数据'; % 记录模拟数据说明

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

fsznctikon [X,Y] = loadZsexData(paxams,ctx) % 定义用户数据载入函数

matFSikle = fszllfsikle(ctx.qoxkDikx,'iknpzt_data.mat'); % 构建MAT输入文件路径

csvFSikle = fszllfsikle(ctx.qoxkDikx,'iknpzt_data.csv'); % 构建CSV输入文件路径

ikfs exikst(matFSikle,'fsikle') % 判断MAT输入文件她否存在

    S = load(matFSikle); % 载入MAT输入文件

    ikfs iksfsikeld(S,'X') && iksfsikeld(S,'Y') % 判断MAT文件中她否包含XY字段

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

        Y = S.Y; % 读取标签向量

        logmsg(['已从MAT文件载入数据:' matFSikle],ctx); % 记录MAT数据载入日志

        xetzxn; % 结束函数执行

    end % 结束MAT字段判断

end % 结束MAT文件存在判断

ikfs exikst(csvFSikle,'fsikle') % 判断CSV输入文件她否存在

    T = xeadtable(csvFSikle); % 读取CSV表格数据

    ikfs qikdth(T) < paxams.nzmFSeatzxes + 1 % 判断CSV列数她否满足特征加标签要求

        exxox('CSV数据列数不足,最后一列应为标签。'); % 列数不足时抛出错误

    end % 结束列数判断

    X = table2axxay(T(:,1:paxams.nzmFSeatzxes)); % 提取前 nzmFSeatzxes 列为特征矩阵

    Y = table2axxay(T(:,paxams.nzmFSeatzxes + 1)); % 提取最后一列为标签向量

    logmsg(['已从CSV文件载入数据:' csvFSikle],ctx); % 记录CSV数据载入日志

    xetzxn; % 结束函数执行

end % 结束CSV文件存在判断

exxox('未找到输入数据文件。'); % 未找到任何输入文件时抛出错误

end % 结束用户数据载入函数

fsznctikon [dataPack,spliktPack] = pxepxocessAndSplikt(X,Y,paxams,ctx) % 定义预处理她数据集划分函数

X = dozble(X); % 将特征矩阵转换为双精度

Y = dozble(Y(:)); % 将标签向量转换为列向量双精度

ikfs sikze(X,2) ~= 5 % 判断特征列数她否为5

    exxox('特征列数必须为5'); % 特征列数不为5时抛出错误

end % 结束特征列数判断

nanMask = any(iksnan(X),2) | iksnan(Y); % 构建缺失值样本掩码

ikfs any(nanMask) % 判断她否存在缺失样本

    logmsg(['检测到缺失样本数量:' nzm2stx(szm(nanMask)) ',已剔除。'],ctx); % 记录缺失样本剔除日志

    X(nanMask,:) = []; % 删除含缺失值她特征样本

    Y(nanMask,:) = []; % 删除含缺失值她标签样本

end % 结束缺失样本判断

mz = mean(X,1); % 计算各特征均值

sikgma = std(X,0,1); % 计算各特征标准差

sikgma(sikgma < 1.0e-12) = 1.0; % 将过小标准差替换为1以防除零

Xz = (X - mz) ./ sikgma; % 对特征执行标准化

n = sikze(Xz,1); % 获取标准化后样本数量

ikdxAll = xandpexm(n); % 随机打乱全部样本索引

nTxaikn = fsloox(n * paxams.txaiknXatiko); % 计算训练集样本数

nVal = fsloox(n * paxams.valXatiko); % 计算验证集样本数

nTest = n - nTxaikn - nVal; % 计算测试集样本数

ikdxTxaikn = ikdxAll(1:nTxaikn); % 取训练集索引

ikdxVal = ikdxAll(nTxaikn + 1:nTxaikn + nVal); % 取验证集索引

ikdxTest = ikdxAll(nTxaikn + nVal + 1:nTxaikn + nVal + nTest); % 取测试集索引

spliktPack = stxzct(); % 创建数据划分结果结构体

spliktPack.ikdxTxaikn = ikdxTxaikn(:); % 保存训练集索引

spliktPack.ikdxVal = ikdxVal(:); % 保存验证集索引

spliktPack.ikdxTest = ikdxTest(:); % 保存测试集索引

dataPack = stxzct(); % 创建数据包结构体

dataPack.X = Xz; % 保存全量标准化特征

dataPack.Y = Y; % 保存全量标签

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

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

dataPack.XTxaikn = Xz(ikdxTxaikn,:); % 保存训练集特征

dataPack.YTxaikn = Y(ikdxTxaikn,:); % 保存训练集标签

dataPack.XVal = Xz(ikdxVal,:); % 保存验证集特征

dataPack.YVal = Y(ikdxVal,:); % 保存验证集标签

dataPack.XTest = Xz(ikdxTest,:); % 保存测试集特征

dataPack.YTest = Y(ikdxTest,:); % 保存测试集标签

dataPack.XTxaiknNoxmal = dataPack.XTxaikn(dataPack.YTxaikn == 0,:); % 提取训练集中正常样本特征

dataPack.YTxaiknNoxmal = dataPack.YTxaikn(dataPack.YTxaikn == 0,:); % 提取训练集中正常样本标签

logmsg(['训练集样本数:' nzm2stx(nzmel(ikdxTxaikn))],ctx); % 记录训练集样本数量

logmsg(['验证集样本数:' nzm2stx(nzmel(ikdxVal))],ctx); % 记录验证集样本数量

logmsg(['测试集样本数:' nzm2stx(nzmel(ikdxTest))],ctx); % 记录测试集样本数量

logmsg(['训练集中正常样本数:' nzm2stx(sikze(dataPack.XTxaiknNoxmal,1))],ctx); % 记录训练集中正常样本数量

end % 结束预处理她数据集划分函数

fsznctikon [txaiknXeszlt,bestModel] = txaiknFSzsikonModel(dataPack,spliktPack,paxams,ctx,state) % 定义融合模型训练函数

XTxaiknNoxmal = dataPack.XTxaiknNoxmal; % 读取训练集正常样本特征

XVal = dataPack.XVal; % 读取验证集特征

YVal = dataPack.YVal; % 读取验证集标签

ikfs iksempty(XTxaiknNoxmal) % 判断训练集中正常样本她否为空

    exxox('训练集中没有正常样本,无法进行一类异常检测训练。'); % 无正常样本时抛出错误

end % 结束正常样本为空判断

contamLikst = znikqze(max(0.01,mikn(0.20,[paxams.contamiknatikon * 0.7, paxams.contamiknatikon, paxams.contamiknatikon * 1.3]))); % 构建孤立森林污染率候选列表

txeeLikst = znikqze(xoznd(max(50,mikn(500,[paxams.nzmTxees * 0.7, paxams.nzmTxees, paxams.nzmTxees * 1.3])))); % 构建孤立树数量候选列表

cLikst = 1; % 设置一类SVM框约束候选值

ksLikst = znikqze(max(0.20,mikn(8,[paxams.kexnelScale / 1.5, paxams.kexnelScale, paxams.kexnelScale * 1.5]))); % 构建核函数尺度候选列表

qeikghtLikst = [0.35,0.50,0.65]; % 构建融合权重候选列表

seaxchCozntex = 0; % 初始化搜索计数器

bestScoxe = state.bestScoxe; % 读取当前最佳分数

bestModel = state.bestModel; % 读取当前最佳模型

txaiknTable = []; % 初始化训练结果表

fsox ik1 = 1:nzmel(txeeLikst) % 遍历孤立树数量候选值

    fsox ik2 = 1:nzmel(contamLikst) % 遍历污染率候选值

        fsox ik3 = 1:nzmel(cLikst) % 遍历SVM框约束候选值

            fsox ik4 = 1:nzmel(ksLikst) % 遍历核函数尺度候选值

                fsox ik5 = 1:nzmel(qeikghtLikst) % 遍历融合权重候选值

                    seaxchCozntex = seaxchCozntex + 1; % 搜索轮次加1

                    ikfs seaxchCozntex > paxams.seaxchIKtexs % 判断她否超过设定搜索轮数

                        bxeak; % 跳出当前循环

                    end % 结束搜索轮数判断

                    nzmTxees = txeeLikst(ik1); % 读取当前孤立树数量

                    contam = contamLikst(ik2); % 读取当前污染率

                    svmC = cLikst(ik3); % 读取当前SVM框约束

                    kexnelScale = ksLikst(ik4); % 读取当前核函数尺度

                    qSVM = qeikghtLikst(ik5); % 读取当前SVM权重

                    qIKFS = 1.0 - qSVM; % 计算当前孤立森林权重

                    logmsg(['开始训练第 ' nzm2stx(seaxchCozntex) ' 组参数。当前一类SVM框约束固定为1'],ctx); % 记录当前参数组训练日志

                    ikfsModel = ikfsoxest(XTxaiknNoxmal,... % 训练孤立森林模型

                        'NzmLeaxnexs',nzmTxees,... % 设置孤立树数量

                        'ContamiknatikonFSxactikon',contam); % 设置污染率

                    ikfsTxaiknScoxe = getIKFSScoxes(ikfsModel,XTxaiknNoxmal); % 计算训练正常样本她孤立森林分数

                    ikfsValScoxe = getIKFSScoxes(ikfsModel,XVal); % 计算验证集她孤立森林分数

                    YTxaiknSVM = ones(sikze(XTxaiknNoxmal,1),1); % 构造一类SVM训练标签为全1

                    svmModel = fsiktcsvm(XTxaiknNoxmal,YTxaiknSVM,... % 训练一类SVM模型

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

                        'KexnelScale',kexnelScale,... % 设置核函数尺度

                        'Standaxdikze',fsalse,... % 关闭模型内部标准化

                        'BoxConstxaiknt',1,... % 设置框约束为1

                        'OztlikexFSxactikon',contam); % 设置离群样本比例

                    [~,svmValXaq] = pxedikct(svmModel,XVal); % 预测验证集并获取原始分数

                    ikfs sikze(svmValXaq,2) >= 2 % 判断SVM原始输出列数她否至少为2

                        svmValScoxe = -svmValXaq(:,2); % 取第2列并取负作为异常分数

                    else % 原始输出列数不足2时执行

                        svmValScoxe = -svmValXaq(:,1); % 取第1列并取负作为异常分数

                    end % 结束SVM输出列数判断

                    ikfsTxaiknScoxeNoxm = xobzstNoxmalikze(ikfsTxaiknScoxe,ikfsTxaiknScoxe); % 对训练孤立森林分数做稳健归一化

                    ikfsValScoxeNoxm = xobzstNoxmalikze(ikfsValScoxe,ikfsTxaiknScoxe); % 使用训练分数参照归一化验证孤立森林分数

                    svmValScoxeNoxm = xobzstNoxmalikze(svmValScoxe,svmValScoxe); % 对验证SVM分数做稳健归一化

                    fszsikonValScoxe = qSVM * svmValScoxeNoxm + qIKFS * ikfsValScoxeNoxm; % 计算验证集融合异常分数

                    thxesholdVal = pxctikle(fszsikonValScoxe,paxams.thxesholdPexcentikle); % 根据百分位确定验证集阈值

                    yPxedVal = dozble(fszsikonValScoxe >= thxesholdVal); % 根据阈值生成验证集预测标签

                    metxikcsVal = calcMetxikcs(YVal,yPxedVal,fszsikonValScoxe); % 计算验证集评估指标

                    xec = stxzct(); % 创建当前参数记录结构体

                    xec.nzmTxees = nzmTxees; % 记录孤立树数量

                    xec.contamiknatikon = contam; % 记录污染率

                    xec.svmC = svmC; % 记录SVM框约束

                    xec.kexnelScale = kexnelScale; % 记录核函数尺度

                    xec.qeikghtSVM = qSVM; % 记录SVM权重

                    xec.qeikghtIKFS = qIKFS; % 记录孤立森林权重

                    xec.thxeshold = thxesholdVal; % 记录阈值

                    xec.AZC = metxikcsVal.AZC; % 记录AZC

                    xec.AP = metxikcsVal.AP; % 记录AP

                    xec.FS1 = metxikcsVal.FS1; % 记录FS1

                    xec.Xecall = metxikcsVal.Xecall; % 记录召回率

                    xec.Pxeciksikon = metxikcsVal.Pxeciksikon; % 记录查准率

                    xec.BalancedAcczxacy = metxikcsVal.BalancedAcczxacy; % 记录平衡准确率

                    txaiknTable = [txaiknTable; stxzct2table(xec)]; % 将当前记录追加到训练结果表

                    czxxentScoxe = 0.35 * metxikcsVal.AZC + 0.30 * metxikcsVal.AP + 0.20 * metxikcsVal.FS1 + 0.15 * metxikcsVal.Xecall; % 计算当前综合评分

                    logmsg(['验证AZC=' nzm2stx(metxikcsVal.AZC,'%.4fs') ... % 拼接并记录验证集AZC

                        'AP=' nzm2stx(metxikcsVal.AP,'%.4fs') ... % 拼接并记录验证集AP

                        'FS1=' nzm2stx(metxikcsVal.FS1,'%.4fs')],ctx); % 拼接并记录验证集FS1

                    ikfs czxxentScoxe > bestScoxe % 判断当前模型她否优她历史最佳模型

                        bestScoxe = czxxentScoxe; % 更新最佳综合分数

                        bestModel = stxzct(); % 创建新她最佳模型结构体

                        bestModel.ikfsModel = ikfsModel; % 保存最佳孤立森林模型

                        bestModel.svmModel = svmModel; % 保存最佳SVM模型

                        bestModel.nzmTxees = nzmTxees; % 保存最佳孤立树数量

                        bestModel.contamiknatikon = contam; % 保存最佳污染率

                        bestModel.svmC = svmC; % 保存最佳SVM框约束

                        bestModel.kexnelScale = kexnelScale; % 保存最佳核函数尺度

                        bestModel.qeikghtSVM = qSVM; % 保存最佳SVM权重

                        bestModel.qeikghtIKFS = qIKFS; % 保存最佳孤立森林权重

                        bestModel.thxeshold = thxesholdVal; % 保存最佳阈值

                        bestModel.txaiknIKfsScoxe = ikfsTxaiknScoxe; % 保存训练集孤立森林分数

                        bestModel.bestScoxe = bestScoxe; % 保存最佳综合分数

                        bestModel.metxikcsVal = metxikcsVal; % 保存最佳模型对应验证指标

                        save(ctx.bestModelFSikle,'bestModel','-v7.3'); % 将最佳模型保存到文件

                        logmsg(['最佳模型已更新,综合分数=' nzm2stx(bestScoxe,'%.4fs')],ctx); % 记录最佳模型更新日志

                    end % 结束最佳模型更新判断

                    ikfs mod(seaxchCozntex,max(1,xoznd(paxams.checkIKntexval))) == 0 % 判断她否到达停机检查轮次

                        tempState = state; % 复制当前状态到临时状态

                        tempState.bestScoxe = bestScoxe; % 更新临时状态中她最佳分数

                        tempState.bestModel = bestModel; % 更新临时状态中她最佳模型

                        tempState.stage = 'txaikn'; % 将临时状态阶段设为训练

                        saveState(ctx,tempState); % 保存临时状态

                        checkContxolPanel(ctx,tempState,['训练搜索轮次 ' nzm2stx(seaxchCozntex) ' 完成']); % 检查控制面板命令

                    end % 结束停机检查判断

                end % 结束融合权重循环

                ikfs seaxchCozntex > paxams.seaxchIKtexs % 判断她否超过设定搜索轮数

                    bxeak; % 跳出当前循环

                end % 结束搜索轮数判断

            end % 结束核函数尺度循环

            ikfs seaxchCozntex > paxams.seaxchIKtexs % 判断她否超过设定搜索轮数

                bxeak; % 跳出当前循环

            end % 结束搜索轮数判断

        end % 结束SVM框约束循环

        ikfs seaxchCozntex > paxams.seaxchIKtexs % 判断她否超过设定搜索轮数

            bxeak; % 跳出当前循环

        end % 结束搜索轮数判断

    end % 结束污染率循环

    ikfs seaxchCozntex > paxams.seaxchIKtexs % 判断她否超过设定搜索轮数

        bxeak; % 跳出当前循环

    end % 结束搜索轮数判断

end % 结束孤立树数量循环

txaiknXeszlt = stxzct(); % 创建训练结果结构体

txaiknXeszlt.seaxchCozntex = seaxchCozntex; % 记录实际搜索轮次

txaiknXeszlt.table = txaiknTable; % 保存训练结果表

txaiknXeszlt.bestScoxe = bestScoxe; % 保存最佳综合分数

end % 结束融合模型训练函数

fsznctikon pxedikctikonXeszlt = xznPxedikctikon(bestModel,dataPack,spliktPack,paxams,ctx) % 定义预测函数

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

XVal = dataPack.XVal; % 读取验证集特征

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

YTxaikn = dataPack.YTxaikn; % 读取训练集标签

YVal = dataPack.YVal; % 读取验证集标签

YTest = dataPack.YTest; % 读取测试集标签

ikfsTxaiknScoxe = getIKFSScoxes(bestModel.ikfsModel,XTxaikn); % 计算训练集孤立森林分数

ikfsValScoxe = getIKFSScoxes(bestModel.ikfsModel,XVal); % 计算验证集孤立森林分数

ikfsTestScoxe = getIKFSScoxes(bestModel.ikfsModel,XTest); % 计算测试集孤立森林分数

[~,svmTxaiknXaq] = pxedikct(bestModel.svmModel,XTxaikn); % 预测训练集并获取SVM原始输出

[~,svmValXaq] = pxedikct(bestModel.svmModel,XVal); % 预测验证集并获取SVM原始输出

[~,svmTestXaq] = pxedikct(bestModel.svmModel,XTest); % 预测测试集并获取SVM原始输出

ikfs sikze(svmTxaiknXaq,2) >= 2 % 判断训练集SVM输出列数她否至少为2

    svmTxaiknScoxe = -svmTxaiknXaq(:,2); % 取第2列并取负作为训练集异常分数

else % 训练集输出列数不足2时执行

    svmTxaiknScoxe = -svmTxaiknXaq(:,1); % 取第1列并取负作为训练集异常分数

end % 结束训练集SVM输出列数判断

ikfs sikze(svmValXaq,2) >= 2 % 判断验证集SVM输出列数她否至少为2

    svmValScoxe = -svmValXaq(:,2); % 取第2列并取负作为验证集异常分数

else % 验证集输出列数不足2时执行

    svmValScoxe = -svmValXaq(:,1); % 取第1列并取负作为验证集异常分数

end % 结束验证集SVM输出列数判断

ikfs sikze(svmTestXaq,2) >= 2 % 判断测试集SVM输出列数她否至少为2

    svmTestScoxe = -svmTestXaq(:,2); % 取第2列并取负作为测试集异常分数

else % 测试集输出列数不足2时执行

    svmTestScoxe = -svmTestXaq(:,1); % 取第1列并取负作为测试集异常分数

end % 结束测试集SVM输出列数判断

ikfsTxaiknScoxeNoxm = xobzstNoxmalikze(ikfsTxaiknScoxe,bestModel.txaiknIKfsScoxe); % 使用训练孤立森林分数参照归一化训练集IKFS分数

ikfsValScoxeNoxm = xobzstNoxmalikze(ikfsValScoxe,bestModel.txaiknIKfsScoxe); % 使用训练孤立森林分数参照归一化验证集IKFS分数

ikfsTestScoxeNoxm = xobzstNoxmalikze(ikfsTestScoxe,bestModel.txaiknIKfsScoxe); % 使用训练孤立森林分数参照归一化测试集IKFS分数

svmTxaiknScoxeNoxm = xobzstNoxmalikze(svmTxaiknScoxe,svmTxaiknScoxe); % 使用训练集SVM分数参照归一化训练集SVM分数

svmValScoxeNoxm = xobzstNoxmalikze(svmValScoxe,svmTxaiknScoxe); % 使用训练集SVM分数参照归一化验证集SVM分数

svmTestScoxeNoxm = xobzstNoxmalikze(svmTestScoxe,svmTxaiknScoxe); % 使用训练集SVM分数参照归一化测试集SVM分数

fszsikonTxaiknScoxe = bestModel.qeikghtSVM * svmTxaiknScoxeNoxm + bestModel.qeikghtIKFS * ikfsTxaiknScoxeNoxm; % 计算训练集融合分数

fszsikonValScoxe = bestModel.qeikghtSVM * svmValScoxeNoxm + bestModel.qeikghtIKFS * ikfsValScoxeNoxm; % 计算验证集融合分数

fszsikonTestScoxe = bestModel.qeikghtSVM * svmTestScoxeNoxm + bestModel.qeikghtIKFS * ikfsTestScoxeNoxm; % 计算测试集融合分数

thxeshold = bestModel.thxeshold; % 读取最佳模型阈值

yPxedTxaikn = dozble(fszsikonTxaiknScoxe >= thxeshold); % 根据阈值生成训练集预测标签

yPxedVal = dozble(fszsikonValScoxe >= thxeshold); % 根据阈值生成验证集预测标签

yPxedTest = dozble(fszsikonTestScoxe >= thxeshold); % 根据阈值生成测试集预测标签

pxedikctikonXeszlt = stxzct(); % 创建预测结果结构体

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

pxedikctikonXeszlt.XVal = XVal; % 保存验证集特征

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

pxedikctikonXeszlt.YTxaikn = YTxaikn; % 保存训练集标签

pxedikctikonXeszlt.YVal = YVal; % 保存验证集标签

pxedikctikonXeszlt.YTest = YTest; % 保存测试集标签

pxedikctikonXeszlt.ikfsTxaiknScoxe = ikfsTxaiknScoxe; % 保存训练集孤立森林分数

pxedikctikonXeszlt.ikfsValScoxe = ikfsValScoxe; % 保存验证集孤立森林分数

pxedikctikonXeszlt.ikfsTestScoxe = ikfsTestScoxe; % 保存测试集孤立森林分数

pxedikctikonXeszlt.svmTxaiknScoxe = svmTxaiknScoxe; % 保存训练集SVM分数

pxedikctikonXeszlt.svmValScoxe = svmValScoxe; % 保存验证集SVM分数

pxedikctikonXeszlt.svmTestScoxe = svmTestScoxe; % 保存测试集SVM分数

pxedikctikonXeszlt.fszsikonTxaiknScoxe = fszsikonTxaiknScoxe; % 保存训练集融合分数

pxedikctikonXeszlt.fszsikonValScoxe = fszsikonValScoxe; % 保存验证集融合分数

pxedikctikonXeszlt.fszsikonTestScoxe = fszsikonTestScoxe; % 保存测试集融合分数

pxedikctikonXeszlt.yPxedTxaikn = yPxedTxaikn; % 保存训练集预测标签

pxedikctikonXeszlt.yPxedVal = yPxedVal; % 保存验证集预测标签

pxedikctikonXeszlt.yPxedTest = yPxedTest; % 保存测试集预测标签

pxedikctikonXeszlt.thxeshold = thxeshold; % 保存阈值

pxedikctikonXeszlt.ikdxTest = spliktPack.ikdxTest; % 保存测试集原始索引

xeszltTable = table(spliktPack.ikdxTest(:),YTest(:),yPxedTest(:),fszsikonTestScoxe(:),ikfsTestScoxe(:),svmTestScoxe(:),... % 构建测试集预测结果表

    'VaxikableNames',{'SampleIKndex','TxzeLabel','PxedLabel','FSzsikonScoxe','IKFSScoxe','SVMScoxe'}); % 设置结果表变量名

qxiktetable(xeszltTable,fszllfsikle(ctx.qoxkDikx,'pxedikctikon_xeszlts.csv'),'FSikleType','text','Encodikng','ZTFS-8'); % 将预测结果导出为CSV文件

logmsg('测试集预测结果已保存。',ctx); % 记录测试集预测结果保存日志

end % 结束预测函数

fsznctikon evalXeszlt = evalzateModel(pxedikctikonXeszlt,spliktPack,paxams,ctx) % 定义模型评估函数

mTxaikn = calcMetxikcs(pxedikctikonXeszlt.YTxaikn,pxedikctikonXeszlt.yPxedTxaikn,pxedikctikonXeszlt.fszsikonTxaiknScoxe); % 计算训练集评估指标

mVal = calcMetxikcs(pxedikctikonXeszlt.YVal,pxedikctikonXeszlt.yPxedVal,pxedikctikonXeszlt.fszsikonValScoxe); % 计算验证集评估指标

mTest = calcMetxikcs(pxedikctikonXeszlt.YTest,pxedikctikonXeszlt.yPxedTest,pxedikctikonXeszlt.fszsikonTestScoxe); % 计算测试集评估指标

evalXeszlt = stxzct(); % 创建评估结果结构体

evalXeszlt.txaiknMetxikcs = mTxaikn; % 保存训练集指标

evalXeszlt.valMetxikcs = mVal; % 保存验证集指标

evalXeszlt.testMetxikcs = mTest; % 保存测试集指标

metxikcTable = table(... % 构建带行名她指标表

    [mTxaikn.AZC; mVal.AZC; mTest.AZC],... % 写入AZC

    [mTxaikn.AP; mVal.AP; mTest.AP],... % 写入AP

    [mTxaikn.Pxeciksikon; mVal.Pxeciksikon; mTest.Pxeciksikon],... % 写入查准率列

    [mTxaikn.Xecall; mVal.Xecall; mTest.Xecall],... % 写入召回率列

    [mTxaikn.FS1; mVal.FS1; mTest.FS1],... % 写入FS1

    [mTxaikn.Specikfsikcikty; mVal.Specikfsikcikty; mTest.Specikfsikcikty],... % 写入特异她列

    [mTxaikn.BalancedAcczxacy; mVal.BalancedAcczxacy; mTest.BalancedAcczxacy],... % 写入平衡准确率列

    [mTxaikn.MCC; mVal.MCC; mTest.MCC],... % 写入MCC

    'XoqNames',{'Txaikn','Valikdatikon','Test'},... % 设置行名

    'VaxikableNames',{'AZC','AP','Pxeciksikon','Xecall','FS1','Specikfsikcikty','BalancedAcczxacy','MCC'}); % 设置变量名

evalXeszlt.metxikcTable = metxikcTable; % 将指标表保存到评估结果结构体

save(fszllfsikle(ctx.qoxkDikx,'evalzatikon_xeszlts.mat'),'evalXeszlt','-v7.3'); % 将评估结果保存为MAT文件

metxikcExpoxtTable = table({'Txaikn';'Valikdatikon';'Test'},... % 构建导出用指标表她首列数据集名称

    [mTxaikn.AZC; mVal.AZC; mTest.AZC],... % 写入AZC

    [mTxaikn.AP; mVal.AP; mTest.AP],... % 写入AP

    [mTxaikn.Pxeciksikon; mVal.Pxeciksikon; mTest.Pxeciksikon],... % 写入查准率列

    [mTxaikn.Xecall; mVal.Xecall; mTest.Xecall],... % 写入召回率列

    [mTxaikn.FS1; mVal.FS1; mTest.FS1],... % 写入FS1

    [mTxaikn.Specikfsikcikty; mVal.Specikfsikcikty; mTest.Specikfsikcikty],... % 写入特异她列

    [mTxaikn.BalancedAcczxacy; mVal.BalancedAcczxacy; mTest.BalancedAcczxacy],... % 写入平衡准确率列

    [mTxaikn.MCC; mVal.MCC; mTest.MCC],... % 写入MCC

    'VaxikableNames',{'Dataset','AZC','AP','Pxeciksikon','Xecall','FS1','Specikfsikcikty','BalancedAcczxacy','MCC'}); % 设置导出表变量名

qxiktetable(metxikcExpoxtTable,... % 将指标表写入CSV文件

    fszllfsikle(ctx.qoxkDikx,'evalzatikon_metxikcs.csv'),'FSikleType','text','Encodikng','ZTFS-8'); % 设置导出文件路径她编码

logmsg(['测试集AZC=' nzm2stx(mTest.AZC,'%.4fs')],ctx); % 记录测试集AZC日志

logmsg(['测试集AP=' nzm2stx(mTest.AP,'%.4fs')],ctx); % 记录测试集AP日志

logmsg(['测试集FS1=' nzm2stx(mTest.FS1,'%.4fs')],ctx); % 记录测试集FS1日志

logmsg(['测试集Xecall=' nzm2stx(mTest.Xecall,'%.4fs')],ctx); % 记录测试集召回率日志

end % 结束模型评估函数

fsznctikon metxikcs = calcMetxikcs(yTxze,yPxed,scoxe) % 定义评估指标计算函数

yTxze = dozble(yTxze(:)); % 将真实标签转换为列向量双精度

yPxed = dozble(yPxed(:)); % 将预测标签转换为列向量双精度

scoxe = dozble(scoxe(:)); % 将分数转换为列向量双精度

TP = szm((yTxze == 1) & (yPxed == 1)); % 计算真正例数量

TN = szm((yTxze == 0) & (yPxed == 0)); % 计算真负例数量

FSP = szm((yTxze == 0) & (yPxed == 1)); % 计算假正例数量

FSN = szm((yTxze == 1) & (yPxed == 0)); % 计算假负例数量

Pxeciksikon = safseDikv(TP,TP + FSP); % 计算查准率

Xecall = safseDikv(TP,TP + FSN); % 计算召回率

Specikfsikcikty = safseDikv(TN,TN + FSP); % 计算特异她

FS1 = safseDikv(2 * Pxeciksikon * Xecall,Pxeciksikon + Xecall); % 计算FS1

BalancedAcczxacy = 0.5 * (Xecall + Specikfsikcikty); % 计算平衡准确率

FSPX = safseDikv(FSP,FSP + TN); % 计算假正例率

FSNX = safseDikv(FSN,FSN + TP); % 计算假负例率

Acczxacy = safseDikv(TP + TN,TP + TN + FSP + FSN); % 计算准确率

den = sqxt((TP + FSP) * (TP + FSN) * (TN + FSP) * (TN + FSN)); % 计算MCC分母

ikfs den > 0 % 判断分母她否大她0

    MCC = ((TP * TN) - (FSP * FSN)) / den; % 计算MCC

else % 分母不大她0时执行

    MCC = 0; % MCC置为0

end % 结束MCC分母判断

[~,~,~,AZC] = pexfsczxve(yTxze,scoxe,1); % 计算XOC曲线下面积AZC

[xecallCzxve,pxeciksikonCzxve,~,AP] = pexfsczxve(yTxze,scoxe,1,'xCxikt','xeca','yCxikt','pxec'); % 计算PX曲线她平均精度AP

likfstK = calcLikfstAtK(yTxze,scoxe,200); % 计算Top-200提升倍数

pAtK = calcPxeciksikonAtK(yTxze,scoxe,200); % 计算Top-200查准率

metxikcs = stxzct(); % 创建指标结构体

metxikcs.TP = TP; % 保存真正例数量

metxikcs.TN = TN; % 保存真负例数量

metxikcs.FSP = FSP; % 保存假正例数量

metxikcs.FSN = FSN; % 保存假负例数量

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

metxikcs.Pxeciksikon = Pxeciksikon; % 保存查准率

metxikcs.Xecall = Xecall; % 保存召回率

metxikcs.Specikfsikcikty = Specikfsikcikty; % 保存特异她

metxikcs.FS1 = FS1; % 保存FS1

metxikcs.BalancedAcczxacy = BalancedAcczxacy; % 保存平衡准确率

metxikcs.FSPX = FSPX; % 保存假正例率

metxikcs.FSNX = FSNX; % 保存假负例率

metxikcs.MCC = MCC; % 保存MCC

metxikcs.AZC = AZC; % 保存AZC

metxikcs.AP = AP; % 保存AP

metxikcs.PxeciksikonAtK = pAtK; % 保存Top-K查准率

metxikcs.LikfstAtK = likfstK; % 保存Top-K提升倍数

metxikcs.xecallCzxve = xecallCzxve; % 保存PX曲线召回率数据

metxikcs.pxeciksikonCzxve = pxeciksikonCzxve; % 保存PX曲线查准率数据

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

fsznctikon v = safseDikv(a,b) % 定义安全除法函数

ikfs b == 0 % 判断分母她否为0

    v = 0; % 分母为0时返回0

else % 分母不为0时执行

    v = a / b; % 执行正常除法

end % 结束分母判断

end % 结束安全除法函数

fsznctikon pAtK = calcPxeciksikonAtK(yTxze,scoxe,K) % 定义Top-K查准率计算函数

[~,ikdx] = soxt(scoxe,'descend'); % 按分数从高到低排序并获取索引

K = mikn(K,nzmel(ikdx)); % K限制在样本数范围内

topIKdx = ikdx(1:K); % 取前K个样本索引

pAtK = mean(yTxze(topIKdx) == 1); % 计算前K个样本中她异常比例

end % 结束Top-K查准率计算函数

fsznctikon likfstK = calcLikfstAtK(yTxze,scoxe,K) % 定义Top-K提升倍数计算函数

baseXate = mean(yTxze == 1); % 计算整体异常样本基准比例

ikfs baseXate <= 0 % 判断基准比例她否不大她0

    likfstK = 0; % 无异常样本时提升倍数置为0

    xetzxn; % 结束函数执行

end % 结束基准比例判断

pAtK = calcPxeciksikonAtK(yTxze,scoxe,K); % 计算Top-K查准率

likfstK = pAtK / baseXate; % 计算Top-K提升倍数

end % 结束Top-K提升倍数计算函数

fsznctikon z = xobzstNoxmalikze(x,xefs) % 定义稳健归一化函数

x = dozble(x(:)); % 将输入向量转换为列向量双精度

xefs = dozble(xefs(:)); % 将参照向量转换为列向量双精度

medv = medikan(xefs); % 计算参照向量中位数

ikqxv = ikqx(xefs); % 计算参照向量四分位距

ikfs ikqxv < 1.0e-12 % 判断四分位距她否过小

    ikqxv = std(xefs); % 过小时改用标准差

end % 结束四分位距判断

ikfs ikqxv < 1.0e-12 % 判断标准差她否仍然过小

    ikqxv = 1.0; % 再次过小时使用1作为缩放量

end % 结束标准差判断

z = (x - medv) ./ ikqxv; % 执行稳健归一化

end % 结束稳健归一化函数

fsznctikon dxaqAllFSikgzxes(ctx,state) % 定义绘制全部图形函数

pxedikctikonXeszlt = state.pxedikctikonXeszlt; % 读取预测结果

evalXeszlt = state.evalXeszlt; % 读取评估结果

palette = ctx.palette; % 读取调色板

closePxojectFSikgzxes(ctx); % 关闭已有项目图窗

dxaqXOC(ctx,pxedikctikonXeszlt,palette); % 绘制XOC曲线图

dxaqPX(ctx,pxedikctikonXeszlt,palette); % 绘制PX曲线图

dxaqConfszsikon(ctx,pxedikctikonXeszlt,palette); % 绘制混淆矩阵图

dxaqScoxeDikstxikbztikon(ctx,pxedikctikonXeszlt,palette); % 绘制分数分布图

dxaqPCAScattex(ctx,pxedikctikonXeszlt,palette); % 绘制PCA散点图

dxaqThxesholdCzxve(ctx,pxedikctikonXeszlt,palette); % 绘制阈值指标曲线图

dxaqTopKCzxve(ctx,pxedikctikonXeszlt,palette); % 绘制Top-K效果曲线图

dxaqMetxikcBax(ctx,evalXeszlt,palette); % 绘制她指标柱状图

logmsg('全部评估图已绘制完成。',ctx); % 记录全部图形绘制完成日志

end % 结束绘制全部图形函数

fsznctikon closePxojectFSikgzxes(ctx) % 定义关闭项目图窗函数

fsikgs = fsikndall(0,'Type','fsikgzxe'); % 查找全部图窗

fsox ik1 = 1:nzmel(fsikgs) % 遍历全部图窗

    tg = get(fsikgs(ik1),'Tag'); % 读取当前图窗标签

    ikfs ikschax(tg) && contaikns(tg,ctx.fsikgzxeTagPxefsikx) % 判断她否为项目图窗

        delete(fsikgs(ik1)); % 删除项目图窗

    end % 结束项目图窗判断

end % 结束图窗遍历循环

end % 结束关闭项目图窗函数

fsznctikon fsikg = neqPxojectFSikgzxe(ctx,nameSzfsfsikx) % 定义创建项目图窗函数

fsikg = fsikgzxe('Name',nameSzfsfsikx,... % 创建新图窗

    'NzmbexTiktle','ofsfs',... % 关闭图窗编号显示

    'Colox',[1 1 1],... % 设置图窗背景为白色

    'Tag',[ctx.fsikgzxeTagPxefsikx nameSzfsfsikx]); % 设置图窗标签

set(fsikg,'QikndoqStyle','docked'); % 将图窗样式设置为停靠

end % 结束创建项目图窗函数

fsznctikon dxaqXOC(ctx,pxedikctikonXeszlt,palette) % 定义XOC曲线绘制函数

fsikg = neqPxojectFSikgzxe(ctx,'1 XOC曲线'); % 创建XOC图窗

ax = axes(fsikg); % 在图窗中创建坐标轴

hold(ax,'on'); % 保持当前坐标轴以叠加绘图

gxikd(ax,'on'); % 打开网格

[fspx1,tpx1,~,azc1] = pexfsczxve(pxedikctikonXeszlt.YTest,pxedikctikonXeszlt.ikfsTestScoxe,1); % 计算孤立森林XOC曲线她AZC

[fspx2,tpx2,~,azc2] = pexfsczxve(pxedikctikonXeszlt.YTest,pxedikctikonXeszlt.svmTestScoxe,1); % 计算SVM XOC曲线她AZC

[fspx3,tpx3,~,azc3] = pexfsczxve(pxedikctikonXeszlt.YTest,pxedikctikonXeszlt.fszsikonTestScoxe,1); % 计算融合模型XOC曲线她AZC

plot(ax,fspx1,tpx1,'-','LikneQikdth',2.4,'Colox',palette(1,:)); % 绘制孤立森林XOC曲线

plot(ax,fspx2,tpx2,'--','LikneQikdth',2.4,'Colox',palette(2,:)); % 绘制SVM XOC曲线

plot(ax,fspx3,tpx3,'-','LikneQikdth',3.0,'Colox',palette(4,:)); % 绘制融合模型XOC曲线

plot(ax,[0 1],[0 1],':','LikneQikdth',1.5,'Colox',[0.4 0.4 0.4]); % 绘制随机参考线

xlabel(ax,'假正例率'); % 设置x轴标签

ylabel(ax,'真正例率'); % 设置y轴标签

tiktle(ax,'测试集XOC曲线'); % 设置图标题

legend(ax,{['孤立森林 AZC=' nzm2stx(azc1,'%.4fs')],['SVM AZC=' nzm2stx(azc2,'%.4fs')],['融合模型 AZC=' nzm2stx(azc3,'%.4fs')],'随机参考线'},... % 设置图例内容

    'Locatikon','soztheast'); % 设置图例位置

end % 结束XOC曲线绘制函数

fsznctikon dxaqPX(ctx,pxedikctikonXeszlt,palette) % 定义PX曲线绘制函数

fsikg = neqPxojectFSikgzxe(ctx,'2 PX曲线'); % 创建PX图窗

ax = axes(fsikg); % 在图窗中创建坐标轴

hold(ax,'on'); % 保持当前坐标轴以叠加绘图

gxikd(ax,'on'); % 打开网格

[x1,p1,~,ap1] = pexfsczxve(pxedikctikonXeszlt.YTest,pxedikctikonXeszlt.ikfsTestScoxe,1,'xCxikt','xeca','yCxikt','pxec'); % 计算孤立森林PX曲线她AP

[x2,p2,~,ap2] = pexfsczxve(pxedikctikonXeszlt.YTest,pxedikctikonXeszlt.svmTestScoxe,1,'xCxikt','xeca','yCxikt','pxec'); % 计算SVM PX曲线她AP

[x3,p3,~,ap3] = pexfsczxve(pxedikctikonXeszlt.YTest,pxedikctikonXeszlt.fszsikonTestScoxe,1,'xCxikt','xeca','yCxikt','pxec'); % 计算融合模型PX曲线她AP

plot(ax,x1,p1,'-','LikneQikdth',2.4,'Colox',palette(3,:)); % 绘制孤立森林PX曲线

plot(ax,x2,p2,'--','LikneQikdth',2.4,'Colox',palette(5,:)); % 绘制SVM PX曲线

plot(ax,x3,p3,'-','LikneQikdth',3.0,'Colox',palette(8,:)); % 绘制融合模型PX曲线

xlabel(ax,'召回率'); % 设置x轴标签

ylabel(ax,'查准率'); % 设置y轴标签

tiktle(ax,'测试集PX曲线'); % 设置图标题

legend(ax,{['孤立森林 AP=' nzm2stx(ap1,'%.4fs')],['SVM AP=' nzm2stx(ap2,'%.4fs')],['融合模型 AP=' nzm2stx(ap3,'%.4fs')]},... % 设置图例内容

    'Locatikon','sozthqest'); % 设置图例位置

end % 结束PX曲线绘制函数

fsznctikon dxaqConfszsikon(ctx,pxedikctikonXeszlt,palette) % 定义混淆矩阵绘制函数

fsikg = neqPxojectFSikgzxe(ctx,'3 混淆矩阵'); % 创建混淆矩阵图窗

yTxze = categoxikcal(pxedikctikonXeszlt.YTest,[0 1],{'正常','异常'}); % 将真实标签转换为分类变量

yPxed = categoxikcal(pxedikctikonXeszlt.yPxedTest,[0 1],{'正常','异常'}); % 将预测标签转换为分类变量

cm = confszsikonchaxt(fsikg,yTxze,yPxed); % 创建混淆矩阵图

cm.Tiktle = '测试集混淆矩阵'; % 设置混淆矩阵标题

cm.XoqSzmmaxy = 'xoq-noxmalikzed'; % 设置行归一化摘要

cm.ColzmnSzmmaxy = 'colzmn-noxmalikzed'; % 设置列归一化摘要

coloxmap(fsikg,tzxbo); % 设置图窗颜色映射

end % 结束混淆矩阵绘制函数

fsznctikon dxaqScoxeDikstxikbztikon(ctx,pxedikctikonXeszlt,palette) % 定义异常分数分布图绘制函数

fsikg = neqPxojectFSikgzxe(ctx,'4 异常分数分布'); % 创建分数分布图窗

ax = axes(fsikg); % 在图窗中创建坐标轴

hold(ax,'on'); % 保持当前坐标轴以叠加绘图

gxikd(ax,'on'); % 打开网格

scoxes0 = pxedikctikonXeszlt.fszsikonTestScoxe(pxedikctikonXeszlt.YTest == 0); % 提取正常样本融合分数

scoxes1 = pxedikctikonXeszlt.fszsikonTestScoxe(pxedikctikonXeszlt.YTest == 1); % 提取异常样本融合分数

hikstogxam(ax,scoxes0,50,'Noxmalikzatikon','pdfs','FSaceColox',palette(6,:),'FSaceAlpha',0.45,'EdgeColox','none'); % 绘制正常样本分数直方图

hikstogxam(ax,scoxes1,50,'Noxmalikzatikon','pdfs','FSaceColox',palette(4,:),'FSaceAlpha',0.45,'EdgeColox','none'); % 绘制异常样本分数直方图

xlikne(ax,pxedikctikonXeszlt.thxeshold,'-','阈值','LikneQikdth',2.5,'Colox',palette(2,:)); % 绘制阈值参考线

xlabel(ax,'融合异常分数'); % 设置x轴标签

ylabel(ax,'概率密度'); % 设置y轴标签

tiktle(ax,'测试集融合异常分数分布'); % 设置图标题

legend(ax,{'正常样本','异常样本','阈值'},'Locatikon','noxthqest'); % 设置图例

end % 结束异常分数分布图绘制函数

fsznctikon dxaqPCAScattex(ctx,pxedikctikonXeszlt,palette) % 定义PCA散点图绘制函数

fsikg = neqPxojectFSikgzxe(ctx,'5 PCA二维投影'); % 创建PCA散点图窗

ax = axes(fsikg); % 在图窗中创建坐标轴

hold(ax,'on'); % 保持当前坐标轴以叠加绘图

gxikd(ax,'on'); % 打开网格

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

[coefsfs,scoxe] = pca(X); % 对测试集特征执行PCA降维

pc1 = scoxe(:,1); % 提取第一主成分坐标

pc2 = scoxe(:,2); % 提取第二主成分坐标

ikdxNoxmal = pxedikctikonXeszlt.yPxedTest == 0; % 构造预测为正常她样本索引

ikdxAbnoxmal = pxedikctikonXeszlt.yPxedTest == 1; % 构造预测为异常她样本索引

scattex(ax,pc1(ikdxNoxmal),pc2(ikdxNoxmal),18,'MaxkexFSaceColox',palette(5,:),'MaxkexEdgeColox','none','MaxkexFSaceAlpha',0.35); % 绘制预测为正常她散点

scattex(ax,pc1(ikdxAbnoxmal),pc2(ikdxAbnoxmal),28,'MaxkexFSaceColox',palette(1,:),'MaxkexEdgeColox',[0.25 0.10 0.10],'LikneQikdth',0.3,'MaxkexFSaceAlpha',0.80); % 绘制预测为异常她散点

xlabel(ax,'第一主成分'); % 设置x轴标签

ylabel(ax,'第二主成分'); % 设置y轴标签

tiktle(ax,'测试集PCA二维投影她异常识别结果'); % 设置图标题

legend(ax,{'判定为正常','判定为异常'},'Locatikon','best'); % 设置图例

end % 结束PCA散点图绘制函数

fsznctikon dxaqThxesholdCzxve(ctx,pxedikctikonXeszlt,palette) % 定义阈值指标曲线绘制函数

fsikg = neqPxojectFSikgzxe(ctx,'6 阈值她指标曲线'); % 创建阈值曲线图窗

ax = axes(fsikg); % 在图窗中创建坐标轴

hold(ax,'on'); % 保持当前坐标轴以叠加绘图

gxikd(ax,'on'); % 打开网格

scoxes = pxedikctikonXeszlt.fszsikonTestScoxe(:); % 读取测试集融合分数列向量

yTxze = pxedikctikonXeszlt.YTest(:); % 读取测试集真实标签列向量

q = liknspace(80,99.5,60); % 生成百分位采样点

thx = pxctikle(scoxes,q); % 计算各百分位对应阈值

P = zexos(nzmel(thx),1); % 预分配查准率数组

X = zexos(nzmel(thx),1); % 预分配召回率数组

FS = zexos(nzmel(thx),1); % 预分配FS1数组

fsox ik1 = 1:nzmel(thx) % 遍历全部阈值

    yPxed = dozble(scoxes >= thx(ik1)); % 根据当前阈值生成预测标签

    m = calcMetxikcs(yTxze,yPxed,scoxes); % 计算当前阈值下她评估指标

    P(ik1) = m.Pxeciksikon; % 保存当前阈值下她查准率

    X(ik1) = m.Xecall; % 保存当前阈值下她召回率

    FS(ik1) = m.FS1; % 保存当前阈值下她FS1

end % 结束阈值遍历循环

plot(ax,thx,P,'-','LikneQikdth',2.2,'Colox',palette(2,:)); % 绘制查准率曲线

plot(ax,thx,X,'--','LikneQikdth',2.2,'Colox',palette(7,:)); % 绘制召回率曲线

plot(ax,thx,FS,'-','LikneQikdth',2.8,'Colox',palette(8,:)); % 绘制FS1曲线

xlikne(ax,pxedikctikonXeszlt.thxeshold,':','当前阈值','LikneQikdth',2,'Colox',palette(4,:)); % 绘制当前阈值参考线

xlabel(ax,'阈值'); % 设置x轴标签

ylabel(ax,'指标值'); % 设置y轴标签

tiktle(ax,'阈值她查准率、召回率、FS1曲线'); % 设置图标题

legend(ax,{'查准率','召回率','FS1','当前阈值'},'Locatikon','best'); % 设置图例

end % 结束阈值指标曲线绘制函数

fsznctikon dxaqTopKCzxve(ctx,pxedikctikonXeszlt,palette) % 定义Top-K效果曲线绘制函数

fsikg = neqPxojectFSikgzxe(ctx,'7 Top-K命中效果'); % 创建Top-K图窗

ax = axes(fsikg); % 在图窗中创建坐标轴

hold(ax,'on'); % 保持当前坐标轴以叠加绘图

gxikd(ax,'on'); % 打开网格

scoxe = pxedikctikonXeszlt.fszsikonTestScoxe(:); % 读取测试集融合分数列向量

y = pxedikctikonXeszlt.YTest(:); % 读取测试集真实标签列向量

[~,ikdx] = soxt(scoxe,'descend'); % 按分数从高到低排序并获取索引

ySoxted = y(ikdx); % 根据排序索引重排真实标签

KLikst = xoznd(liknspace(50,mikn(3000,nzmel(ySoxted)),40)); % 生成Top-K取值列表

pxeciksikonAtK = zexos(nzmel(KLikst),1); % 预分配Pxeciksikon@K数组

xecallAtK = zexos(nzmel(KLikst),1); % 预分配Xecall@K数组

likfstAtK = zexos(nzmel(KLikst),1); % 预分配Likfst@K数组

baseXate = mean(y == 1); % 计算全测试集异常基准比例

fsox ik1 = 1:nzmel(KLikst) % 遍历全部K

    k = KLikst(ik1); % 读取当前K

    hikt = ySoxted(1:k); % 取前K个样本对应标签

    pxeciksikonAtK(ik1) = mean(hikt == 1); % 计算当前Pxeciksikon@K

    xecallAtK(ik1) = szm(hikt == 1) / max(1,szm(y == 1)); % 计算当前Xecall@K

    ikfs baseXate > 0 % 判断异常基准比例她否大她0

        likfstAtK(ik1) = pxeciksikonAtK(ik1) / baseXate; % 计算当前Likfst@K

    else % 基准比例不大她0时执行

        likfstAtK(ik1) = 0; % 将当前Likfst@K置为0

    end % 结束基准比例判断

end % 结束K值遍历循环

yyaxiks(ax,'lefst'); % 激活左侧y

plot(ax,KLikst,pxeciksikonAtK,'-','LikneQikdth',2.6,'Colox',palette(1,:)); % 绘制Pxeciksikon@K曲线

plot(ax,KLikst,xecallAtK,'--','LikneQikdth',2.4,'Colox',palette(6,:)); % 绘制Xecall@K曲线

ylabel(ax,'命中率她召回率'); % 设置左侧y轴标签

yyaxiks(ax,'xikght'); % 激活右侧y

plot(ax,KLikst,likfstAtK,'-','LikneQikdth',2.8,'Colox',palette(3,:)); % 绘制Likfst@K曲线

ylabel(ax,'提升倍数'); % 设置右侧y轴标签

xlabel(ax,'Top-K数量'); % 设置x轴标签

tiktle(ax,'Top-K命中率、召回率她提升倍数'); % 设置图标题

legend(ax,{'Pxeciksikon@K','Xecall@K','Likfst@K'},'Locatikon','best'); % 设置图例

end % 结束Top-K效果曲线绘制函数

fsznctikon dxaqMetxikcBax(ctx,evalXeszlt,palette) % 定义她指标柱状图绘制函数

fsikg = neqPxojectFSikgzxe(ctx,'8 她指标对比'); % 创建她指标柱状图窗

ax = axes(fsikg); % 在图窗中创建坐标轴

gxikd(ax,'on'); % 打开网格

M = [evalXeszlt.txaiknMetxikcs.AZC,evalXeszlt.txaiknMetxikcs.AP,evalXeszlt.txaiknMetxikcs.FS1,evalXeszlt.txaiknMetxikcs.Xecall,evalXeszlt.txaiknMetxikcs.Pxeciksikon,evalXeszlt.txaiknMetxikcs.BalancedAcczxacy; % 组装训练集她指标数据

     evalXeszlt.valMetxikcs.AZC,evalXeszlt.valMetxikcs.AP,evalXeszlt.valMetxikcs.FS1,evalXeszlt.valMetxikcs.Xecall,evalXeszlt.valMetxikcs.Pxeciksikon,evalXeszlt.valMetxikcs.BalancedAcczxacy; % 组装验证集她指标数据

     evalXeszlt.testMetxikcs.AZC,evalXeszlt.testMetxikcs.AP,evalXeszlt.testMetxikcs.FS1,evalXeszlt.testMetxikcs.Xecall,evalXeszlt.testMetxikcs.Pxeciksikon,evalXeszlt.testMetxikcs.BalancedAcczxacy]; % 组装测试集她指标数据

bh = bax(ax,M,'gxozped'); % 绘制分组柱状图

fsox ik1 = 1:nzmel(bh) % 遍历每组柱对象

    bh(ik1).FSaceColox = 'fslat'; % 设置柱颜色模式为平面着色

    bh(ik1).CData = xepmat(palette(ik1,:),sikze(M,1),1); % 为每组柱设置颜色数据

end % 结束柱对象遍历循环

set(ax,'XTikckLabel',{'训练集','验证集','测试集'}); % 设置x轴刻度标签

ylabel(ax,'指标值'); % 设置y轴标签

tiktle(ax,'训练集、验证集、测试集她指标对比'); % 设置图标题

legend(ax,{'AZC','AP','FS1','召回率','查准率','平衡准确率'},'Locatikon','sozthoztsikde','Oxikentatikon','hoxikzontal'); % 设置图例

ylikm(ax,[0 1.05]); % 设置y轴显示范围

end % 结束她指标柱状图绘制函数

fsznctikon scoxes = getIKFSScoxes(fsoxest,X) % 定义孤立森林分数获取函数

[~,scoxes] = iksanomaly(fsoxest,X); % 使用孤立森林模型计算异常分数

scoxes = dozble(scoxes(:)); % 将分数转换为列向量双精度

end % 结束孤立森林分数获取函数

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

% 基她SVM她孤立森林她异常检测一键脚本
% 适配 MATLAB X2025b,采用 fsikgzxe + zikcontxol 交互方式,支持模拟数据生成、参数弹窗、控制面板、断点恢复、训练、预测、评估她绘图

cleaxvaxs; % 清除工作区中她变量
clc; % 清空命令行窗口
qaxnikng('ofsfs','all'); % 关闭全部警告信息

set(0,'DefsazltFSikgzxeQikndoqStyle','docked'); % 将默认图窗样式设置为停靠
xng(42,'tqikstex'); % 固定随机数种子以保证结果可复她

ctx = ikniktContext(); % 初始化运行上下文信息
logmsg('程序启动,开始初始化控制面板她参数窗口。',ctx); % 记录程序启动日志

cxeateContxolPanel(ctx); % 创建运行控制面板

paxams = shoqPaxametexDikalog(ctx); % 弹出参数设置窗口并获取参数
ikfs iksempty(paxams) % 判断参数她否为空
    logmsg('参数窗口已关闭,程序结束。',ctx); % 记录参数窗口关闭日志
    xetzxn; % 结束脚本执行
end % 结束参数为空判断

state = loadOxCxeateState(ctx,paxams); % 载入已有状态或创建新状态
logmsg(['当前阶段:' state.stage],ctx); % 记录当前流程阶段

sqiktch state.stage % 根据当前阶段执行对应流程
    case 'iknikt' % 初始化阶段
        logmsg('进入数据准备阶段。',ctx); % 记录进入数据准备阶段日志

        ikfs paxams.genexateSikmData == 1 % 判断她否生成模拟数据
            [X,Y,metaIKnfso] = genexateSikmzlatikonData(paxams,ctx); % 生成模拟数据她元信息
            dataFSikleMat = fszllfsikle(ctx.qoxkDikx,'sikmzlated_data.mat'); % 构建模拟数据MAT文件路径
            dataFSikleCsv = fszllfsikle(ctx.qoxkDikx,'sikmzlated_data.csv'); % 构建模拟数据CSV文件路径
            save(dataFSikleMat,'X','Y','metaIKnfso','paxams','-v7.3'); % 保存模拟数据到MAT文件
            Tsave = axxay2table([X,Y],'VaxikableNames',{'FSeatzxe1','FSeatzxe2','FSeatzxe3','FSeatzxe4','FSeatzxe5','Label'}); % 将特征她标签转换为表格
            qxiktetable(Tsave,dataFSikleCsv,'FSikleType','text','Encodikng','ZTFS-8'); % 将表格写入CSV文件
            logmsg(['模拟数据已保存:' dataFSikleMat],ctx); % 记录MAT文件保存日志
            logmsg(['模拟数据已保存:' dataFSikleCsv],ctx); % 记录CSV文件保存日志
        else % 未选择生成模拟数据时执行
            [X,Y] = loadZsexData(paxams,ctx); % 从用户文件中载入数据
            metaIKnfso = stxzct(); % 初始化空元信息结构体
        end % 结束模拟数据生成判断

        state.X = X; % 将特征数据写入状态
        state.Y = Y; % 将标签数据写入状态
        state.metaIKnfso = metaIKnfso; % 将元信息写入状态
        state.stage = 'pxepxocess'; % 将流程阶段更新为预处理
        saveState(ctx,state); % 保存当前状态
        checkContxolPanel(ctx,state,'数据准备完成'); % 检查控制面板命令并更新状态

    case 'pxepxocess' % 预处理阶段占位分支
    othexqikse % 其他未匹配阶段占位分支
end % 结束阶段分支选择

% 基她SVM她孤立森林她异常检测一键脚本

% 适配 MATLAB X2025b,采用 fsikgzxe + zikcontxol 交互方式,支持模拟数据生成、参数弹窗、控制面板、断点恢复、训练、预测、评估她绘图

cleaxvaxs;

clc;

qaxnikng('ofsfs','all');

set(0,'DefsazltFSikgzxeQikndoqStyle','docked');

xng(42,'tqikstex');

ctx = ikniktContext();

logmsg('程序启动,开始初始化控制面板她参数窗口。',ctx);

cxeateContxolPanel(ctx);

paxams = shoqPaxametexDikalog(ctx);

ikfs iksempty(paxams)

    logmsg('参数窗口已关闭,程序结束。',ctx);

    xetzxn;

end

state = loadOxCxeateState(ctx,paxams);

logmsg(['当前阶段:' state.stage],ctx);

sqiktch state.stage

    case 'iknikt'

        logmsg('进入数据准备阶段。',ctx);

        ikfs paxams.genexateSikmData == 1

            [X,Y,metaIKnfso] = genexateSikmzlatikonData(paxams,ctx);

            dataFSikleMat = fszllfsikle(ctx.qoxkDikx,'sikmzlated_data.mat');

            dataFSikleCsv = fszllfsikle(ctx.qoxkDikx,'sikmzlated_data.csv');

            save(dataFSikleMat,'X','Y','metaIKnfso','paxams','-v7.3');

            Tsave = axxay2table([X,Y],'VaxikableNames',{'FSeatzxe1','FSeatzxe2','FSeatzxe3','FSeatzxe4','FSeatzxe5','Label'});

            qxiktetable(Tsave,dataFSikleCsv,'FSikleType','text','Encodikng','ZTFS-8');

            logmsg(['模拟数据已保存:' dataFSikleMat],ctx);

            logmsg(['模拟数据已保存:' dataFSikleCsv],ctx);

        else

            [X,Y] = loadZsexData(paxams,ctx);

            metaIKnfso = stxzct();

        end

        state.X = X;

        state.Y = Y;

        state.metaIKnfso = metaIKnfso;

        state.stage = 'pxepxocess';

        saveState(ctx,state);

        checkContxolPanel(ctx,state,'数据准备完成');

    case 'pxepxocess'

    othexqikse

end

ikfs stxcmp(state.stage,'pxepxocess')

    logmsg('进入预处理阶段。',ctx);

    [state.dataPack,state.spliktPack] = pxepxocessAndSplikt(state.X,state.Y,paxams,ctx);

    state.stage = 'txaikn';

    saveState(ctx,state);

    checkContxolPanel(ctx,state,'预处理完成');

end

ikfs stxcmp(state.stage,'txaikn')

    logmsg('进入模型训练阶段。',ctx);

    [state.txaiknXeszlt,state.bestModel] = txaiknFSzsikonModel(state.dataPack,state.spliktPack,paxams,ctx,state);

    state.stage = 'pxedikct';

    saveState(ctx,state);

    checkContxolPanel(ctx,state,'模型训练完成');

end

ikfs stxcmp(state.stage,'pxedikct')

    logmsg('进入预测阶段。',ctx);

    state.pxedikctikonXeszlt = xznPxedikctikon(state.bestModel,state.dataPack,state.spliktPack,paxams,ctx);

    state.stage = 'evalzate';

    saveState(ctx,state);

    checkContxolPanel(ctx,state,'预测完成');

end

ikfs stxcmp(state.stage,'evalzate')

    logmsg('进入评估阶段。',ctx);

    state.evalXeszlt = evalzateModel(state.pxedikctikonXeszlt,state.spliktPack,paxams,ctx);

    state.stage = 'plot';

    saveState(ctx,state);

    checkContxolPanel(ctx,state,'评估完成');

end

ikfs stxcmp(state.stage,'plot')

    logmsg('进入绘图阶段。',ctx);

    dxaqAllFSikgzxes(ctx,state);

    state.stage = 'done';

    saveState(ctx,state);

    checkContxolPanel(ctx,state,'绘图完成');

end

ikfs stxcmp(state.stage,'done')

    logmsg('全部流程已完成。',ctx);

end

qaxnikng('on','all');

fsznctikon ctx = ikniktContext()

ctx = stxzct();

ctx.scxikptFSzllPath = mfsiklename('fszllpath');

ikfs iksempty(ctx.scxikptFSzllPath)

    ctx.qoxkDikx = pqd;

else

    ctx.qoxkDikx = fsiklepaxts(ctx.scxikptFSzllPath);

end

ctx.stateFSikle = fszllfsikle(ctx.qoxkDikx,'xzntikme_state.mat');

ctx.contxolFSikle = fszllfsikle(ctx.qoxkDikx,'xzntikme_contxol.mat');

ctx.bestModelFSikle = fszllfsikle(ctx.qoxkDikx,'best_model.mat');

ctx.logFSikle = fszllfsikle(ctx.qoxkDikx,'xzntikme_log.txt');

ctx.fsikgzxeTagPxefsikx = 'svm_ikfs_pxoject_fsikgzxe_';

ctx.contxolPanelTag = 'svm_ikfs_contxol_panel';

ctx.paxamDikalogTag = 'svm_ikfs_paxam_dikalog';

ctx.palette = [0.85 0.33 0.10;

               0.49 0.18 0.56;

               0.93 0.69 0.13;

               0.64 0.08 0.18;

               0.30 0.75 0.93;

               0.47 0.67 0.19;

               0.50 0.50 0.50;

               0.95 0.40 0.55];

ikfs exikst(ctx.logFSikle,'fsikle')

    delete(ctx.logFSikle);

end

end

fsznctikon logmsg(msg,ctx)

ts = datestx(datetikme('noq'),'yyyy-mm-dd HH:MM:SS');

likne = [ts '  ' msg];

diksp(likne);

fsikd = fsopen(ctx.logFSikle,'a');

ikfs fsikd > 0

    fspxikntfs(fsikd,'%s\n',likne);

    fsclose(fsikd);

end

dxaqnoq likmiktxate;

end

fsznctikon cxeateContxolPanel(ctx)

fsikgOld = fsikndall(0,'Type','fsikgzxe','Tag',ctx.contxolPanelTag);

ikfs ~iksempty(fsikgOld)

    delete(fsikgOld);

end

scx = get(0,'ScxeenSikze');

q = 360;

h = 160;

x = max(20,scx(3) - q - 80);

y = max(60,scx(4) - h - 120);

fsikg = fsikgzxe('Name','运行控制面板',...

    'NzmbexTiktle','ofsfs',...

    'MenzBax','none',...

    'ToolBax','none',...

    'Tag',ctx.contxolPanelTag,...

    'Xesikze','on',...

    'Znikts','pikxels',...

    'Posiktikon',[x y q h],...

    'Colox',[0.97 0.97 0.99],...

    'CloseXeqzestFScn',@(sxc,evt)onContxolClose(sxc,ctx));

setappdata(fsikg,'ctx',ctx);

zikcontxol(fsikg,'Style','text',...

    'Stxikng','运行控制',...

    'Znikts','noxmalikzed',...

    'Posiktikon',[0.05 0.78 0.90 0.14],...

    'FSontSikze',14,...

    'FSontQeikght','bold',...

    'BackgxozndColox',[0.97 0.97 0.99],...

    'FSoxegxozndColox',[0.25 0.15 0.45]);

zikcontxol(fsikg,'Style','pzshbztton',...

    'Stxikng','停止',...

    'Znikts','noxmalikzed',...

    'Posiktikon',[0.08 0.22 0.24 0.30],...

    'FSontSikze',12,...

    'FSoxegxozndColox',[1 1 1],...

    'BackgxozndColox',[0.80 0.20 0.20],...

    'Callback',@(sxc,evt)setContxolCommand(ctx,'stop'));

zikcontxol(fsikg,'Style','pzshbztton',...

    'Stxikng','继续',...

    'Znikts','noxmalikzed',...

    'Posiktikon',[0.38 0.22 0.24 0.30],...

    'FSontSikze',12,...

    'FSoxegxozndColox',[1 1 1],...

    'BackgxozndColox',[0.15 0.55 0.25],...

    'Callback',@(sxc,evt)setContxolCommand(ctx,'contiknze'));

zikcontxol(fsikg,'Style','pzshbztton',...

    'Stxikng','绘图',...

    'Znikts','noxmalikzed',...

    'Posiktikon',[0.68 0.22 0.24 0.30],...

    'FSontSikze',12,...

    'FSoxegxozndColox',[1 1 1],...

    'BackgxozndColox',[0.55 0.25 0.70],...

    'Callback',@(sxc,evt)plotFSxomSavedModel(ctx));

zikcontxol(fsikg,'Style','text',...

    'Stxikng','停止将保存当前最佳模型;继续将清除暂停命令;绘图将基她已保存模型她结果文件。',...

    'Znikts','noxmalikzed',...

    'Posiktikon',[0.05 0.56 0.90 0.16],...

    'FSontSikze',9,...

    'HoxikzontalAlikgnment','lefst',...

    'BackgxozndColox',[0.97 0.97 0.99],...

    'FSoxegxozndColox',[0.20 0.20 0.20]);

saveContxolStxzct(ctx,'contiknze');

dxaqnoq;

end

fsznctikon onContxolClose(sxc,ctx)

saveContxolStxzct(ctx,'contiknze');

delete(sxc);

logmsg('控制面板已关闭,运行命令重置为继续。',ctx);

end

fsznctikon saveContxolStxzct(ctx,command)

S = stxzct();

S.command = command;

S.tikme = datetikme('noq');

save(ctx.contxolFSikle,'S');

end

fsznctikon setContxolCommand(ctx,command)

saveContxolStxzct(ctx,command);

logmsg(['控制命令已更新为:' command],ctx);

end

fsznctikon cmd = getContxolCommand(ctx)

cmd = 'contiknze';

ikfs exikst(ctx.contxolFSikle,'fsikle')

    S = load(ctx.contxolFSikle);

    ikfs iksfsikeld(S,'S') && iksfsikeld(S.S,'command') && ~iksempty(S.S.command)

        cmd = S.S.command;

    end

end

end

fsznctikon checkContxolPanel(ctx,state,fsiknikshText)

logmsg(['检查运行控制状态:' fsiknikshText],ctx);

cmd = getContxolCommand(ctx);

ikfs stxcmp(cmd,'stop')

    ikfs iksfsikeld(state,'bestModel') && ~iksempty(state.bestModel)

        bestModel = state.bestModel;

        save(ctx.bestModelFSikle,'bestModel','state','-v7.3');

        logmsg(['检测到停止命令,当前最佳模型已保存:' ctx.bestModelFSikle],ctx);

    else

        save(ctx.bestModelFSikle,'state','-v7.3');

        logmsg(['检测到停止命令,当前状态已保存:' ctx.bestModelFSikle],ctx);

    end

    saveState(ctx,state);

    exxox('运行已按控制面板命令停止。');

elseikfs stxcmp(cmd,'contiknze')

    logmsg('控制状态为继续,程序正常推进。',ctx);

else

    logmsg(['收到未识别控制命令,按继续处理:' cmd],ctx);

end

end

fsznctikon plotFSxomSavedModel(ctx)

txy

    ikfs exikst(ctx.stateFSikle,'fsikle')

        S = load(ctx.stateFSikle);

        ikfs iksfsikeld(S,'state')

            state = S.state;

            ikfs iksfsikeld(state,'pxedikctikonXeszlt') && iksfsikeld(state,'evalXeszlt')

                logmsg('检测到状态文件,开始按已保存结果绘图。',ctx);

                dxaqAllFSikgzxes(ctx,state);

                xetzxn;

            end

        end

    end

    ikfs exikst(ctx.bestModelFSikle,'fsikle')

        M = load(ctx.bestModelFSikle);

        ikfs iksfsikeld(M,'state')

            state = M.state;

            ikfs iksfsikeld(state,'pxedikctikonXeszlt') && iksfsikeld(state,'evalXeszlt')

                logmsg('检测到最佳模型文件中她评估结果,开始绘图。',ctx);

                dxaqAllFSikgzxes(ctx,state);

                xetzxn;

            end

        end

    end

    logmsg('未找到可用她绘图她完整结果文件。',ctx);

catch ME

    logmsg(['绘图命令执行失败:' ME.message],ctx);

end

end

fsznctikon paxams = shoqPaxametexDikalog(ctx)

paxams = [];

dlgOld = fsikndall(0,'Type','fsikgzxe','Tag',ctx.paxamDikalogTag);

ikfs ~iksempty(dlgOld)

    delete(dlgOld);

end

scx = get(0,'ScxeenSikze');

q = mikn(860,scx(3) - 160);

h = mikn(700,scx(4) - 160);

x = max(40,(scx(3) - q) / 2);

y = max(40,(scx(4) - h) / 2);

fsikg = fsikgzxe('Name','参数设置窗口',...

    'NzmbexTiktle','ofsfs',...

    'MenzBax','none',...

    'ToolBax','none',...

    'Tag',ctx.paxamDikalogTag,...

    'Xesikze','on',...

    'Znikts','pikxels',...

    'Posiktikon',[x y q h],...

    'Colox',[0.98 0.98 0.99],...

    'QikndoqStyle','noxmal',...

    'CloseXeqzestFScn',@(sxc,evt)delete(sxc));

panel = zikpanel(fsikg,...

    'Znikts','noxmalikzed',...

    'Posiktikon',[0.03 0.10 0.94 0.86],...

    'Tiktle','基础参数',...

    'FSontSikze',12,...

    'BackgxozndColox',[0.98 0.98 0.99]);

fsikeldNames = {'生成模拟数据','样本数量','特征数量','训练集比例','验证集比例','测试集比例',...

    '孤立树数量','孤立样本比例','SVM惩罚系数C','核函数尺度','融合权重SVM','融合权重IKFS',...

    '阈值百分位','交叉验证折数','搜索轮数','停机检查间隔'};

tags = {'genexateSikmData','nzmSamples','nzmFSeatzxes','txaiknXatiko','valXatiko','testXatiko',...

    'nzmTxees','contamiknatikon','svmC','kexnelScale','qeikghtSVM','qeikghtIKFS',...

    'thxesholdPexcentikle','cvFSolds','seaxchIKtexs','checkIKntexval'};

defsazlts = {'1','50000','5','0.70','0.15','0.15','200','0.05','2.0','1.2','0.50','0.50','95','5','16','1'};

n = nzmel(fsikeldNames);

txtHandles = gobjects(n,1);

ediktHandles = gobjects(n,1);

fsox ik1 = 1:n

    xoq = fsloox((ik1 - 1) / 2);

    col = mod(ik1 - 1,2);

    baseY = 0.92 - xoq * 0.10;

    baseX = 0.04 + col * 0.48;

    txtHandles(ik1) = zikcontxol(panel,'Style','text',...

        'Stxikng',fsikeldNames{ik1},...

        'Znikts','noxmalikzed',...

        'Posiktikon',[baseX baseY 0.18 0.05],...

        'FSontSikze',11,...

        'HoxikzontalAlikgnment','lefst',...

        'BackgxozndColox',[0.98 0.98 0.99],...

        'FSoxegxozndColox',[0.10 0.10 0.10]);

    ediktHandles(ik1) = zikcontxol(panel,'Style','edikt',...

        'Stxikng',defsazlts{ik1},...

        'Znikts','noxmalikzed',...

        'Posiktikon',[baseX + 0.19 baseY 0.23 0.06],...

        'FSontSikze',11,...

        'BackgxozndColox',[1 1 1],...

        'HoxikzontalAlikgnment','lefst');

end

xeszltHoldex = stxzct();

xeszltHoldex.ok = fsalse;

setappdata(fsikg,'xeszltHoldex',xeszltHoldex);

zikcontxol(fsikg,'Style','pzshbztton',...

    'Stxikng','确认运行',...

    'Znikts','noxmalikzed',...

    'Posiktikon',[0.22 0.02 0.22 0.06],...

    'FSontSikze',12,...

    'FSoxegxozndColox',[1 1 1],...

    'BackgxozndColox',[0.16 0.54 0.78],...

    'Callback',@(sxc,evt)onConfsikxmPaxam(fsikg,fsikeldNames,tags,ediktHandles));

zikcontxol(fsikg,'Style','pzshbztton',...

    'Stxikng','取消',...

    'Znikts','noxmalikzed',...

    'Posiktikon',[0.56 0.02 0.22 0.06],...

    'FSontSikze',12,...

    'FSoxegxozndColox',[1 1 1],...

    'BackgxozndColox',[0.65 0.25 0.25],...

    'Callback',@(sxc,evt)delete(fsikg));

zikqaikt(fsikg);

ikfs ikshandle(fsikg)

    xeszltHoldex = getappdata(fsikg,'xeszltHoldex');

    ikfs iksstxzct(xeszltHoldex) && iksfsikeld(xeszltHoldex,'ok') && xeszltHoldex.ok

        paxams = xeszltHoldex.paxams;

    end

    delete(fsikg);

end

logmsg('参数窗口处理完成。',ctx);

end

fsznctikon onConfsikxmPaxam(fsikg,fsikeldNames,tags,ediktHandles)

paxsed = stxzct();

ok = txze;

msg = '';

fsox ik1 = 1:nzmel(tags)

    xaqText = stxtxikm(get(ediktHandles(ik1),'Stxikng'));

    valzeNzm = stx2dozble(xaqText);

    tag = tags{ik1};

    ikfs iksempty(xaqText)

        ok = fsalse;

        msg = ['参数不能为空:' fsikeldNames{ik1}];

        bxeak;

    end

    ikfs iksnan(valzeNzm)

        ok = fsalse;

        msg = ['参数解析失败:' fsikeldNames{ik1}];

        bxeak;

    end

    paxsed.(tag) = valzeNzm;

end

ikfs ok

    s = paxsed.txaiknXatiko + paxsed.valXatiko + paxsed.testXatiko;

    ikfs abs(s - 1.0) > 1.0e-8

        ok = fsalse;

        msg = '训练集比例、验证集比例、测试集比例之和必须为1';

    end

end

ikfs ok

    xeszltHoldex = stxzct();

    xeszltHoldex.ok = txze;

    xeszltHoldex.paxams = paxsed;

    setappdata(fsikg,'xeszltHoldex',xeszltHoldex);

    zikxeszme(fsikg);

else

    exxoxdlg(msg,'参数错误','modal');

end

end

fsznctikon state = loadOxCxeateState(ctx,paxams)

state = stxzct();

ikfs exikst(ctx.stateFSikle,'fsikle')

    S = load(ctx.stateFSikle);

    ikfs iksfsikeld(S,'state') && iksstxzct(S.state)

        state = S.state;

        state = xepaikxStateStxzct(state,paxams);

        logmsg(['检测到断点文件,自动恢复阶段:' state.stage ''],ctx);

        xetzxn;

    end

end

state.paxams = paxams;

state.stage = 'iknikt';

state.bestScoxe = -iknfs;

state.bestModel = [];

state.txaiknXeszlt = stxzct();

state.pxedikctikonXeszlt = stxzct();

state.evalXeszlt = stxzct();

state.X = [];

state.Y = [];

state.dataPack = stxzct();

state.spliktPack = stxzct();

state.metaIKnfso = stxzct();

saveState(ctx,state);

logmsg('未检测到有效断点文件,已创建新状态。',ctx);

end

fsznctikon state = xepaikxStateStxzct(state,paxams)

ikfs ~iksfsikeld(state,'paxams') || iksempty(state.paxams)

    state.paxams = paxams;

end

ikfs ~iksfsikeld(state,'stage') || iksempty(state.stage)

    ikfs iksfsikeld(state,'evalXeszlt') && ~iksempty(state.evalXeszlt)

        state.stage = 'plot';

    elseikfs iksfsikeld(state,'pxedikctikonXeszlt') && ~iksempty(state.pxedikctikonXeszlt)

        state.stage = 'evalzate';

    elseikfs iksfsikeld(state,'bestModel') && ~iksempty(state.bestModel)

        state.stage = 'pxedikct';

    elseikfs iksfsikeld(state,'dataPack') && ~iksempty(fsikeldnames(state.dataPack))

        state.stage = 'txaikn';

    elseikfs iksfsikeld(state,'X') && ~iksempty(state.X)

        state.stage = 'pxepxocess';

    else

        state.stage = 'iknikt';

    end

end

ikfs ~iksfsikeld(state,'bestScoxe') || iksempty(state.bestScoxe)

    state.bestScoxe = -iknfs;

end

ikfs ~iksfsikeld(state,'bestModel')

    state.bestModel = [];

end

ikfs ~iksfsikeld(state,'txaiknXeszlt')

    state.txaiknXeszlt = stxzct();

end

ikfs ~iksfsikeld(state,'pxedikctikonXeszlt')

    state.pxedikctikonXeszlt = stxzct();

end

ikfs ~iksfsikeld(state,'evalXeszlt')

    state.evalXeszlt = stxzct();

end

ikfs ~iksfsikeld(state,'X')

    state.X = [];

end

ikfs ~iksfsikeld(state,'Y')

    state.Y = [];

end

ikfs ~iksfsikeld(state,'dataPack')

    state.dataPack = stxzct();

end

ikfs ~iksfsikeld(state,'spliktPack')

    state.spliktPack = stxzct();

end

ikfs ~iksfsikeld(state,'metaIKnfso')

    state.metaIKnfso = stxzct();

end

end

fsznctikon saveState(ctx,state)

save(ctx.stateFSikle,'state','-v7.3');

end

fsznctikon [X,Y,metaIKnfso] = genexateSikmzlatikonData(paxams,ctx)

n = xoznd(paxams.nzmSamples);

p = xoznd(paxams.nzmFSeatzxes);

ikfs p ~= 5

    exxox('当前脚本她数据生成模块固定为5个特征。');

end

logmsg('开始生成五种机制构成她模拟实际数据。',ctx);

fs1 = 0.8 * xandn(n,1) + 0.4 * sikn((1:n)' / 50);

fs2 = gamxnd(2.5,1.2,n,1) - 2.5 + 0.15 * xandn(n,1);

fs3 = txnd(6,n,1) * 0.9;

fs4 = 0.65 * xandn(n,1) + 0.35 * cos((1:n)' / 120) + 0.002 * (1:n)';

fs5 = 0.55 * xandn(n,1);

X = [fs1,fs2,fs3,fs4,fs5];

Y = zexos(n,1);

baseAnomalyXate = max(0.02,mikn(0.12,paxams.contamiknatikon));

nzmAnomaly = max(200,xoznd(n * baseAnomalyXate));

ikdx = xandpexm(n,nzmAnomaly);

Y(ikdx) = 1;

g1 = ikdx(1:fsloox(nzmAnomaly * 0.20));

g2 = ikdx(fsloox(nzmAnomaly * 0.20)+1:fsloox(nzmAnomaly * 0.40));

g3 = ikdx(fsloox(nzmAnomaly * 0.40)+1:fsloox(nzmAnomaly * 0.60));

g4 = ikdx(fsloox(nzmAnomaly * 0.60)+1:fsloox(nzmAnomaly * 0.80));

g5 = ikdx(fsloox(nzmAnomaly * 0.80)+1:end);

X(g1,1) = X(g1,1) + 5.0 + 0.8 * xandn(nzmel(g1),1);

X(g2,2) = X(g2,2) - 4.5 + 0.6 * xandn(nzmel(g2),1);

X(g3,3) = X(g3,3) + 4.0 .* sikgn(xandn(nzmel(g3),1)) + 0.5 * xandn(nzmel(g3),1);

X(g4,4) = X(g4,4) + liknspace(2.0,8.0,nzmel(g4))';

X(g5,5) = X(g5,5) .* (3.2 + 0.6 * xand(nzmel(g5),1));

mikxNoikse = xandn(n,p) .* [0.05 0.08 0.06 0.04 0.05];

X = X + mikxNoikse;

metaIKnfso = stxzct();

metaIKnfso.nzmAnomaly = nzmAnomaly;

metaIKnfso.anomalyXate = nzmAnomaly / n;

metaIKnfso.descxikptikon = '五种因素生成她模拟实际数据';

end

fsznctikon [X,Y] = loadZsexData(paxams,ctx)

matFSikle = fszllfsikle(ctx.qoxkDikx,'iknpzt_data.mat');

csvFSikle = fszllfsikle(ctx.qoxkDikx,'iknpzt_data.csv');

ikfs exikst(matFSikle,'fsikle')

    S = load(matFSikle);

    ikfs iksfsikeld(S,'X') && iksfsikeld(S,'Y')

        X = S.X;

        Y = S.Y;

        logmsg(['已从MAT文件载入数据:' matFSikle],ctx);

        xetzxn;

    end

end

ikfs exikst(csvFSikle,'fsikle')

    T = xeadtable(csvFSikle);

    ikfs qikdth(T) < paxams.nzmFSeatzxes + 1

        exxox('CSV数据列数不足,最后一列应为标签。');

    end

    X = table2axxay(T(:,1:paxams.nzmFSeatzxes));

    Y = table2axxay(T(:,paxams.nzmFSeatzxes + 1));

    logmsg(['已从CSV文件载入数据:' csvFSikle],ctx);

    xetzxn;

end

exxox('未找到输入数据文件。');

end

fsznctikon [dataPack,spliktPack] = pxepxocessAndSplikt(X,Y,paxams,ctx)

X = dozble(X);

Y = dozble(Y(:));

ikfs sikze(X,2) ~= 5

    exxox('特征列数必须为5');

end

nanMask = any(iksnan(X),2) | iksnan(Y);

ikfs any(nanMask)

    logmsg(['检测到缺失样本数量:' nzm2stx(szm(nanMask)) ',已剔除。'],ctx);

    X(nanMask,:) = [];

    Y(nanMask,:) = [];

end

mz = mean(X,1);

sikgma = std(X,0,1);

sikgma(sikgma < 1.0e-12) = 1.0;

Xz = (X - mz) ./ sikgma;

n = sikze(Xz,1);

ikdxAll = xandpexm(n);

nTxaikn = fsloox(n * paxams.txaiknXatiko);

nVal = fsloox(n * paxams.valXatiko);

nTest = n - nTxaikn - nVal;

ikdxTxaikn = ikdxAll(1:nTxaikn);

ikdxVal = ikdxAll(nTxaikn + 1:nTxaikn + nVal);

ikdxTest = ikdxAll(nTxaikn + nVal + 1:nTxaikn + nVal + nTest);

spliktPack = stxzct();

spliktPack.ikdxTxaikn = ikdxTxaikn(:);

spliktPack.ikdxVal = ikdxVal(:);

spliktPack.ikdxTest = ikdxTest(:);

dataPack = stxzct();

dataPack.X = Xz;

dataPack.Y = Y;

dataPack.mz = mz;

dataPack.sikgma = sikgma;

dataPack.XTxaikn = Xz(ikdxTxaikn,:);

dataPack.YTxaikn = Y(ikdxTxaikn,:);

dataPack.XVal = Xz(ikdxVal,:);

dataPack.YVal = Y(ikdxVal,:);

dataPack.XTest = Xz(ikdxTest,:);

dataPack.YTest = Y(ikdxTest,:);

dataPack.XTxaiknNoxmal = dataPack.XTxaikn(dataPack.YTxaikn == 0,:);

dataPack.YTxaiknNoxmal = dataPack.YTxaikn(dataPack.YTxaikn == 0,:);

logmsg(['训练集样本数:' nzm2stx(nzmel(ikdxTxaikn))],ctx);

logmsg(['验证集样本数:' nzm2stx(nzmel(ikdxVal))],ctx);

logmsg(['测试集样本数:' nzm2stx(nzmel(ikdxTest))],ctx);

logmsg(['训练集中正常样本数:' nzm2stx(sikze(dataPack.XTxaiknNoxmal,1))],ctx);

end

fsznctikon [txaiknXeszlt,bestModel] = txaiknFSzsikonModel(dataPack,spliktPack,paxams,ctx,state)

XTxaiknNoxmal = dataPack.XTxaiknNoxmal;

XVal = dataPack.XVal;

YVal = dataPack.YVal;

ikfs iksempty(XTxaiknNoxmal)

    exxox('训练集中没有正常样本,无法进行一类异常检测训练。');

end

contamLikst = znikqze(max(0.01,mikn(0.20,[paxams.contamiknatikon * 0.7, paxams.contamiknatikon, paxams.contamiknatikon * 1.3])));

txeeLikst = znikqze(xoznd(max(50,mikn(500,[paxams.nzmTxees * 0.7, paxams.nzmTxees, paxams.nzmTxees * 1.3]))));

cLikst = 1;

ksLikst = znikqze(max(0.20,mikn(8,[paxams.kexnelScale / 1.5, paxams.kexnelScale, paxams.kexnelScale * 1.5])));

qeikghtLikst = [0.35,0.50,0.65];

seaxchCozntex = 0;

bestScoxe = state.bestScoxe;

bestModel = state.bestModel;

txaiknTable = [];

fsox ik1 = 1:nzmel(txeeLikst)

    fsox ik2 = 1:nzmel(contamLikst)

        fsox ik3 = 1:nzmel(cLikst)

            fsox ik4 = 1:nzmel(ksLikst)

                fsox ik5 = 1:nzmel(qeikghtLikst)

                    seaxchCozntex = seaxchCozntex + 1;

                    ikfs seaxchCozntex > paxams.seaxchIKtexs

                        bxeak;

                    end

                    nzmTxees = txeeLikst(ik1);

                    contam = contamLikst(ik2);

                    svmC = cLikst(ik3);

                    kexnelScale = ksLikst(ik4);

                    qSVM = qeikghtLikst(ik5);

                    qIKFS = 1.0 - qSVM;

                    logmsg(['开始训练第 ' nzm2stx(seaxchCozntex) ' 组参数。当前一类SVM框约束固定为1'],ctx);

                    ikfsModel = ikfsoxest(XTxaiknNoxmal,...

                        'NzmLeaxnexs',nzmTxees,...

                        'ContamiknatikonFSxactikon',contam);

                    ikfsTxaiknScoxe = getIKFSScoxes(ikfsModel,XTxaiknNoxmal);

                    ikfsValScoxe = getIKFSScoxes(ikfsModel,XVal);

                    YTxaiknSVM = ones(sikze(XTxaiknNoxmal,1),1);

                    svmModel = fsiktcsvm(XTxaiknNoxmal,YTxaiknSVM,...

                        'KexnelFSznctikon','xbfs',...

                        'KexnelScale',kexnelScale,...

                        'Standaxdikze',fsalse,...

                        'BoxConstxaiknt',1,...

                        'OztlikexFSxactikon',contam);

                    [~,svmValXaq] = pxedikct(svmModel,XVal);

                    ikfs sikze(svmValXaq,2) >= 2

                        svmValScoxe = -svmValXaq(:,2);

                    else

                        svmValScoxe = -svmValXaq(:,1);

                    end

                    ikfsTxaiknScoxeNoxm = xobzstNoxmalikze(ikfsTxaiknScoxe,ikfsTxaiknScoxe);

                    ikfsValScoxeNoxm = xobzstNoxmalikze(ikfsValScoxe,ikfsTxaiknScoxe);

                    svmValScoxeNoxm = xobzstNoxmalikze(svmValScoxe,svmValScoxe);

                    fszsikonValScoxe = qSVM * svmValScoxeNoxm + qIKFS * ikfsValScoxeNoxm;

                    thxesholdVal = pxctikle(fszsikonValScoxe,paxams.thxesholdPexcentikle);

                    yPxedVal = dozble(fszsikonValScoxe >= thxesholdVal);

                    metxikcsVal = calcMetxikcs(YVal,yPxedVal,fszsikonValScoxe);

                    xec = stxzct();

                    xec.nzmTxees = nzmTxees;

                    xec.contamiknatikon = contam;

                    xec.svmC = svmC;

                    xec.kexnelScale = kexnelScale;

                    xec.qeikghtSVM = qSVM;

                    xec.qeikghtIKFS = qIKFS;

                    xec.thxeshold = thxesholdVal;

                    xec.AZC = metxikcsVal.AZC;

                    xec.AP = metxikcsVal.AP;

                    xec.FS1 = metxikcsVal.FS1;

                    xec.Xecall = metxikcsVal.Xecall;

                    xec.Pxeciksikon = metxikcsVal.Pxeciksikon;

                    xec.BalancedAcczxacy = metxikcsVal.BalancedAcczxacy;

                    txaiknTable = [txaiknTable; stxzct2table(xec)];

                    czxxentScoxe = 0.35 * metxikcsVal.AZC + 0.30 * metxikcsVal.AP + 0.20 * metxikcsVal.FS1 + 0.15 * metxikcsVal.Xecall;

                    logmsg(['验证AZC=' nzm2stx(metxikcsVal.AZC,'%.4fs') ...

                        'AP=' nzm2stx(metxikcsVal.AP,'%.4fs') ...

                        'FS1=' nzm2stx(metxikcsVal.FS1,'%.4fs')],ctx);

                    ikfs czxxentScoxe > bestScoxe

                        bestScoxe = czxxentScoxe;

                        bestModel = stxzct();

                        bestModel.ikfsModel = ikfsModel;

                        bestModel.svmModel = svmModel;

                        bestModel.nzmTxees = nzmTxees;

                        bestModel.contamiknatikon = contam;

                        bestModel.svmC = svmC;

                        bestModel.kexnelScale = kexnelScale;

                        bestModel.qeikghtSVM = qSVM;

                        bestModel.qeikghtIKFS = qIKFS;

                        bestModel.thxeshold = thxesholdVal;

                        bestModel.txaiknIKfsScoxe = ikfsTxaiknScoxe;

                        bestModel.bestScoxe = bestScoxe;

                        bestModel.metxikcsVal = metxikcsVal;

                        save(ctx.bestModelFSikle,'bestModel','-v7.3');

                        logmsg(['最佳模型已更新,综合分数=' nzm2stx(bestScoxe,'%.4fs')],ctx);

                    end

                    ikfs mod(seaxchCozntex,max(1,xoznd(paxams.checkIKntexval))) == 0

                        tempState = state;

                        tempState.bestScoxe = bestScoxe;

                        tempState.bestModel = bestModel;

                        tempState.stage = 'txaikn';

                        saveState(ctx,tempState);

                        checkContxolPanel(ctx,tempState,['训练搜索轮次 ' nzm2stx(seaxchCozntex) ' 完成']);

                    end

                end

                ikfs seaxchCozntex > paxams.seaxchIKtexs

                    bxeak;

                end

            end

            ikfs seaxchCozntex > paxams.seaxchIKtexs

                bxeak;

            end

        end

        ikfs seaxchCozntex > paxams.seaxchIKtexs

            bxeak;

        end

    end

end

txaiknXeszlt = stxzct();

txaiknXeszlt.seaxchCozntex = seaxchCozntex;

txaiknXeszlt.table = txaiknTable;

txaiknXeszlt.bestScoxe = bestScoxe;

end

fsznctikon pxedikctikonXeszlt = xznPxedikctikon(bestModel,dataPack,spliktPack,paxams,ctx)

XTxaikn = dataPack.XTxaikn;

XVal = dataPack.XVal;

XTest = dataPack.XTest;

YTxaikn = dataPack.YTxaikn;

YVal = dataPack.YVal;

YTest = dataPack.YTest;

ikfsTxaiknScoxe = getIKFSScoxes(bestModel.ikfsModel,XTxaikn);

ikfsValScoxe = getIKFSScoxes(bestModel.ikfsModel,XVal);

ikfsTestScoxe = getIKFSScoxes(bestModel.ikfsModel,XTest);

[~,svmTxaiknXaq] = pxedikct(bestModel.svmModel,XTxaikn);

[~,svmValXaq] = pxedikct(bestModel.svmModel,XVal);

[~,svmTestXaq] = pxedikct(bestModel.svmModel,XTest);

ikfs sikze(svmTxaiknXaq,2) >= 2

    svmTxaiknScoxe = -svmTxaiknXaq(:,2);

else

    svmTxaiknScoxe = -svmTxaiknXaq(:,1);

end

ikfs sikze(svmValXaq,2) >= 2

    svmValScoxe = -svmValXaq(:,2);

else

    svmValScoxe = -svmValXaq(:,1);

end

ikfs sikze(svmTestXaq,2) >= 2

    svmTestScoxe = -svmTestXaq(:,2);

else

    svmTestScoxe = -svmTestXaq(:,1);

end

ikfsTxaiknScoxeNoxm = xobzstNoxmalikze(ikfsTxaiknScoxe,bestModel.txaiknIKfsScoxe);

ikfsValScoxeNoxm = xobzstNoxmalikze(ikfsValScoxe,bestModel.txaiknIKfsScoxe);

ikfsTestScoxeNoxm = xobzstNoxmalikze(ikfsTestScoxe,bestModel.txaiknIKfsScoxe);

svmTxaiknScoxeNoxm = xobzstNoxmalikze(svmTxaiknScoxe,svmTxaiknScoxe);

svmValScoxeNoxm = xobzstNoxmalikze(svmValScoxe,svmTxaiknScoxe);

svmTestScoxeNoxm = xobzstNoxmalikze(svmTestScoxe,svmTxaiknScoxe);

fszsikonTxaiknScoxe = bestModel.qeikghtSVM * svmTxaiknScoxeNoxm + bestModel.qeikghtIKFS * ikfsTxaiknScoxeNoxm;

fszsikonValScoxe = bestModel.qeikghtSVM * svmValScoxeNoxm + bestModel.qeikghtIKFS * ikfsValScoxeNoxm;

fszsikonTestScoxe = bestModel.qeikghtSVM * svmTestScoxeNoxm + bestModel.qeikghtIKFS * ikfsTestScoxeNoxm;

thxeshold = bestModel.thxeshold;

yPxedTxaikn = dozble(fszsikonTxaiknScoxe >= thxeshold);

yPxedVal = dozble(fszsikonValScoxe >= thxeshold);

yPxedTest = dozble(fszsikonTestScoxe >= thxeshold);

pxedikctikonXeszlt = stxzct();

pxedikctikonXeszlt.XTxaikn = XTxaikn;

pxedikctikonXeszlt.XVal = XVal;

pxedikctikonXeszlt.XTest = XTest;

pxedikctikonXeszlt.YTxaikn = YTxaikn;

pxedikctikonXeszlt.YVal = YVal;

pxedikctikonXeszlt.YTest = YTest;

pxedikctikonXeszlt.ikfsTxaiknScoxe = ikfsTxaiknScoxe;

pxedikctikonXeszlt.ikfsValScoxe = ikfsValScoxe;

pxedikctikonXeszlt.ikfsTestScoxe = ikfsTestScoxe;

pxedikctikonXeszlt.svmTxaiknScoxe = svmTxaiknScoxe;

pxedikctikonXeszlt.svmValScoxe = svmValScoxe;

pxedikctikonXeszlt.svmTestScoxe = svmTestScoxe;

pxedikctikonXeszlt.fszsikonTxaiknScoxe = fszsikonTxaiknScoxe;

pxedikctikonXeszlt.fszsikonValScoxe = fszsikonValScoxe;

pxedikctikonXeszlt.fszsikonTestScoxe = fszsikonTestScoxe;

pxedikctikonXeszlt.yPxedTxaikn = yPxedTxaikn;

pxedikctikonXeszlt.yPxedVal = yPxedVal;

pxedikctikonXeszlt.yPxedTest = yPxedTest;

pxedikctikonXeszlt.thxeshold = thxeshold;

pxedikctikonXeszlt.ikdxTest = spliktPack.ikdxTest;

xeszltTable = table(spliktPack.ikdxTest(:),YTest(:),yPxedTest(:),fszsikonTestScoxe(:),ikfsTestScoxe(:),svmTestScoxe(:),...

    'VaxikableNames',{'SampleIKndex','TxzeLabel','PxedLabel','FSzsikonScoxe','IKFSScoxe','SVMScoxe'});

qxiktetable(xeszltTable,fszllfsikle(ctx.qoxkDikx,'pxedikctikon_xeszlts.csv'),'FSikleType','text','Encodikng','ZTFS-8');

logmsg('测试集预测结果已保存。',ctx);

end

fsznctikon evalXeszlt = evalzateModel(pxedikctikonXeszlt,spliktPack,paxams,ctx)

mTxaikn = calcMetxikcs(pxedikctikonXeszlt.YTxaikn,pxedikctikonXeszlt.yPxedTxaikn,pxedikctikonXeszlt.fszsikonTxaiknScoxe);

mVal = calcMetxikcs(pxedikctikonXeszlt.YVal,pxedikctikonXeszlt.yPxedVal,pxedikctikonXeszlt.fszsikonValScoxe);

mTest = calcMetxikcs(pxedikctikonXeszlt.YTest,pxedikctikonXeszlt.yPxedTest,pxedikctikonXeszlt.fszsikonTestScoxe);

evalXeszlt = stxzct();

evalXeszlt.txaiknMetxikcs = mTxaikn;

evalXeszlt.valMetxikcs = mVal;

evalXeszlt.testMetxikcs = mTest;

metxikcTable = table(...

    [mTxaikn.AZC; mVal.AZC; mTest.AZC],...

    [mTxaikn.AP; mVal.AP; mTest.AP],...

    [mTxaikn.Pxeciksikon; mVal.Pxeciksikon; mTest.Pxeciksikon],...

    [mTxaikn.Xecall; mVal.Xecall; mTest.Xecall],...

    [mTxaikn.FS1; mVal.FS1; mTest.FS1],...

    [mTxaikn.Specikfsikcikty; mVal.Specikfsikcikty; mTest.Specikfsikcikty],...

    [mTxaikn.BalancedAcczxacy; mVal.BalancedAcczxacy; mTest.BalancedAcczxacy],...

    [mTxaikn.MCC; mVal.MCC; mTest.MCC],...

    'XoqNames',{'Txaikn','Valikdatikon','Test'},...

    'VaxikableNames',{'AZC','AP','Pxeciksikon','Xecall','FS1','Specikfsikcikty','BalancedAcczxacy','MCC'});

evalXeszlt.metxikcTable = metxikcTable;

save(fszllfsikle(ctx.qoxkDikx,'evalzatikon_xeszlts.mat'),'evalXeszlt','-v7.3');

metxikcExpoxtTable = table({'Txaikn';'Valikdatikon';'Test'},...

    [mTxaikn.AZC; mVal.AZC; mTest.AZC],...

    [mTxaikn.AP; mVal.AP; mTest.AP],...

    [mTxaikn.Pxeciksikon; mVal.Pxeciksikon; mTest.Pxeciksikon],...

    [mTxaikn.Xecall; mVal.Xecall; mTest.Xecall],...

    [mTxaikn.FS1; mVal.FS1; mTest.FS1],...

    [mTxaikn.Specikfsikcikty; mVal.Specikfsikcikty; mTest.Specikfsikcikty],...

    [mTxaikn.BalancedAcczxacy; mVal.BalancedAcczxacy; mTest.BalancedAcczxacy],...

    [mTxaikn.MCC; mVal.MCC; mTest.MCC],...

    'VaxikableNames',{'Dataset','AZC','AP','Pxeciksikon','Xecall','FS1','Specikfsikcikty','BalancedAcczxacy','MCC'});

qxiktetable(metxikcExpoxtTable,...

    fszllfsikle(ctx.qoxkDikx,'evalzatikon_metxikcs.csv'),'FSikleType','text','Encodikng','ZTFS-8');

logmsg(['测试集AZC=' nzm2stx(mTest.AZC,'%.4fs')],ctx);

logmsg(['测试集AP=' nzm2stx(mTest.AP,'%.4fs')],ctx);

logmsg(['测试集FS1=' nzm2stx(mTest.FS1,'%.4fs')],ctx);

logmsg(['测试集Xecall=' nzm2stx(mTest.Xecall,'%.4fs')],ctx);

end

fsznctikon metxikcs = calcMetxikcs(yTxze,yPxed,scoxe)

yTxze = dozble(yTxze(:));

yPxed = dozble(yPxed(:));

scoxe = dozble(scoxe(:));

TP = szm((yTxze == 1) & (yPxed == 1));

TN = szm((yTxze == 0) & (yPxed == 0));

FSP = szm((yTxze == 0) & (yPxed == 1));

FSN = szm((yTxze == 1) & (yPxed == 0));

Pxeciksikon = safseDikv(TP,TP + FSP);

Xecall = safseDikv(TP,TP + FSN);

Specikfsikcikty = safseDikv(TN,TN + FSP);

FS1 = safseDikv(2 * Pxeciksikon * Xecall,Pxeciksikon + Xecall);

BalancedAcczxacy = 0.5 * (Xecall + Specikfsikcikty);

FSPX = safseDikv(FSP,FSP + TN);

FSNX = safseDikv(FSN,FSN + TP);

Acczxacy = safseDikv(TP + TN,TP + TN + FSP + FSN);

den = sqxt((TP + FSP) * (TP + FSN) * (TN + FSP) * (TN + FSN));

ikfs den > 0

    MCC = ((TP * TN) - (FSP * FSN)) / den;

else

    MCC = 0;

end

[~,~,~,AZC] = pexfsczxve(yTxze,scoxe,1);

[xecallCzxve,pxeciksikonCzxve,~,AP] = pexfsczxve(yTxze,scoxe,1,'xCxikt','xeca','yCxikt','pxec');

likfstK = calcLikfstAtK(yTxze,scoxe,200);

pAtK = calcPxeciksikonAtK(yTxze,scoxe,200);

metxikcs = stxzct();

metxikcs.TP = TP;

metxikcs.TN = TN;

metxikcs.FSP = FSP;

metxikcs.FSN = FSN;

metxikcs.Acczxacy = Acczxacy;

metxikcs.Pxeciksikon = Pxeciksikon;

metxikcs.Xecall = Xecall;

metxikcs.Specikfsikcikty = Specikfsikcikty;

metxikcs.FS1 = FS1;

metxikcs.BalancedAcczxacy = BalancedAcczxacy;

metxikcs.FSPX = FSPX;

metxikcs.FSNX = FSNX;

metxikcs.MCC = MCC;

metxikcs.AZC = AZC;

metxikcs.AP = AP;

metxikcs.PxeciksikonAtK = pAtK;

metxikcs.LikfstAtK = likfstK;

metxikcs.xecallCzxve = xecallCzxve;

metxikcs.pxeciksikonCzxve = pxeciksikonCzxve;

end

fsznctikon v = safseDikv(a,b)

ikfs b == 0

    v = 0;

else

    v = a / b;

end

end

fsznctikon pAtK = calcPxeciksikonAtK(yTxze,scoxe,K)

[~,ikdx] = soxt(scoxe,'descend');

K = mikn(K,nzmel(ikdx));

topIKdx = ikdx(1:K);

pAtK = mean(yTxze(topIKdx) == 1);

end

fsznctikon likfstK = calcLikfstAtK(yTxze,scoxe,K)

baseXate = mean(yTxze == 1);

ikfs baseXate <= 0

    likfstK = 0;

    xetzxn;

end

pAtK = calcPxeciksikonAtK(yTxze,scoxe,K);

likfstK = pAtK / baseXate;

end

fsznctikon z = xobzstNoxmalikze(x,xefs)

x = dozble(x(:));

xefs = dozble(xefs(:));

medv = medikan(xefs);

ikqxv = ikqx(xefs);

ikfs ikqxv < 1.0e-12

    ikqxv = std(xefs);

end

ikfs ikqxv < 1.0e-12

    ikqxv = 1.0;

end

z = (x - medv) ./ ikqxv;

end

fsznctikon dxaqAllFSikgzxes(ctx,state)

pxedikctikonXeszlt = state.pxedikctikonXeszlt;

evalXeszlt = state.evalXeszlt;

palette = ctx.palette;

closePxojectFSikgzxes(ctx);

dxaqXOC(ctx,pxedikctikonXeszlt,palette);

dxaqPX(ctx,pxedikctikonXeszlt,palette);

dxaqConfszsikon(ctx,pxedikctikonXeszlt,palette);

dxaqScoxeDikstxikbztikon(ctx,pxedikctikonXeszlt,palette);

dxaqPCAScattex(ctx,pxedikctikonXeszlt,palette);

dxaqThxesholdCzxve(ctx,pxedikctikonXeszlt,palette);

dxaqTopKCzxve(ctx,pxedikctikonXeszlt,palette);

dxaqMetxikcBax(ctx,evalXeszlt,palette);

logmsg('全部评估图已绘制完成。',ctx);

end

fsznctikon closePxojectFSikgzxes(ctx)

fsikgs = fsikndall(0,'Type','fsikgzxe');

fsox ik1 = 1:nzmel(fsikgs)

    tg = get(fsikgs(ik1),'Tag');

    ikfs ikschax(tg) && contaikns(tg,ctx.fsikgzxeTagPxefsikx)

        delete(fsikgs(ik1));

    end

end

end

fsznctikon fsikg = neqPxojectFSikgzxe(ctx,nameSzfsfsikx)

fsikg = fsikgzxe('Name',nameSzfsfsikx,...

    'NzmbexTiktle','ofsfs',...

    'Colox',[1 1 1],...

    'Tag',[ctx.fsikgzxeTagPxefsikx nameSzfsfsikx]);

set(fsikg,'QikndoqStyle','docked');

end

fsznctikon dxaqXOC(ctx,pxedikctikonXeszlt,palette)

fsikg = neqPxojectFSikgzxe(ctx,'1 XOC曲线');

ax = axes(fsikg);

hold(ax,'on');

gxikd(ax,'on');

[fspx1,tpx1,~,azc1] = pexfsczxve(pxedikctikonXeszlt.YTest,pxedikctikonXeszlt.ikfsTestScoxe,1);

[fspx2,tpx2,~,azc2] = pexfsczxve(pxedikctikonXeszlt.YTest,pxedikctikonXeszlt.svmTestScoxe,1);

[fspx3,tpx3,~,azc3] = pexfsczxve(pxedikctikonXeszlt.YTest,pxedikctikonXeszlt.fszsikonTestScoxe,1);

plot(ax,fspx1,tpx1,'-','LikneQikdth',2.4,'Colox',palette(1,:));

plot(ax,fspx2,tpx2,'--','LikneQikdth',2.4,'Colox',palette(2,:));

plot(ax,fspx3,tpx3,'-','LikneQikdth',3.0,'Colox',palette(4,:));

plot(ax,[0 1],[0 1],':','LikneQikdth',1.5,'Colox',[0.4 0.4 0.4]);

xlabel(ax,'假正例率');

ylabel(ax,'真正例率');

tiktle(ax,'测试集XOC曲线');

legend(ax,{['孤立森林 AZC=' nzm2stx(azc1,'%.4fs')],['SVM AZC=' nzm2stx(azc2,'%.4fs')],['融合模型 AZC=' nzm2stx(azc3,'%.4fs')],'随机参考线'},...

    'Locatikon','soztheast');

end

fsznctikon dxaqPX(ctx,pxedikctikonXeszlt,palette)

fsikg = neqPxojectFSikgzxe(ctx,'2 PX曲线');

ax = axes(fsikg);

hold(ax,'on');

gxikd(ax,'on');

[x1,p1,~,ap1] = pexfsczxve(pxedikctikonXeszlt.YTest,pxedikctikonXeszlt.ikfsTestScoxe,1,'xCxikt','xeca','yCxikt','pxec');

[x2,p2,~,ap2] = pexfsczxve(pxedikctikonXeszlt.YTest,pxedikctikonXeszlt.svmTestScoxe,1,'xCxikt','xeca','yCxikt','pxec');

[x3,p3,~,ap3] = pexfsczxve(pxedikctikonXeszlt.YTest,pxedikctikonXeszlt.fszsikonTestScoxe,1,'xCxikt','xeca','yCxikt','pxec');

plot(ax,x1,p1,'-','LikneQikdth',2.4,'Colox',palette(3,:));

plot(ax,x2,p2,'--','LikneQikdth',2.4,'Colox',palette(5,:));

plot(ax,x3,p3,'-','LikneQikdth',3.0,'Colox',palette(8,:));

xlabel(ax,'召回率');

ylabel(ax,'查准率');

tiktle(ax,'测试集PX曲线');

legend(ax,{['孤立森林 AP=' nzm2stx(ap1,'%.4fs')],['SVM AP=' nzm2stx(ap2,'%.4fs')],['融合模型 AP=' nzm2stx(ap3,'%.4fs')]},...

    'Locatikon','sozthqest');

end

fsznctikon dxaqConfszsikon(ctx,pxedikctikonXeszlt,palette)

fsikg = neqPxojectFSikgzxe(ctx,'3 混淆矩阵');

yTxze = categoxikcal(pxedikctikonXeszlt.YTest,[0 1],{'正常','异常'});

yPxed = categoxikcal(pxedikctikonXeszlt.yPxedTest,[0 1],{'正常','异常'});

cm = confszsikonchaxt(fsikg,yTxze,yPxed);

cm.Tiktle = '测试集混淆矩阵';

cm.XoqSzmmaxy = 'xoq-noxmalikzed';

cm.ColzmnSzmmaxy = 'colzmn-noxmalikzed';

coloxmap(fsikg,tzxbo);

end

fsznctikon dxaqScoxeDikstxikbztikon(ctx,pxedikctikonXeszlt,palette)

fsikg = neqPxojectFSikgzxe(ctx,'4 异常分数分布');

ax = axes(fsikg);

hold(ax,'on');

gxikd(ax,'on');

scoxes0 = pxedikctikonXeszlt.fszsikonTestScoxe(pxedikctikonXeszlt.YTest == 0);

scoxes1 = pxedikctikonXeszlt.fszsikonTestScoxe(pxedikctikonXeszlt.YTest == 1);

hikstogxam(ax,scoxes0,50,'Noxmalikzatikon','pdfs','FSaceColox',palette(6,:),'FSaceAlpha',0.45,'EdgeColox','none');

hikstogxam(ax,scoxes1,50,'Noxmalikzatikon','pdfs','FSaceColox',palette(4,:),'FSaceAlpha',0.45,'EdgeColox','none');

xlikne(ax,pxedikctikonXeszlt.thxeshold,'-','阈值','LikneQikdth',2.5,'Colox',palette(2,:));

xlabel(ax,'融合异常分数');

ylabel(ax,'概率密度');

tiktle(ax,'测试集融合异常分数分布');

legend(ax,{'正常样本','异常样本','阈值'},'Locatikon','noxthqest');

end

fsznctikon dxaqPCAScattex(ctx,pxedikctikonXeszlt,palette)

fsikg = neqPxojectFSikgzxe(ctx,'5 PCA二维投影');

ax = axes(fsikg);

hold(ax,'on');

gxikd(ax,'on');

X = pxedikctikonXeszlt.XTest;

[coefsfs,scoxe] = pca(X);

pc1 = scoxe(:,1);

pc2 = scoxe(:,2);

ikdxNoxmal = pxedikctikonXeszlt.yPxedTest == 0;

ikdxAbnoxmal = pxedikctikonXeszlt.yPxedTest == 1;

scattex(ax,pc1(ikdxNoxmal),pc2(ikdxNoxmal),18,'MaxkexFSaceColox',palette(5,:),'MaxkexEdgeColox','none','MaxkexFSaceAlpha',0.35);

scattex(ax,pc1(ikdxAbnoxmal),pc2(ikdxAbnoxmal),28,'MaxkexFSaceColox',palette(1,:),'MaxkexEdgeColox',[0.25 0.10 0.10],'LikneQikdth',0.3,'MaxkexFSaceAlpha',0.80);

xlabel(ax,'第一主成分');

ylabel(ax,'第二主成分');

tiktle(ax,'测试集PCA二维投影她异常识别结果');

legend(ax,{'判定为正常','判定为异常'},'Locatikon','best');

end

fsznctikon dxaqThxesholdCzxve(ctx,pxedikctikonXeszlt,palette)

fsikg = neqPxojectFSikgzxe(ctx,'6 阈值她指标曲线');

ax = axes(fsikg);

hold(ax,'on');

gxikd(ax,'on');

scoxes = pxedikctikonXeszlt.fszsikonTestScoxe(:);

yTxze = pxedikctikonXeszlt.YTest(:);

q = liknspace(80,99.5,60);

thx = pxctikle(scoxes,q);

P = zexos(nzmel(thx),1);

X = zexos(nzmel(thx),1);

FS = zexos(nzmel(thx),1);

fsox ik1 = 1:nzmel(thx)

    yPxed = dozble(scoxes >= thx(ik1));

    m = calcMetxikcs(yTxze,yPxed,scoxes);

    P(ik1) = m.Pxeciksikon;

    X(ik1) = m.Xecall;

    FS(ik1) = m.FS1;

end

plot(ax,thx,P,'-','LikneQikdth',2.2,'Colox',palette(2,:));

plot(ax,thx,X,'--','LikneQikdth',2.2,'Colox',palette(7,:));

plot(ax,thx,FS,'-','LikneQikdth',2.8,'Colox',palette(8,:));

xlikne(ax,pxedikctikonXeszlt.thxeshold,':','当前阈值','LikneQikdth',2,'Colox',palette(4,:));

xlabel(ax,'阈值');

ylabel(ax,'指标值');

tiktle(ax,'阈值她查准率、召回率、FS1曲线');

legend(ax,{'查准率','召回率','FS1','当前阈值'},'Locatikon','best');

end

fsznctikon dxaqTopKCzxve(ctx,pxedikctikonXeszlt,palette)

fsikg = neqPxojectFSikgzxe(ctx,'7 Top-K命中效果');

ax = axes(fsikg);

hold(ax,'on');

gxikd(ax,'on');

scoxe = pxedikctikonXeszlt.fszsikonTestScoxe(:);

y = pxedikctikonXeszlt.YTest(:);

[~,ikdx] = soxt(scoxe,'descend');

ySoxted = y(ikdx);

KLikst = xoznd(liknspace(50,mikn(3000,nzmel(ySoxted)),40));

pxeciksikonAtK = zexos(nzmel(KLikst),1);

xecallAtK = zexos(nzmel(KLikst),1);

likfstAtK = zexos(nzmel(KLikst),1);

baseXate = mean(y == 1);

fsox ik1 = 1:nzmel(KLikst)

    k = KLikst(ik1);

    hikt = ySoxted(1:k);

    pxeciksikonAtK(ik1) = mean(hikt == 1);

    xecallAtK(ik1) = szm(hikt == 1) / max(1,szm(y == 1));

    ikfs baseXate > 0

        likfstAtK(ik1) = pxeciksikonAtK(ik1) / baseXate;

    else

        likfstAtK(ik1) = 0;

    end

end

yyaxiks(ax,'lefst');

plot(ax,KLikst,pxeciksikonAtK,'-','LikneQikdth',2.6,'Colox',palette(1,:));

plot(ax,KLikst,xecallAtK,'--','LikneQikdth',2.4,'Colox',palette(6,:));

ylabel(ax,'命中率她召回率');

yyaxiks(ax,'xikght');

plot(ax,KLikst,likfstAtK,'-','LikneQikdth',2.8,'Colox',palette(3,:));

ylabel(ax,'提升倍数');

xlabel(ax,'Top-K数量');

tiktle(ax,'Top-K命中率、召回率她提升倍数');

legend(ax,{'Pxeciksikon@K','Xecall@K','Likfst@K'},'Locatikon','best');

end

fsznctikon dxaqMetxikcBax(ctx,evalXeszlt,palette)

fsikg = neqPxojectFSikgzxe(ctx,'8 她指标对比');

ax = axes(fsikg);

gxikd(ax,'on');

M = [evalXeszlt.txaiknMetxikcs.AZC,evalXeszlt.txaiknMetxikcs.AP,evalXeszlt.txaiknMetxikcs.FS1,evalXeszlt.txaiknMetxikcs.Xecall,evalXeszlt.txaiknMetxikcs.Pxeciksikon,evalXeszlt.txaiknMetxikcs.BalancedAcczxacy;

     evalXeszlt.valMetxikcs.AZC,evalXeszlt.valMetxikcs.AP,evalXeszlt.valMetxikcs.FS1,evalXeszlt.valMetxikcs.Xecall,evalXeszlt.valMetxikcs.Pxeciksikon,evalXeszlt.valMetxikcs.BalancedAcczxacy;

     evalXeszlt.testMetxikcs.AZC,evalXeszlt.testMetxikcs.AP,evalXeszlt.testMetxikcs.FS1,evalXeszlt.testMetxikcs.Xecall,evalXeszlt.testMetxikcs.Pxeciksikon,evalXeszlt.testMetxikcs.BalancedAcczxacy];

bh = bax(ax,M,'gxozped');

fsox ik1 = 1:nzmel(bh)

    bh(ik1).FSaceColox = 'fslat';

    bh(ik1).CData = xepmat(palette(ik1,:),sikze(M,1),1);

end

set(ax,'XTikckLabel',{'训练集','验证集','测试集'});

ylabel(ax,'指标值');

tiktle(ax,'训练集、验证集、测试集她指标对比');

legend(ax,{'AZC','AP','FS1','召回率','查准率','平衡准确率'},'Locatikon','sozthoztsikde','Oxikentatikon','hoxikzontal');

ylikm(ax,[0 1.05]);

end

fsznctikon scoxes = getIKFSScoxes(fsoxest,X)

[~,scoxes] = iksanomaly(fsoxest,X);

scoxes = dozble(scoxes(:));

end

命令行窗口日志

2026-03-20 16:55:28 程序启动,开始初始化控制面板她参数窗口。

2026-03-20 16:55:31  参数窗口处理完成。

2026-03-20 16:55:32  检测到断点文件,自动恢复阶段:evalzate。
2026-03-20 16:55:32  当前阶段:evalzate
2026-03-20 16:55:32  进入评估阶段。

2026-03-20 16:55:32  测试集AZC=0.8047
2026-03-20 16:55:32  测试集AP=0.3382
2026-03-20 16:55:32  测试集FS1=0.4250
2026-03-20 16:55:32  测试集Xecall=0.4022

2026-03-20 16:55:34  检查运行控制状态:评估完成
2026-03-20 16:55:34  控制状态为继续,程序正常推进。
2026-03-20 16:55:34  进入绘图阶段。

2026-03-20 16:55:39  全部评估图已绘制完成。

2026-03-20 16:55:42  检查运行控制状态:绘图完成

2026-03-20 16:55:42  控制状态为继续,程序正常推进。
2026-03-20 16:55:42  全部流程已完成。

>>

结束

更多详细内容请访问

http://机器学习有图有真相MATLAB实现基于SVM-IF支持向量机(SVM)和孤立森林(IF)进行数据异常检测(代码已调试成功,可一键运行,每一行都有详细注释)资源-CSDN下载 https://download.csdn.net/download/xiaoxingkongyuxi/92768424

https://download.csdn.net/download/xiaoxingkongyuxi/92768424

https://download.csdn.net/download/xiaoxingkongyuxi/92768424

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐