文章目錄
- 一、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報告沒有)。