
目標達成率圖介紹
以往在商業分析上,我們會依據公司所訂定的商業目標進行達成率的訂定,並使用目標達成率圖持續的追蹤和確校,而麥特在本篇文章中,將會用機器學習模型的估計方法,來示範如何將已有的歷史資料進行模型的建立與分析,找到實務上關鍵的目標達成率因子,來提供商業決策與執行面向。
目標達成率圖的組成

目標達成率圖通常由以下幾個部分組成:
- X軸:通常表示時間(如月份、季度等)或是想追蹤的目標。
- Y軸:顯示數值,例如實際銷售額或目標達成率。
- 資料呈現:以長條圖(Bar Plot)或折線圖(Line Chart)的形式呈現實際達成的資料。
- 顏色:使用不同顏色來區分達成與未達成的目標,例如,達成的部分用綠色表示,未達成的部分用紅色表示。
目標達成率圖應用場景

目標達成率圖可以應用於多種場景,包括但不限於:
- 銷售預測:
- 用於評估每月或每季度週期性的銷售額是否達到預期目標,幫助銷售團隊調整策略方針。
- 客戶留存分析:
- 評估客戶留存率是否符合業務需求,進一步辨識影響留存率的因素。
- 市場推廣活動:
- 推廣活動結束後,分析實際效果與預期效果之間的差距原因,以便為未來活動提供參考。
- 績效評估:
- 用於員工或團隊績效考核,幫助管理層了解各部門或個體在特定業務指標上的表現。
- 產品開發:
- 評估新產品推出後的市場反應是否符合預期,以便及時調整產品策略。
目標達成率圖程式範例
本次的操作範例是使用 UCI資料集當中葡萄牙銀行的電話行銷資料集,對應的分類目標是預測顧客是否會認購定期存款(定存),我們將建立一個機器學習模型,用來提升認購定期存款的達成率,並分析資料集當中的特徵項目,來找出關鍵影響認購定期存款的特徵,用以追蹤會認購定期存款的顧客主要是因為哪些原因達成定存的認購。
以下的範例code我會放在我的colab上,歡迎使用。
首先我們會先安裝Bank Marketing 資料集及所需要的套件
!pip install ucimlrepo
接著載入 Bank Marketing 資料集,裡面包含了16項的特徵和目標變數 y,表示是否認購定期存款(’yes’, ‘no’),並且將類別特徵的字串值轉換為類別值。
from ucimlrepo import fetch_ucirepo
from sklearn.preprocessing import LabelEncoder
# 載入 Bank Marketing 資料集
bank_marketing = fetch_ucirepo(id=222)
# 取得特徵和目標變數資料
X = bank_marketing.data.features
y = bank_marketing.data.targets
# 顯示資料集的元資料
print("Metadata:")
print(bank_marketing.metadata)
# 顯示變數的資訊
print("\\nVariable Information:")
print(bank_marketing.variables)
# 轉換 'y' 欄位的值(yes/no)為 1 和 0
y = y['y'].map({'yes': 1, 'no': 0})
# 編碼類別變數 (例如職業、婚姻狀況等)
label_encoder = LabelEncoder()
# 對 X 中的類別變數進行編碼,使用 .loc 來避免 SettingWithCopyWarning
for column in X.select_dtypes(include=['object']).columns:
X.loc[:, column] = label_encoder.fit_transform(X[column])
我們將會訓練一個隨機森林的機器學習模型,我們希望基於原始目標 y的達成度,做出表現更好的模型預測,並且檢視有哪些特徵是影響目標變數最為重要的特徵。
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import confusion_matrix, classification_report
# 資料分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=28)
# 建立隨機森林模型
model = RandomForestClassifier(n_estimators=250, random_state=28, n_jobs=-1, max_depth=3, class_weight={0:1, 1:13}, max_features=8)
model.fit(X_train, y_train)
# 預測結果
y_pred = model.predict(X_test)
# 顯示分類報告和混淆矩陣
print("Test Set Classification Report:\n", classification_report(y_test, y_pred))
print("Confusion Matrix:\n", confusion_matrix(y_test, y_pred))
# 計算目標達成率
actual_rate = sum(y_test) / len(y_test) # 實際達成率
predicted_rate = sum(y_pred) / len(y_pred) # 預測達成率
# 繪製達成率圖
plt.figure(figsize=(10, 6))
# 設定柱狀圖 X 座標(讓兩個柱狀圖靠近)
x_pos = [0.4, 1.2] # 控制間距
bar_width = 0.4 # 縮小寬度
# 條形圖
bars = plt.bar(x_pos, [actual_rate, predicted_rate],
color=['#E74C3C', '#3498DB'], edgecolor='black', width=bar_width)
# 在每個條形圖上顯示數值(百分比格式)
for bar in bars:
yval = bar.get_height()
plt.text(bar.get_x() + bar.get_width()/2, yval + 0.02, f"{yval:.0%}",
ha='center', va='bottom', fontsize=14, color='black', fontweight='bold')
# 添加標籤和標題
plt.ylabel('Goal Achievement Rate (%)', fontsize=14)
plt.title('Actual vs Predicted Goal Achievement Rate', fontsize=16, fontweight='bold')
# 設定 X 軸標籤
plt.xticks(x_pos, ['Actual Rate', 'Predicted Rate'], fontsize=12)
# Y 軸最大值設定為 0.6
plt.ylim(0, 0.6)
# 顯示網格線
plt.grid(axis='y', linestyle='--', alpha=0.7)
# 調整佈局避免擠壓
plt.tight_layout()
# 顯示圖形
plt.show()

