【matlab】绘制maxENT模型的ROC曲线和omission curve
文章目录
- 一、maxENT模型
- 二、ROC曲线
- 三、实操
- 3.1 数据提取
- 3.2 绘制ROC曲线
- 3.3 绘制遗漏曲线
- 3.4 多次训练的ROC和测试的ROC
一、maxENT模型
前面的文章已经详细讲过了。
maxENT软件运行后,会生成一个html报告,里面有ROC曲线,但我们往往需要自己画图,设计一下样式,而不是直接使用输出的图像。
二、ROC曲线
ROC 曲线,即受试者工作特征曲线(Receiver Operating Characteristic Curve
),是用来评估二分类模型性能的重要工具。
-
二分类决策:在二分类模型中,模型通常根据某个阈值(threshold)将样本预测为正例或负例。调整这个阈值会影响预测结果,从而改变模型的敏感性(正确识别正例的能力)和特异性(正确排除负例的能力)。
-
混淆矩阵要素:
- 真阳性(TP):被正确预测为正例的样本数量。
- 真阴性(TN):被正确预测为负例的样本数量。
- 假阳性(FP):被错误预测为正例的负样本数量。
- 假阴性(FN):被错误预测为负例的正样本数量。
🔹主要指标
-
真正率(True Positive Rate, TPR):也称为敏感性或召回率,计算公式为
T P R = T P T P + F N TPR = \frac{TP}{TP + FN} TPR=TP+FNTP
该指标反映模型检测到正类的比例。
-
假正率(False Positive Rate, FPR):计算公式为
F P R = F P F P + T N FPR = \frac{FP}{FP + TN} FPR=FP+TNFP
该指标反映在所有负样本中误判为正样本的比例。
在 ROC 曲线上,TPR 是纵轴,而 FPR 是横轴。
❄️ 如何绘制 ROC 曲线
- 设置不同阈值:对于一个分类器,可以从 0 到 1 选择若干不同的概率阈值。
- 计算指标:对于每个阈值,依据预测结果计算对应的 TPR 和 FPR。
- 绘图:将
每个阈值
对应的 (FPR, TPR) 点在二维坐标系中描绘出来,并连接这些点,形成一条曲线。
随着阈值的变化:
- 当阈值很高时,模型较为严格,只预测非常有信心的样本为正例,此时 TPR 较低,FPR 也较低。
- 当阈值很低时,更多样本被预测为正例,TPR 提高,但同时 FPR 也会上升。
☘️曲线下的面积(AUC)
- AUC(Area Under the Curve):ROC 曲线下的面积代表了模型的整体区分能力。
- AUC = 1:理想模型,能完美区分正负样本。
- AUC = 0.5:与随机猜测相当,说明模型没有区分能力。
AUC 数值越大,说明模型在不同阈值下保持了较高的 TPR 同时控制了 FPR 的上升,表现越优。
🗝️ROC 曲线的应用与特点
- 独立于样本类别分布:与精确度(accuracy)不同,ROC 曲线上各点的计算不受类别比例影响,对于类别分布不平衡的问题,ROC 依然能有效反映模型性能。
- 决策阈值选择:通过 ROC 曲线,可以直观地看到在不同阈值下模型的表现,从而帮助选择一个合适的平衡点。例如,在医疗诊断中,可能更倾向于降低假阴性(提高 TPR),即使假阳性(FPR)上升。
- 模型比较:当需要比较多个模型时,ROC 曲线及其 AUC 值可以作为一个统一的指标。如果一条 ROC 曲线始终在另一条之上,那么前者所对应的模型通常表现更好。
三、实操
3.1 数据提取
首先是maxENT软件的设置,上上篇文章末尾写了。
比如:第三列(最后一张图)那个:
Write background predictions
选项可以选上,我截图的时候没选择。这个输出数据可以用来自己话ROC曲线。
我设置模型运行10次,输出文件夹里面会有10对这样的文件:当然还有其它文件,这些是画图需要的。
我预测了多个物种的适生区,每个10次,取均值。
所以首先要根据物种,把csv文件提取出来。代码示例:
%% 提取maxent多次训练后的输出csv并按物种分别保存%%
clear
clc% 设置源文件夹路径和目标文件夹路径
sourceFolder = 'xxx'; % 这里填写源文件夹路径
destinationFolder = 'xxx'; % 这里填写目标文件夹路径% 获取源文件夹中所有csv文件
csvFiles = dir(fullfile(sourceFolder, '*.csv'));% 遍历所有文件
for i = 1:length(csvFiles)% 获取文件名fileName = csvFiles(i).name;% 检查文件名是否包含 backgroundPredictions 或 samplePredictionsif contains(fileName, 'backgroundPredictions') || contains(fileName, 'samplePredictions')% 使用正则表达式提取动物名称(保留中间的下划线,去除尾部的下划线)animalName = regexp(fileName, '^[a-zA-Z_]+(?=\d)', 'match', 'once');% 去除末尾的下划线(如果有)if animalName(end) == '_'animalName = animalName(1:end-1);end% 创建以动物名称命名的目标文件夹,如果文件夹不存在则创建animalFolder = fullfile(destinationFolder, animalName);if ~exist(animalFolder, 'dir')mkdir(animalFolder);end% 复制文件到相应的文件夹copyfile(fullfile(sourceFolder, fileName), fullfile(animalFolder, fileName));end
enddisp('文件复制完成');
执行后,会有一个data(假设)文件夹,文件夹下面每个物种有一个文件夹,文件夹里面是10对csv数据。
3.2 绘制ROC曲线
这是一次预测的曲线,不是多次预测的平均:
%% 1. 读取数据clear
clcpresence = readtable('xxx_samplePredictions.csv',VariableNamingRule='preserve');
background = readtable('xxx_backgroundPredictions.csv',VariableNamingRule='preserve');% 属性名设置
presence.Properties.VariableNames = strrep(presence.Properties.VariableNames, ' ', '_');
background.Properties.VariableNames = strrep(background.Properties.VariableNames, ' ', '_');%% 2. 计算AUC% 提取预测值
pp = presence.Cloglog_prediction; % presence 数据中的预测
bb = background.Cloglog; % background 数据中的预测% 测试集 AUC
testpp = pp(presence.Test_or_train == "test");
combined = [testpp; bb];
label = [ones(length(testpp), 1); zeros(length(bb), 1)];
[~, ~, ~, AUC_test] = perfcurve(label, combined, 1);% 训练集 AUC
trainpp = pp(presence.Test_or_train == "train");
combined_train = [trainpp; bb];
label_train = [ones(length(trainpp), 1); zeros(length(bb), 1)];
[~, ~, ~, AUC_train] = perfcurve(label_train, combined_train, 1);% 输出 AUC 值
disp(['Test AUC: ', num2str(AUC_test)]);
disp(['Train AUC: ', num2str(AUC_train)]);%% 3. 绘制 ROC 曲线
[X_test, Y_test, ~, ~] = perfcurve(label, combined, 1);
[X_train, Y_train, ~, ~] = perfcurve(label_train, combined_train, 1);figure;
plot(X_test, Y_test, 'Color', '#5EC1C7', 'LineWidth', 1.5); % 测试集 ROC
hold on;
plot(X_train, Y_train, 'Color', '#DA4A22', 'LineWidth', 1.5); % 训练集 ROC
plot([0, 1], [0, 1], 'k--'); % 对角线
xlabel('1 - Specificity');
ylabel('Sensitivity');
title('ROC Curve');
legend({'Test Set', 'Train Set', 'Random'}, 'Location', 'Best');
ylim([0 1.1])
grid minor;
hold off;
3.3 绘制遗漏曲线
maxENT的输出称作:omission curve
这个数据使用的是模型输出文件夹里面的,上面的代码没有提取。这里只是示例。
%% 4. 绘制遗漏曲线% 读取遗漏数据
omission = readtable('xxx_omission.csv',VariableNamingRule='preserve');
omission.Properties.VariableNames = strrep(omission.Properties.VariableNames, ' ', '_');% 绘制遗漏曲线
figure;
plot(omission.Corresponding_cumulative_value, omission.Fractional_area, 'Color', '#DA4A22', 'LineWidth', 1.5); % Fractional area
hold on;
plot(omission.Corresponding_cumulative_value, omission.Test_omission, 'Color', '#5EC1C7', 'LineWidth', 1.5); % Test omission
plot(omission.Corresponding_cumulative_value, omission.Training_omission, 'Color', '#9EC735', 'LineWidth', 1.5); % Training omission
plot([0, 100], [0, 1], 'k--'); % 对角线
xlabel('Cumulative threshold');
ylabel('Fractional value');
title('Omission Curve');
legend({'Fractional Area', 'Test Omission', 'Training Omission', 'Random'}, 'Location', 'Best');
grid minor;
hold off;
3.4 多次训练的ROC和测试的ROC
这个不免费了,价格10快,愿意就Buy,如果你需要的话还是很值的,我也不能用爱发电哈哈🤭。
URL:https://mbd.pub/o/bread/aJqclJ9y
绘制效果:
maxENT的报告绘制的:这两个都是训练的ROC曲线,我的代码还有测试的ROC曲线(maxENT报告没有)。