用收益成本分析圖(Profit-Cost Curve)輕鬆評估策略效益

在商業領域中,許多的業務推行和決策往往需要多加考慮在進行決策的調整,調整的目的不外乎是希望提升業務收入,或者降低成本,本篇內容將介紹收益成本分析圖(Profit-Cost Curve),讓機器學習模型在訓練的同時,就自動幫我們評估好模型最佳閾值(threshold),能夠讓業務推行的同時,在收益與成本的管控上取得更好的平衡。

收益成本分析圖介紹

收益-成本分析圖是機器學習模型用於分析在不同閾值(threshold)設定下的預測結果,幫助找到收益與成本的最佳平衡點,此分析圖特別適合在公司的利潤和損失高度相關的應用場景。

收益成本分析圖組成

收益成本分析圖中,有兩條重要的曲線,以及一條虛線:

  1. 收益曲線(Profit)
    代表模型在給定閾值下正確預測的正面效益(Positive)。
  2. 曲線(Cost)
    代表模型在給定閾值下錯誤預測,例如假陽性(False Positive)或假陰性(False Negative))所產生的負面影響。
  3. 閾值虛線(threshold)
    代表模型在特定的閾值條件下,模型所得到的最佳收益與成本的權衡點。

收益成本分析圖應用場景

收益成本分析圖主要會應用在利潤與損失之間進行權衡的業務情境,一般來說有這些類別:

  • 行銷活動:
      公司促銷郵件、優惠券或其他行銷推廣活動。
  • 風險管理:
      金融機構對貸款申請人進行信用風險評估,或保險公司評估承保風險。
  • 詐欺檢測:
      在電子商務平台、金融機構或保險公司規劃檢測交易中的欺詐行為。
  • 醫療診斷:
      利用機器學習模型來輔助醫生進行醫療診斷(例如癌症檢測、疾病預測等)。
  • 求職篩選:
      利用自動化軟體篩選系統,以預測求職候選人是否適合某個職務。
  • 製造業產品品質檢測:
      使用機器學習模型檢測產品是否存在缺陷、良率控制。
  • 能源消耗與預測:
      能源公司利用模型預測能源需求,並決定資源分配問題。

收益成本分析圖範例

我們使用開源開源機器學習平台 OpenML 的信用卡詐欺檢測資料集進行收益成本分析圖(Profit-Cost Curve)的繪製,資料集中有 1000 位申請信用卡的資料,其包含年齡、性別、職業、收入、信用額度等 20 個特徵,我們的分類目標是信用卡申請的結果(good 表示良好信用, bad 表示不良信用),最終的圖表可以幫助銀行進行信用卡業務的管控,用以提升效率,可執行的程式碼放在我的Colab上。

# 安裝需要的套件
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler

# 加載開源資料集(信用卡詐欺檢測資料集)
from sklearn.datasets import fetch_openml

# 加載資料集
credit_data = fetch_openml(name="credit-g", version=1)
data = pd.DataFrame(credit_data.data, columns=credit_data.feature_names)
data['target'] = credit_data.target

# 將目標變量轉換為二進制 (good = 1, bad = 0)
data['target'] = data['target'].apply(lambda x: 1 if x == 'good' else 0)

# 2. 資料預處理
X = pd.get_dummies(data.drop('target', axis=1), drop_first=True)
y = data['target']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=28)

# 3. 訓練模型
model = LogisticRegression(max_iter=500, random_state=28)
model.fit(X_train, y_train)
y_scores = model.predict_proba(X_test)[:, 1]

# 4. 定義收益與成本計算
def calculate_profit_cost(y_true, y_scores, thresholds, profit_per_correct=100, cost_per_incorrect=200):
    profits, costs = [], []
    for thresh in thresholds:
        y_pred = (y_scores >= thresh).astype(int)
        tp = np.sum((y_pred == 1) & (y_true == 1))  # True Positives(真陽性)
        fp = np.sum((y_pred == 1) & (y_true == 0))  # False Positives(假陽性)

        profit = tp * profit_per_correct
        cost = fp * cost_per_incorrect

        costs.append(cost)
        profits.append(profit)

    return np.array(profits), np.array(costs)

# 5. 計算收益與成本
thresholds = np.linspace(0, 1, 100)
profits, costs = calculate_profit_cost(y_test, y_scores, thresholds)

# 6. 繪製收益-成本曲線
plt.figure(figsize=(10, 6))
plt.plot(thresholds, profits, label="Profit", color="green")
plt.plot(thresholds, costs, label="Cost", color="red")
plt.axvline(thresholds[np.argmax(profits - costs)], color='blue', linestyle='--', label='Optimal Threshold')
plt.title("Profit-Cost Curve")
plt.xlabel("Threshold")
plt.ylabel("Value")
plt.legend()
plt.grid()
plt.show()

我們的評估方式是以 Profit(真陽性帶來的收益)最高且 Cost(假陽性帶來的成本)最低為目標。在分析後,我們發現最佳的閾值約為 0.6。此閾值可以在獲得最大的良好(good)信用卡申請結果的同時,將錯誤預測(實際為 bad 但被預測為 good)的數量降到最低。

import seaborn as sns
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report

# 找出最佳閾值
optimal_threshold_index = np.argmax(profits - costs)
optimal_threshold = thresholds[optimal_threshold_index]

# 在最佳閾值位置上的利潤和成本
optimal_profit = profits[optimal_threshold_index]
optimal_cost = costs[optimal_threshold_index]

print("收益成本分析結果:")
print(f"最佳閾值: {optimal_threshold}")
print(f"在最佳閾值位置上的利潤: {optimal_profit}")
print(f"在最佳閾值位置上的成本: {optimal_cost} \n")

# 使用最佳閾值 0.6364 進行預測
y_pred = (y_scores >= 0.6364).astype(int)

# 顯示分類報告
report = classification_report(y_test, y_pred, target_names=['Bad', 'Good'])
print("Classification Report: \n")
print(report)

# 計算混淆矩陣
cm = confusion_matrix(y_test, y_pred)

# 繪製混淆矩陣
plt.figure(figsize=(4, 4))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=['Bad', 'Good'], yticklabels=['Bad', 'Good'])
plt.title('Confusion Matrix')
plt.xlabel('Predicted')
plt.ylabel('True')
plt.show()

以最終閾值定在 0.6364 的基準來看,我們得到正確預測 good 信用卡申請結果:

  • 準確率(Precision)為 0.87,表示在所有被預測為 good 的申請中,87% 實際為 good
  • 召回率(Recall):為 0.81,表示在所有實際為 good 的申請中,模型成功識別出 81%。
  • 調和平均數(F1-score):為 0.84,結果綜合了準確率與召回率的平衡。

經由收益成本分析圖(Profit-Cost Curve)的分析結果,表示模型在預測良好 (good) 信用卡申請結果時有 84% 更加穩定的整體表現。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *