• ML.NET技术研究系列-2聚类算法KMeans


    上一篇博文我们介绍了ML.NET 的入门:

    ML.NET技术研究系列1-入门篇

    本文我们继续,研究分享一下聚类算法k-means.

    一、k-means算法简介

    k-means算法是一种聚类算法,所谓聚类,即根据相似性原则,将具有较高相似度的数据对象划分至同一类簇,将具有较高相异度的数据对象划分至不同类簇。
    

    1. k-means算法的原理是什么样的?参考:https://baijiahao.baidu.com/s?id=1622412414004300046&wfr=spider&for=pc

       k-means算法中的k代表类簇个数,means代表类簇内数据对象的均值(这种均值是一种对类簇中心的描述),因此,k-means算法又称为k-均值算法。

       k-means算法是一种基于划分的聚类算法,以距离作为数据对象间相似性度量的标准,即数据对象间的距离越小,则它们的相似性越高,则它们越有可能在同一个类簇。

       数据对象间距离的计算有很多种,k-means算法通常采用欧氏距离来计算数据对象间的距离。算法详细的流程描述如下:

       2. k-means算法的优缺点:

         优点: 算法简单易实现; 

         缺点: 需要用户事先指定类簇个数; 聚类结果对初始类簇中心的选取较为敏感; 容易陷入局部最优; 只能发现球形类簇;

    接下来我们说一下k-means算法的经典应用场景:鸢尾花

    二、鸢尾花

    首先,鸢尾花是一种植物,有四个典型的属性:

    •   花瓣长度
    •   花瓣宽度
    •   花萼长度
    •   花萼宽度

      

     鸢尾花有三大品种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
    

     上述数据中,第一列是鸢尾花花萼长度,第二列是鸢尾花花萼宽度,第三列是鸢尾花花瓣长度,第四列是鸢尾花花瓣宽度。

       基于上述数据做机器学习、训练,形成一个模型。

    三、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

  • 相关阅读:
    彻底理解多态
    变量可以存储在堆中,栈中,方法区中。哪里都可以啊。对象只能存储在堆中
    json序列化后的是字符串,不是二进制。是字符串!!!确定不是二进制!!!
    线程流程理解
    增加一个类的功能可以采用继承或者代理模式或者装饰者模式
    Java 代理模式和装饰者模式的区别
    异常不管咋样,只要抛出了,不管是方法级别抛出,还是类级别抛出。终究有一个地方要对异常进行处理
    汉高澳大利亚sinox为什么不能下载源代码,因为sinox执行unix/linux/windows规划
    使用Visual Studio将Objective-C编译C++
    百度编辑器ueditor简单易用
  • 原文地址:https://www.cnblogs.com/tianqing/p/11183035.html
Copyright © 2020-2023  润新知