AI時代的網站與手機App建置與開發Part22 - 使用ML.NET判斷關鍵影響因素
· 摘要
找出造成某種結果的關鍵因素, 例如找出造成心臟疾病的關鍵因素, 找到員工離職的關鍵因素, 找出企業營業利潤不佳的關鍵原因, 找出客戶流失的關鍵原因, 是很實用的決策支援, 能夠協助企業或個人做出正確的決策, 進而防範不良結果發生, 防患於未然, 是企業經營勝出的良策.
在本篇文章中, 我們將使用Microsoft ML.NET支援的Permutation Feature
Importance(PFI)演算法發掘造成罹患糖尿病的關鍵因素, 讀者有興趣也可進行研究, 研究房屋價格的關鍵因素, 影響員工績效的關鍵因素, 或是造成罹患失智症的關鍵原因.
· 準備訓練資料
首先請啟動瀏覽器, 瀏覽至diabetes.csv下載罹患糖杘病的病患的相關資料(下載網址: https://www.kaggle.com/datasets/saurabh00007/diabetescsv).
圖1所示即為下載得到的資料:
圖1: 罹患糖杘病的病患的相關資料
這份罹患糖杘病的病患的相關資料的欄位詳細說明如下表:
資料集描述:
|
欄位名稱 |
欄位說明 |
|
Pregnancies |
懷孕了幾次 |
|
Glucose |
血液中葡萄糖濃度 |
|
BloodPressure |
舒張壓(毫米汞柱mm
Hg) |
|
SkinThickness |
三頭肌皮摺厚度 |
|
Insulin |
胰島素濃度 |
|
BMI |
身體質量指數(BMI 值) |
|
DiabetesPedigreeFunction |
糖尿病函數,這個函數使用了家族糖尿病史來導出個人得糖尿病的風險值 |
|
Age |
年齡 |
|
Outcome |
0 代表未罹患糖尿病,1 代表罹患糖尿病 |
· 使用ML.NET找出罹患糖患病的關鍵因素
首先請下載上述的罹患糖杘病的病患的相關資料並加入到使用Visual Studio建立的專案, 並於[屬性]視窗將加入到專案, 內含罹患糖杘病的病患的相關資料的檔案的[複製到輸出目錄]屬性的內容值設定為:有更新時才複製.
· 定義描述罹患糖杘病的病患的相關資料的Patient類別
public class
Patient
{
[ColumnName("Pregnancies"),
LoadColumn(0)]
public
float Pregnancies { get; set; }
[ColumnName("Glucose"),
LoadColumn(1)]
public
float Glucose { get; set; }
[ColumnName("BloodPressure"),
LoadColumn(2)]
public
float BloodPressure { get; set; }
[ColumnName("SkinThickness"),
LoadColumn(3)]
public
float SkinThickness { get; set; }
[ColumnName("Insulin"),
LoadColumn(4)]
public
float Insulin { get; set; }
[ColumnName("BMI"),
LoadColumn(5)]
public
float BMI { get; set; }
[ColumnName("DiabetesPedigreeFunction"),
LoadColumn(6)]
public
float DiabetesPedigreeFunction { get; set;
}
[ColumnName("Age"),
LoadColumn(7)]
public
float Age { get; set; }
[ColumnName("Label"),
LoadColumn(8)] //必須將結果欄位的欄位名稱命名為Label
public
float Outcome { get; set; }
}
· 實作發掘罹患糖杘病的闗鍵因素
private void
btnUsePFI_Click(object
sender, EventArgs e)
{
MLContext mlContext = new MLContext();
// 載入資料
IDataView data = mlContext.Data.LoadFromTextFile<Patient>(
"diabetes.csv", separatorChar: ',', hasHeader: true);
// 將資料以80%:20%的比例切割成訓練資料和測試資料
var trainTestData = mlContext.Data.TrainTestSplit(data, testFraction: 0.2);
//取得切割妥的訓練資料
var trainData = trainTestData.TrainSet;
//取得切割妥的測試資料
var testData = trainTestData.TestSet;
//準備欲分析的特徵(取出所有除了Outcome以外的所有特徵)
var featureColumns = typeof(Patient).GetProperties()
.Where(p => p.Name != nameof(Patient.Outcome))
.Select(p => p.Name)
.ToArray();
// 指定欲分析的特徵,
調整特徵的內容值至0~1之間的範圍, 並指定使用
// Sdca(Stochastic Dual Coordinate
Ascent)迴歸演算法
var pipeline = mlContext.Transforms.Concatenate(
"Features", featureColumns)
.Append(mlContext.Transforms.NormalizeMinMax("Features"))
.Append(mlContext.Regression.Trainers.Sdca());
// 使用訓練資料執行訓練
var model = pipeline.Fit(trainData);
// 使用測試資料執行測試
var predictions = model.Transform(testData);
// 取得特徵的重要性數據
ImmutableDictionary<string, RegressionMetricsStatistics>
permutationFeatureImportance
= mlContext.Regression.
PermutationFeatureImportance(model,
predictions, permutationCount: 3);
// 排序特徵的重要性數據
var featureImportanceMetrics =
permutationFeatureImportance
.Select((metric, index) => new { index, metric.Value.RSquared })
.OrderByDescending(myFeatures =>
Math.Abs(myFeatures.RSquared.Mean));
// 顯示特徵的R2(重要性)的平均值
Trace.WriteLine("Feature\tPFI");
foreach (var feature in
featureImportanceMetrics)
{
Trace.WriteLine($"Column:{featureColumns[feature.index]},
{feature.RSquared.Mean:F6}");
}
}
執行上述的程式碼會顯示影響罹患糖尿病的關鍵因素由較重要~較不重要排序後的結果, 如圖2所示:
請注意Permutation Feature Importance (PFI)會計算每一個特徵對欲研究的結果的相對貢獻值(R2的平均值 : RSquared.Mean), R2的平均值越大代表特徵是造成欲研究的結果較關鍵的因素, 而R2的平均值越小代表特徵是造成欲研究的結果較不關鍵的因素.
範例下載:



留言
張貼留言