由於資料集本身的分布屬於不平衡資料,也就是變數 y 當中,’yes’和’no’的比例約為 1:13,所以在建立隨機森林模型的時候,我將二元分類的權重(weight)進行微調,讓模型對於正確可以預測認購定期存款(’yes’)的比重增加,最後模型對於預測認購定期存款(’yes’)的準確度來到約 4成,表示與原始資料結果相比(目標達成率 0.12),我們建構的模型(目標達成率 0.42)有更好的表現。
接下來我們需要近一步分析該模型是使用了哪些更為重要的特徵項,才有辦法將目標達成率提升至 0.42,所以我們將使用隨機森林模型當中很關鍵的 feature_importances_,並將每一個特徵進行重要度的降序排列,來找出影響目標達成率最關鍵的幾項特徵。
# 取得特徵重要性
feature_importances = model.feature_importances_
# 創建特徵名稱和重要性分數的DataFrame
features_df = pd.DataFrame({
'Feature': X.columns,
'Importance': feature_importances
})
# 按重要性排序
features_df = features_df.sort_values(by='Importance', ascending=False)
# 顯示排序後的特徵重要性
# print("\\nFeature Importances (Sorted):")
# print(features_df)
# 視覺化特徵重要性
plt.figure(figsize=(10, 6))
bars = plt.barh(features_df['Feature'], features_df['Importance'], color='teal')
plt.xlabel('Importance')
plt.title('Feature Importance Ranking')
# 在每個條形圖的右側顯示格式化後的重要性數值
for bar in bars:
width = bar.get_width()
plt.text(width + 0.02, bar.get_y() + bar.get_height()/2,
f'{width:.2f}', va='center', ha='left', fontsize=12, color='black')
# 反轉y軸,使最重要的特徵顯示在頂部
plt.gca().invert_yaxis()
plt.tight_layout()
plt.show()

從圖表的結果來看,影響最為重要的特徵是 duration,也就是最後一次與客戶聯繫的持續時間是最重要的特徵,這就表示與客戶進行長時間的通話可能會增加他們認購定期存款的機率。
排名第二重要的特徵是 contact,也就是聯繫方式,也是相對重要的特徵,其中 contact有分為行動電話(telephone)和固定電話(cellular),表示不同的聯繫方式可能對預測結果有相對顯著性的影響。
其他特徵如 pdays(從上次活動最後一次聯絡客戶後經過的天數)、 housing(有無房屋貸款)、 poutcome(先前進行行銷活動的結果)和 previous(在活動之前為此客戶進行聯繫的次數)也有一定的重要性,這些特徵反映了過去的聯繫歷程和客戶的財務狀況,這些因素可能會影響客戶進行認購定期存款的決策。
其他較低的重要性值(如age、balance、campaign等)表示這些特徵對於預測是否認購定期存款的影響是較小的。
最後我們將原始的目標達成率與我們所建立的隨機森林模型目標達成率進行比較
Actual_Achievement_Rate = sum(y) / len(y) * 100
Predicted_Achievement_Rate = sum(y_pred) / len(y_pred) * 100 # 這是經過模型預測後的達成率
print("原始資料的認購定期存款達成率(GAR) : ", round(Actual_Achievement_Rate, 2), "%")
print("經過模型篩選特徵預測後的認購定期存款達成率(GAR) : ", round(Predicted_Achievement_Rate, 2), "%")
print("提升的認購定期存款比率 :", round(Predicted_Achievement_Rate, 2) - round(Actual_Achievement_Rate, 2), "%")
- 原始資料的認購定期存款達成率(GAR) : 11.7 %
- 經過模型篩選特徵預測後的認購定期存款達成率(GAR) : 41.79 %
- 提升的認購定期存款比率 : 30.09 %
討論
目標達成率圖是很直觀能夠追蹤商業策略進度的一種呈現方式,而除了觀察是否達到最高達成率的同時,找出能夠有效提升達成率的關鍵因子是更為重要的事情,我們應用機器學習模型來觀察資料背後當中的重要因子,就能夠有效的提供商業策略,有利於業務的推行;通過簡單視覺化的方式,來提升業務推動效率,也幫助企業可以更簡單理解資料分析背後的有用訊息。
