AI時代的網站與手機App建置與開發Part22 - 使用ML.NET判斷關鍵影響因素

 

·       摘要

找出造成某種結果的關鍵因素, 例如找出造成心臟疾病的關鍵因素, 找到員工離職的關鍵因素, 找出企業營業利潤不佳的關鍵原因, 找出客戶流失的關鍵原因, 是很實用的決策支援, 能夠協助企業或個人做出正確的決策, 進而防範不良結果發生, 防患於未然, 是企業經營勝出的良策.

在本篇文章中, 我們將使用Microsoft ML.NET支援的Permutation Feature Importance(PFI)演算法發掘造成罹患糖尿病的關鍵因素, 讀者有興趣也可進行研究, 研究房屋價格的關鍵因素, 影響員工績效的關鍵因素, 或是造成罹患失智症的關鍵原因.

: 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所示:

2: 影響罹患糖尿病的關鍵因素排序後的結果

請注意Permutation Feature Importance (PFI)會計算每一個特徵對欲研究的結果的相對貢獻值(R2的平均值 : RSquared.Mean), R2的平均值越大代表特徵是造成欲研究的結果較關鍵的因素, R2的平均值越小代表特徵是造成欲研究的結果較不關鍵的因素.

範例下載:

https://github.com/CraigIII/FindImportantFeatures.git

留言

這個網誌中的熱門文章

AI時代的網站與手機App建置與開發Part27 - ML.NET與物件偵測

AI時代的網站與手機App建置與開發Part24 - ML.NET與圖片異常偵測

AI時代的網站與手機App建置與開發Part28 - 使用YOLO模型進行物件偵測