import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams['axes.unicode_minus'] = False

df = pd.read_csv("Dataset.csv")
df.head()

加載?“Dataset.csv” 數(shù)據(jù)集并顯示其前幾行,此數(shù)據(jù)集為一個二分類數(shù)據(jù)集

數(shù)據(jù)分割

from sklearn.model_selection import train_test_split

X = df.drop(['target'], axis=1)
y = df['target']

# 分割數(shù)據(jù)集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,
random_state=42, stratify=df['target'])

將數(shù)據(jù)集分為特征變量 X 和目標變量 y,然后使用 train_test_split 函數(shù)按 80% 訓(xùn)練集和 20% 測試集的比例將數(shù)據(jù)集進行分割,同時使用 stratify 參數(shù)確保目標變量 target 在訓(xùn)練集和測試集中的分布一致

模型構(gòu)建

from sklearn.ensemble import RandomForestClassifier

# 構(gòu)建隨機森林模型,并設(shè)置多個參數(shù)
model = RandomForestClassifier(
n_estimators=100, # 森林中樹的數(shù)量,更多的樹通常能提高模型的性能,但計算開銷也會增加
max_depth=10, # 樹的最大深度,防止樹過深導(dǎo)致過擬合。較小的深度可能導(dǎo)致欠擬合
min_samples_split=5, # 每個節(jié)點至少需要有5個樣本才能繼續(xù)分裂,增大可以防止過擬合
min_samples_leaf=2, # 每個葉子節(jié)點至少要有2個樣本,防止葉子節(jié)點過小導(dǎo)致模型過擬合
max_features='sqrt', # 每次分裂時考慮的特征數(shù)量,'sqrt' 表示使用特征數(shù)量的平方根,能提高模型的泛化能力
bootstrap=True, # 是否在構(gòu)建每棵樹時進行有放回的抽樣,True 是默認設(shè)置,可以減少模型的方差
oob_score=True, # 是否使用袋外樣本來評估模型的泛化能力,開啟此項可以進行無偏驗證
random_state=42, # 保證結(jié)果可重復(fù),設(shè)置隨機數(shù)種子
class_weight='balanced' # 類別權(quán)重,適用于樣本不均衡的情況,'balanced' 自動調(diào)整類別權(quán)重
)

# 訓(xùn)練模型
model.fit(X_train, y_train)

構(gòu)建并訓(xùn)練了一個隨機森林分類模型 (RandomForestClassifier),其中設(shè)置了多個參數(shù),如樹的數(shù)量、最大深度、節(jié)點分裂的最小樣本數(shù)、特征選擇方式等,以控制模型的復(fù)雜度和防止過擬合。使用了袋外評分 (oob_score) 來評估模型的泛化能力,并通過 class_weight=’balanced’ 來處理類別不平衡問題,最后通過 model.fit(X_train, y_train) 在訓(xùn)練數(shù)據(jù)上進行模型訓(xùn)練

利用決策曲線分析 (DCA) 評估機器學(xué)習(xí)模型的凈收益

from sklearn.metrics import confusion_matrix

# 矢量化計算模型凈收益的函數(shù)
def compute_net_benefit_model_vectorized(thresholds, y_pred_scores, y_labels):
# 先將 y_labels 轉(zhuǎn)換為 numpy 數(shù)組以避免多維索引問題
y_labels = np.array(y_labels)
y_pred_scores = np.array(y_pred_scores)
# 計算總樣本數(shù)
n = len(y_labels)
# 預(yù)分配數(shù)組
net_benefit_model = np.zeros_like(thresholds)
# 將預(yù)測得分和閾值進行廣播計算
y_pred_matrix = (y_pred_scores[:, None] > thresholds).astype(int)
# 矢量化計算混淆矩陣的元素:TP 和 FP
tp = (y_pred_matrix & y_labels[:, None]).sum(axis=0)
fp = ((y_pred_matrix == 1) & (y_labels[:, None] == 0)).sum(axis=0)
# 計算凈收益
net_benefit_model = (tp / n) - (fp / n) * (thresholds / (1 - thresholds))
return net_benefit_model

