ML.NET技術研究系列-2聚類算法KMeans

上一篇博文咱們介紹了ML.NET 的入門:html

ML.NET技術研究系列1-入門篇git

本文咱們繼續,研究分享一下聚類算法k-means.github

1、k-means算法簡介算法

k-means算法是一種聚類算法,所謂聚類,即根據類似性原則,將具備較高類似度的數據對象劃分至同一類簇,將具備較高相異度的數據對象劃分至不一樣類簇。

1. k-means算法的原理是什麼樣的?參考:https://baijiahao.baidu.com/s?id=1622412414004300046&wfr=spider&for=pcsql

   k-means算法中的k表明類簇個數,means表明類簇內數據對象的均值(這種均值是一種對類簇中心的描述),所以,k-means算法又稱爲k-均值算法。機器學習

   k-means算法是一種基於劃分的聚類算法,以距離做爲數據對象間類似性度量的標準,即數據對象間的距離越小,則它們的類似性越高,則它們越有可能在同一個類簇。ide

   數據對象間距離的計算有不少種,k-means算法一般採用歐氏距離來計算數據對象間的距離。算法詳細的流程描述以下:函數

   2. k-means算法的優缺點:post

     優勢: 算法簡單易實現; 學習

     缺點: 須要用戶事先指定類簇個數; 聚類結果對初始類簇中心的選取較爲敏感; 容易陷入局部最優; 只能發現球形類簇;

接下來咱們說一下k-means算法的經典應用場景:鳶尾花

2、鳶尾花

首先,鳶尾花是一種植物,有四個典型的屬性:

  •   花瓣長度
  •   花瓣寬度
  •   花萼長度
  •   花萼寬度

  

 鳶尾花有三大品種setosa、versicolor 或 virginica ,每一個品種對應的以上四個屬性各不相同。

 鳶尾花數據集中一共包含了150條記錄,每一個樣本的包含它的萼片長度和寬度,花瓣的長度和寬度以及這個樣本所屬的具體品種。每一個品種的樣本量爲50條。

 鳶尾花樣本數據格式:

5.2,3.4,1.4,0.2,Iris-setosa
4.7,3.2,1.6,0.2,Iris-setosa
4.8,3.1,1.6,0.2,Iris-setosa
6.0,2.2,4.0,1.0,Iris-versicolor
6.1,2.9,4.7,1.4,Iris-versicolor
5.6,2.9,3.6,1.3,Iris-versicolor
5.7,2.5,5.0,2.0,Iris-virginica
5.8,2.8,5.1,2.4,Iris-virginica
6.4,3.2,5.3,2.3,Iris-virginica

 上述數據中,第一列是鳶尾花花萼長度,第二列是鳶尾花花萼寬度,第三列是鳶尾花花瓣長度,第四列是鳶尾花花瓣寬度。

   基於上述數據作機器學習、訓練,造成一個模型。

3、ML.NET k-means

   基於上述的場景,咱們先準備樣本數據,https://github.com/dotnet/machinelearning/blob/master/test/data/iris.data

   另存爲iris.data文件,每一個屬性逗號間隔。

   而後,大體梳理了一下實現步驟:

  1.    新建一個.Net  Core Console Project
  2.    添加Microsoft.ML nuget 1.2.0版本
  3.    添加鳶尾花數據、預測類實體類IrisData、ClusterPrediction
  4.    構造MLContext、從iris.data構造IDataView,採用Trainers.KMeans進行模型訓練,造成模型文件:IrisClusteringModel.zip
  5.    輸入一個測試數據,進行預測。

   好,讓咱們開始搞吧:

   1. 新建一個.Net  Core Console Project

    先看下用的VS的版本:

   

    新建一個.Net Core Console的Project KMeansDemo

   2. 添加Microsoft.ML nuget 1.2.0版本

   

  將iris.data文件放到Project下的Data目錄中,同時右鍵iris.data,設置爲:始終複製

  

  

 

 3. 添加鳶尾花數據、預測類實體類IrisData、ClusterPrediction

using System;
using System.Collections.Generic;
using System.Text;

namespace KMeansDemo
{
    using Microsoft.ML.Data;

    /// <summary>
    /// 鳶尾花數據
    /// </summary>
    class IrisData
    {
        /// <summary>
        /// 鳶尾花花萼長度
        /// </summary>
        [LoadColumn(0)]
        public float SepalLength;

        /// <summary>
        /// 鳶尾花花萼寬度
        /// </summary>
        [LoadColumn(1)]
        public float SepalWidth;

        /// <summary>
        /// 鳶尾花花瓣長度
        /// </summary>
        [LoadColumn(2)]
        public float PetalLength;

        /// <summary>
        /// 鳶尾花花瓣寬度
        /// </summary>
        [LoadColumn(3)]
        public float PetalWidth;
    }
}

 

using System;
using System.Collections.Generic;
using System.Text;

namespace KMeansDemo
{
    using Microsoft.ML.Data;

    public class ClusterPrediction
    {
        /// <summary>
        /// 預測的族羣
        /// </summary>
        [ColumnName("PredictedLabel")]
        public uint PredictedClusterId;

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

4.  構造MLContext、從iris.data構造IDataView,採用Trainers.KMeans進行模型訓練,造成模型文件:IrisClusteringModel.zip

 在Main函數中,開始編碼 ,首先添加引用

using Microsoft.ML;

 聲明樣本數據文件和模型文件的文件路徑

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

 構造MLContext、IDataView,採用Trainer.KMeans進行模型訓練,造成模型文件:IrisClusteringModel.zip

var mlContext = new MLContext(seed: 0);
IDataView dataView = mlContext.Data.LoadFromTextFile<IrisData>(_dataPath, hasHeader: false, separatorChar: ',');
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);
using (var fileStream = new FileStream(_modelPath, FileMode.Create, FileAccess.Write, FileShare.Write))
{
      mlContext.Model.Save(model, dataView.Schema, fileStream);
}
Console.WriteLine("完成模型訓練!");
Console.WriteLine("模型文件:"+ _modelPath);

5.  輸入一個測試數據,進行預測。

 輸入一個測試數據,使用生成的模型,進行預測:

var predictor = mlContext.Model.CreatePredictionEngine<IrisData, ClusterPrediction>(model);
var Setosa = new IrisData
{
                SepalLength = 5.1f,
                SepalWidth = 3.5f,
                PetalLength = 1.4f,
                PetalWidth = 0.2f
};

var prediction = predictor.Predict(Setosa);
Console.WriteLine($"Cluster: {prediction.PredictedClusterId}");
Console.WriteLine($"Distances: {string.Join(" ", prediction.Distances)}");
Console.WriteLine("Press any key!");

 所有的代碼:

 1 using Microsoft.ML;
 2 using System;
 3 using System.IO;
 4 
 5 namespace KMeansDemo
 6 {
 7     class Program
 8     {
 9         static readonly string _dataPath = Path.Combine(Environment.CurrentDirectory, "Data", "iris.data");
10         static readonly string _modelPath = Path.Combine(Environment.CurrentDirectory, "Data", "IrisClusteringModel.zip");
11 
12         static void Main(string[] args)
13         {
14             var mlContext = new MLContext(seed: 0);
15             IDataView dataView = mlContext.Data.LoadFromTextFile<IrisData>(_dataPath, hasHeader: false, separatorChar: ',');
16             string featuresColumnName = "Features";
17             var pipeline = mlContext.Transforms
18                 .Concatenate(featuresColumnName, "SepalLength", "SepalWidth", "PetalLength", "PetalWidth")
19                 .Append(mlContext.Clustering.Trainers.KMeans(featuresColumnName, numberOfClusters: 3));
20             var model = pipeline.Fit(dataView);
21             using (var fileStream = new FileStream(_modelPath, FileMode.Create, FileAccess.Write, FileShare.Write))
22             {
23                 mlContext.Model.Save(model, dataView.Schema, fileStream);
24             }
25             Console.WriteLine("完成模型訓練!");
26             Console.WriteLine("模型文件:"+ _modelPath);
27             
28             //預測
29             var predictor = mlContext.Model.CreatePredictionEngine<IrisData, ClusterPrediction>(model);
30 
31             var Setosa = new IrisData
32             {
33                 SepalLength = 5.1f,
34                 SepalWidth = 3.5f,
35                 PetalLength = 1.4f,
36                 PetalWidth = 0.2f
37             };
38 
39             var prediction = predictor.Predict(Setosa);
40             Console.WriteLine($"Cluster: {prediction.PredictedClusterId}");
41             Console.WriteLine($"Distances: {string.Join(" ", prediction.Distances)}");
42             Console.WriteLine("Press any key!");
43         }
44     }
45 }

Run,看一下輸出:

 以上就是經過ML.NET 的KMeans算法,實現聚類。

 上面的數據是一個監督學習的樣本,同時是一個數值類型的數據,比較好奇的是,能不能對文本數據+值數據進行聚類,下一篇,咱們將繼續完成文本數據+值數據的聚類分析。

以上,分享給你們。

 

周國慶

2019/7/14

相關文章
相關標籤/搜索