教學課程:使用 k-means 叢集搭配 ML.NET 來分類鳶尾花

本教學課程說明如何使用 ML.NET 為鳶尾花資料集建立一個群集模型

在本教學課程中,您會了解如何:

  • 了解問題
  • 選取適當的機器學習工作
  • 準備資料
  • 載入並轉換資料
  • 選擇學習演算法
  • 將模型定型
  • 使用模型來進行預測

必要條件

了解問題

這個問題是關於將一組鳶尾花按照花卉特徵分成不同的群組。 這些特徵是萼片的長度和寬度以及花瓣的長度和寬度。 本教學課程中假設不知道每個花卉的類型。 您想要從特徵了解資料集的結構,還要預測資料執行個體如何符合此結構。

選取適當的機器學習工作

因為您不知道每個花卉屬於哪個群組,所以您選擇非監督式機器學習工作。 若要按照類似元素歸於同一群組中的方式來分割群組中的資料集,請使用群集機器學習工作。

建立主控台應用程式

  1. 建立名為 「IrisFlowerClustering」 的 C# 主控台應用程式 。 按 [下一步] 按鈕。

  2. 選擇 .NET 6 作為要使用的架構。 按一下 [ 建立 ] 按鈕。

  3. 在專案中建立名為 Data 的目錄,以儲存資料集和模型檔案:

    在 [方案總管] 中,以滑鼠右鍵按一下專案,然後選取 [新增]>[新增資料夾]。 輸入 "Data",然後按 Enter。

  4. 安裝 Microsoft.ML NuGet 套件:

    注意

    除非另有說明,否則此樣本會使用所提及 NuGet 封裝的最新穩定版本。

    [方案總管] 中,以滑鼠右鍵按一下專案,然後選取 [管理 NuGet 套件]。 選擇 [nuget.org] 作為 [套件來源],選取 [ 流覽 ] 索引標籤,搜尋 Microsoft.ML ,然後選取 [ 安裝 ] 按鈕。 在 [預覽變更] 對話方塊上,選取 [確定] 按鈕,然後在 [授權接受] 對話方塊上,如果您同意所列套件的授權條款,請選取 [我接受]

準備資料

  1. 下載 iris.data 資料集,並將它儲存到上一個步驟中建立的 Data 資料夾。 如需有關鳶尾花資料集的詳細資訊,請參閱鳶尾花資料集維基百科頁面和鳶尾花資料集頁面 (也就是資料集的來源)。

  2. 以滑鼠右鍵按一下 [方案總管] 中的 iris.data 檔案,然後選取 [內容]。 在 [進階] 底下,將 [複製到輸出目錄] 的值變更為 [有更新時才複製]。

Iris.data 檔案包含五個資料行,分別表示:

  • 以公分為單位的分數長度
  • 以公分為單位的分半形
  • 以公分為單位的花花長度
  • 以公分為單位的花花寬度
  • 鳶尾花的類型

為了示範群集方法,本教學課程會略過最後一個資料行。

建立資料類別

為輸入資料和預測建立類別:

  1. 在 [方案總管] 中,以滑鼠右鍵按一下專案,然後選取 [新增]>[新項目]

  2. 在 [新增項目] 對話方塊中,選取 [類別],然後將 [名稱] 欄位變更為 IrisData.cs。 接著,選取 [新增] 按鈕。

  3. 將下列的 using 指示詞加入新檔案:

    using Microsoft.ML.Data;
    

移除現有的類別定義,然後將下列程式碼 (定義 IrisDataClusterPrediction 這兩個類別) 新增至 IrisData.cs 檔案:

public class IrisData
{
    [LoadColumn(0)]
    public float SepalLength;

    [LoadColumn(1)]
    public float SepalWidth;

    [LoadColumn(2)]
    public float PetalLength;

    [LoadColumn(3)]
    public float PetalWidth;
}

public class ClusterPrediction
{
    [ColumnName("PredictedLabel")]
    public uint PredictedClusterId;

    [ColumnName("Score")]
    public float[]? Distances;
}

IrisData 是輸入資料類別,它含有資料集中每個特徵的定義。 請使用 LoadColumn 屬性來指定資料集檔案中來源資料行的索引。

ClusterPrediction 類別代表套用至 IrisData 執行個體的群集模型結果。 使用 ColumnName 屬性分別將 PredictedClusterIdDistances 欄位繫結至 PredictedLabelScore 資料行。 群集這些資料行的工作具有下列意義:

  • PredictedLabel 資料行包含預測群集的 ID。
  • Score 資料行包含平方歐幾里得距離到群集矩心的陣列。 陣列長度等於群集數目。

注意

使用 float 型別表示輸入和預測資料類別中的浮點值。

定義資料和模型路徑

返回 Program.cs 檔案並新增兩個欄位,保存資料集檔案的路徑以及儲存模型之檔案的路徑:

  • _dataPath 會針對具有用來定型模型之資料集的檔案,包含檔案的路徑。
  • _modelPath 會針對儲存定型模型的檔案,包含檔案的路徑。

在 using 語句底下新增下列程式碼,以指定這些路徑:

string _dataPath = Path.Combine(Environment.CurrentDirectory, "Data", "iris.data");
string _modelPath = Path.Combine(Environment.CurrentDirectory, "Data", "IrisClusteringModel.zip");

建立 ML 內容

Program.cs 檔案頂端加入下列額外的 using 指示詞:

using Microsoft.ML;
using IrisFlowerClustering;

使用下列程式碼取代 Console.WriteLine("Hello World!"); 行:

var mlContext = new MLContext(seed: 0);

Microsoft.ML.MLContext 類別表示機器學習環境,並為資料載入、模型定型、預測和其他工作提供記錄機制和進入點。 這在概念上類似於在 Entity Framework 中使用的 DbContext

設定資料載入

在 下方 MLContext 新增下列程式碼,以設定載入資料的方式:

IDataView dataView = mlContext.Data.LoadFromTextFile<IrisData>(_dataPath, hasHeader: false, separatorChar: ',');

泛型MLContext.Data.LoadFromTextFile 擴充方法會從提供的 IrisData 型別推斷資料集架構,並傳回 IDataView 可用來作為轉換器輸入的資料集架構。

建立學習管線

在本教學課程中,叢集工作的學習管線包含下列兩個步驟:

  • 將載入的資料行串連成一個 [特徵] 資料行,以供叢集定型器使用;
  • 使用 KMeansTrainer 定型器透過 k-means++ 叢集演算法將模型定型。

載入資料之後,新增下列內容:

string featuresColumnName = "Features";
var pipeline = mlContext.Transforms
    .Concatenate(featuresColumnName, "SepalLength", "SepalWidth", "PetalLength", "PetalWidth")
    .Append(mlContext.Clustering.Trainers.KMeans(featuresColumnName, numberOfClusters: 3));

此程式碼指定應該將資料集分成三個叢集。

將模型定型

上述小節中加入的步驟已準備好訓練的管道,不過,還沒有開始執行。 在檔案底部新增下列行,以執行資料載入和模型定型:

var model = pipeline.Fit(dataView);

儲存模型

此時,您已有一個可整合至任何現有或新 .NET 應用程式的模型。 若要將模型儲存至.zip檔案,請在呼叫 方法的下方 Fit 新增下列程式碼:

using (var fileStream = new FileStream(_modelPath, FileMode.Create, FileAccess.Write, FileShare.Write))
{
    mlContext.Model.Save(model, dataView.Schema, fileStream);
}

使用模型來進行預測

為了進行預測,請使用 PredictionEngine<TSrc,TDst> 類別,其帶領輸入類型的執行個體通過轉換程式管線,並產生輸出類型的執行個體。 新增下列這一行,以建立該類別的實例:

var predictor = mlContext.Model.CreatePredictionEngine<IrisData, ClusterPrediction>(model);

PredictionEngine 是一種便利的 API,可讓您在單一資料執行個體上接著執行預測。 PredictionEngine 不是安全執行緒。 可接受在單一執行緒或原型環境中使用。 為了提升效能和執行緒安全性,請使用 PredictionEnginePool 服務,以建立 PredictionEngine 物件的 ObjectPool 供整個應用程式使用。 請參閱本指南,以瞭解如何在ASP.NET Core Web API 中使用 PredictionEnginePool

注意

PredictionEnginePool 服務延伸模組目前處於預覽狀態。

建立 TestIrisData 類型以容納測試資料執行個體:

  1. 在 [方案總管] 中,以滑鼠右鍵按一下專案,然後選取 [新增]>[新項目]

  2. 在 [新增項目] 對話方塊中,選取 [類別],然後將 [名稱] 欄位變更為 TestIrisData.cs。 接著,選取 [新增] 按鈕。

  3. 將類別修改成靜態,如以下範例所示:

    static class TestIrisData
    

本教學課程介紹此類別內一個鳶尾花資料執行個體。 您可以新增其他案例來對此模型進行實驗。 將下列程式碼新增至 TestIrisData 類別:

internal static readonly IrisData Setosa = new IrisData
{
    SepalLength = 5.1f,
    SepalWidth = 3.5f,
    PetalLength = 1.4f,
    PetalWidth = 0.2f
};

若要找出指定專案所屬的叢集,請返回 Program.cs 檔案,並在檔案底部新增下列程式碼:

var prediction = predictor.Predict(TestIrisData.Setosa);
Console.WriteLine($"Cluster: {prediction.PredictedClusterId}");
Console.WriteLine($"Distances: {string.Join(" ", prediction.Distances ?? Array.Empty<float>())}");

執行程式,以查看哪些群集包含指定的資料執行個體以及從該執行個體到群集矩心的平方距離。 您的結果應該與以下類似:

Cluster: 2
Distances: 11.69127 0.02159119 25.59896

恭喜! 您現在已成功建置用來群集鳶尾花並進行預測的機器學習模型。 您可以在 dotnet/samples GitHub 存放庫中找到本教學課程的原始程式碼。

後續步驟

在本教學課程中,您已了解如何:

  • 了解問題
  • 選取適當的機器學習工作
  • 準備資料
  • 載入並轉換資料
  • 選擇學習演算法
  • 將模型定型
  • 使用模型來進行預測

請查看我們的 GitHub 存放庫來繼續學習及尋找更多範例。