# 矢量化計算 Treat all 策略凈收益的函數(shù)
def compute_net_benefit_all_vectorized(thresholds, y_labels):
# 將 y_labels 轉(zhuǎn)換為 numpy 數(shù)組以避免多維索引問題
y_labels = np.array(y_labels)
# 計算混淆矩陣的元素(基于 Treat all 策略,所有樣本被視為正類)
tn, fp, fn, tp = confusion_matrix(y_labels, y_labels).ravel()
total = tp + tn
# 預(yù)分配數(shù)組
net_benefit_all = np.zeros_like(thresholds)
# 矢量化計算凈收益
net_benefit_all = (tp / total) - (tn / total) * (thresholds / (1 - thresholds))
return net_benefit_all

# 繪制 DCA 的函數(shù)
def plot_dca_custom(thresholds, net_benefit_model, net_benefit_all):
fig, ax = plt.subplots(figsize=(8, 6),dpi=1200)
# 繪制凈收益曲線
ax.plot(thresholds, net_benefit_model, color='deepskyblue', label='Model')
ax.plot(thresholds, net_benefit_all, color='black', label='Treat all')
ax.plot((0, 1), (0, 0), color='#808080', label='Treat none')

# 填充模型比 Treat all 和 Treat none 優(yōu)勢部分
y2 = np.maximum(net_benefit_all, 0)
y1 = np.maximum(net_benefit_model, y2)
ax.fill_between(thresholds, y1, y2, color='deepskyblue', alpha=0.3) # 保持原來的填充顏色
# 美化圖表
ax.set_xlim(0, 1)
ax.set_ylim(net_benefit_model.min() - 0.15, net_benefit_model.max() + 0.15)
ax.set_xlabel('Threshold Probability', fontdict={'family': 'Times New Roman', 'fontsize': 15})
ax.set_ylabel('Net Benefit', fontdict={'family': 'Times New Roman', 'fontsize': 15})
ax.grid(True)
ax.legend(loc='upper right')
plt.savefig("DCA.pdf", bbox_inches='tight')
plt.show()
# 運行 DCA 分析函數(shù)
def run_dca_analysis(model, X_test, y_test):
# 使用模型預(yù)測概率
y_pred_scores = model.predict_proba(X_test)[:, 1] # 獲得正類的預(yù)測概率
y_labels = y_test # 使用測試集的真實標簽
# 定義閾值范圍
thresholds = np.arange(0, 1, 0.01)
# 計算不同閾值下的凈收益
net_benefit_model = compute_net_benefit_model_vectorized(thresholds, y_pred_scores, y_labels)
net_benefit_all = compute_net_benefit_all_vectorized(thresholds, y_labels)
# 調(diào)用繪圖函數(shù)
plot_dca_custom(thresholds, net_benefit_model, net_benefit_all)

通過決策曲線分析 (DCA) 評估機器學(xué)習(xí)模型在不同閾值下的凈收益,首先通過 compute_net_benefit_model_vectorized 和 compute_net_benefit_all_vectorized 函數(shù)分別計算模型和 Treat all 策略的凈收益,依據(jù)閾值來衡量真正例 (TP) 和假正例 (FP) 對模型效益的影響,然后通過 plot_dca_custom 函數(shù)將模型與 Treat all 和 Treat none 策略的凈收益曲線進行可視化對比,最后 run_dca_analysis 函數(shù)執(zhí)行整個分析過程,幫助決策者判斷在不同閾值下,使用模型是否比其他策略帶來更高的效益

函數(shù)調(diào)用

run_dca_analysis(model, X_test, y_test)

本文章轉(zhuǎn)載微信公眾號@Python機器學(xué)習(xí)AI

上一篇:

用SHAP可視化解讀數(shù)據(jù)特征的重要性:蜂巢圖與特征關(guān)系圖結(jié)合展示

下一篇:

優(yōu)化XGBoost分類模型:網(wǎng)格搜索與K折交叉驗證實現(xiàn)

我們有何不同?

API服務(wù)商零注冊

多API并行試用

數(shù)據(jù)驅(qū)動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費